OSDN Git Service

implement videoframe compliment option.
[rec10/rec10-git.git] / rec10 / trunk / src / tv2mp4.py
1 #!/usr/bin/python\r
2 # coding: UTF-8\r
3 # Rec10 TS Recording Tools\r
4 # Copyright (C) 2009-2010 Yukikaze\r
5 import commands\r
6 import shutil\r
7 import auto_process\r
8 import os\r
9 import re\r
10 import os.path\r
11 import string\r
12 import base64\r
13 import time\r
14 import subprocess\r
15 import traceback\r
16 \r
17 import tv2avi\r
18 import recdblist\r
19 import configreader\r
20 import status\r
21 import tv2audio\r
22 \r
23 def ts2mp4(pin, pout, opt):\r
24     dir=os.path.split(pout)[0]\r
25     title=os.path.split(pout)[1]\r
26     title=os.path.splitext(title)[0]\r
27     tpraw=os.path.join(dir, title+".264")\r
28     tpmp4=os.path.join(dir, title+".mp4")\r
29     if re.search("x",opt) or re.search("b",opt):\r
30         if re.search(".",opt):\r
31             tv2audio.dualaudio2sep(pin,"0", opt)\r
32         else:\r
33             tv2audio.dualaudio2sep(pin, "167", opt)\r
34     if os.path.isfile(pin) and os.path.getsize(pin)>10*1000:\r
35         tv2avi.ts2raw(pin, tpraw, opt)\r
36         time.sleep(10)\r
37         if os.path.isfile(tpraw) and os.path.getsize(tpraw)>10*1000:\r
38             raw2mp4(tpraw, tpmp4, opt)\r
39         time.sleep(10)\r
40         if os.path.exists(tpraw):\r
41             os.remove(tpraw)\r
42 def raw2mp4(pin,pout,opt):\r
43     dir=os.path.split(pout)[0]\r
44     title=os.path.split(pout)[1]\r
45     title=os.path.splitext(title)[0]\r
46     duration="-fps 29.970030 "\r
47     if re.search("a",opt):\r
48         duration="-fps 23.976023 "\r
49     elif re.search("v",opt):\r
50         duration="-fps 23.976023 "\r
51     if re.search("d",opt):\r
52         duration="-fps 29.970030 "##ffmpegが24fpsに対応していないための措置\r
53     elif re.search("5",opt):\r
54         duration="-fps 29.970030 "##ffmpegが24fpsに対応していないための措置\r
55     if re.search("I",opt):\r
56         duration="-fps 29.970030 "\r
57     exe = configreader.getpath("mp4box")\r
58     txt=""\r
59     os.environ['LANG']="ja_JP.UTF-8"\r
60     pints=pin.replace(".264",".ts")\r
61     e1=exe +u" "+duration+" -add \""+pin+"\" -new \""+pout+"\""\r
62     execmp4box(pin, pout, e1)\r
63     addAudio(pints, pout, opt)\r
64     addCaption(pints, pout)\r
65     #recdblist.addlog(pout, txt, "mp4boxログ-コマンド")\r
66     #recdblist.addlog(pout, txt, "mp4boxログ-詳細")\r
67     if status.getSettings_auto_del_tmp()==1:\r
68         if os.path.exists(pout):\r
69             if re.search(opt,"MW8") or re.search(opt,"MW9"):\r
70                 auto_process.deltmpfile(dir, title, ".mp4")\r
71             elif re.search(opt,"8") or re.search(opt,"9"):\r
72                 ""\r
73             else:\r
74                 auto_process.deltmpfile(dir, title, ".mp4")\r
75 def mkv2mp4(pin,pout):\r
76     exeb = configreader.getpath(u"mkvextract")\r
77     exe = configreader.getpath(u"mp4Box")\r
78     #dtsedit=configreader.getpath("DtsEdit")\r
79     wineexe=configreader.getpath("wine")\r
80     dir=os.path.split(pin)[0]\r
81     title=os.path.split(pin)[1]\r
82     title=os.path.splitext(title)[0]\r
83     etitle=base64.b16encode(title.encode('utf-8'))\r
84     audiopath=os.path.join(dir,etitle+u"_audio.aac")\r
85     videopath=os.path.join(dir,etitle+u"_video.264")\r
86     timecodepath=os.path.join(dir,etitle+u"_1_timecode.txt")\r
87     tmpmp4=os.path.join(dir,etitle+u".tmp.mp4")\r
88     exe0=exeb+u" tracks \'"+pin+u"\' 1:\'"+videopath+u"\' 2:\'"+audiopath+u"\'"\r
89     exe1=exeb+u" timecodes_v2 \'"+pin+"\' 1:\'"+timecodepath+"\'"\r
90     exe2=exe+u" -fps 29.970030 -add \'"+videopath+u"\' -add \'"+audiopath+u"\' -new \'"+tmpmp4+u"\'"\r
91     exe3=wineexe+u" "+dtsedit+u" -tc \'Z:\\"+timecodepath+u"\' \'Z:\\"+tmpmp4+u"\' -o \'Z:\\"+pout+u"\'"\r
92     os.environ['LANG']="ja_JP.UTF-8"\r
93     txt=""\r
94     try:\r
95         txt=txt+execcomd(exe0)+"\n"\r
96         txt=txt+execcomd(exe1)+"\n"\r
97         txt=txt+execcomd(exe2)+"\n"\r
98         txt=txt+execcomd(exe3)+"\n"\r
99     except:\r
100         ""\r
101     recdblist.addlog(pin, txt, u"MKV2MP4-log")\r
102     txt = "\n####MKV2MP4-log####\n"+txt\r
103     time.sleep(10)\r
104     if status.getSettings_auto_del_tmp()==1:\r
105         if os.path.exists(pout):\r
106             auto_process.deltmpfile(dir, title, ".mp4")\r
107 def addCaption(pts,pmp4):##字幕の追加を試みる。\r
108     wineexe=configreader.getpath("wine")\r
109     pincap=pts.replace(".ts",".srt")\r
110     try:\r
111         cap2ass=configreader.getpath("caption2ass")\r
112     except:\r
113         cap2ass=""\r
114     if os.path.isfile(cap2ass):\r
115         e0=wineexe+u" "+cap2ass+u" -format srt \"Z:\\"+pts+"\" \"Z:\\"+pincap+"\""\r
116         recdblist.printutf8(e0)\r
117         p0=subprocess.Popen(e0,shell=True,stdout=subprocess.PIPE)\r
118         time.sleep(100)\r
119         if p0.poll==None:#実行中\r
120             #if os.path.getsize(pincap)<1000:#2mで1kb以下の場合自動で終了\r
121              #   os.kill(p0.pid,signal.SIGKILL)\r
122             #else:\r
123             os.waitpid(p0.pid, 0)\r
124             logt=unicode(p0.communicate()[0], "UTF-8")\r
125             recdblist.addlog(pts,e0, u"Captionログ-コマンド")\r
126             recdblist.addlog(pts,logt, u"Captionログ-詳細")\r
127         if os.path.exists(pincap):\r
128             if os.path.getsize(pincap)>1000:\r
129                 exe = configreader.getpath("mp4box")\r
130                 e1s=exe +u" -add \""+pincap+"\" \""+pmp4+"\""\r
131                 addmp4(pincap,pmp4,e1s)\r
132 def addAudio(pts,pmp4,opts):#オプションに応じた音声の追加を行う\r
133     exe = configreader.getpath("mp4box")\r
134     if re.search("d",opts) or re.search("5",opts):#二カ国語放送/5.1ch放送の場合\r
135         paac1=pts.replace(".ts","_1.aac")\r
136         paac2=pts.replace(".ts","_2.aac")\r
137         recdblist.printutf8(paac1)\r
138         if not os.path.exists(paac1):\r
139             paac1=pts.replace(".ts","_1.mp3")\r
140         if not os.path.exists(paac2):\r
141             paac2=pts.replace(".ts","_2.mp3")\r
142         e1a1=exe +u" -add \""+paac1+"\" \""+pmp4+"\""\r
143         e1a2=exe +u" -add \""+paac2+"\" \""+pmp4+"\""\r
144         if os.path.exists(paac1):\r
145             addmp4(paac1, pmp4, e1a1)\r
146         if os.path.exists(paac2):\r
147             addmp4(paac2, pmp4, e1a2)\r
148     else:\r
149         tv2audio.ts2single_audio(pts,opts)\r
150         pinaac=pts.replace(".ts",".aac")\r
151         if not os.path.exists(pinaac):\r
152             pinaac=pinaac.replace(".aac",".mp3")\r
153         e1a=exe +u" -add \""+pinaac+"\" \""+pmp4+"\""\r
154         if os.path.exists(pinaac):\r
155             addmp4(pinaac, pmp4, e1a)\r
156 def execmp4box(pin,pout,cmd):\r
157     title=os.path.splitext(os.path.split(pin)[1])[0]\r
158     nt=base64.b16encode(title.encode('utf-8'))\r
159     if len(nt)>200:\r
160         nt=nt[:180]\r
161     ptin=os.path.join(os.path.dirname(pin),nt+".264")\r
162     recdblist.printutf8(ptin)\r
163     shutil.move(pin,ptin)\r
164     time.sleep(10)\r
165     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
166     cmdn=string.replace(cmd,pin,ptin)\r
167     cmdn=string.replace(cmdn,pout,ptout)\r
168     recdblist.printutf8(cmdn)\r
169     txt=""\r
170     try:\r
171         txt=execcomd(cmdn)\r
172     except Exception, inst:\r
173         txt= "error occures in execmp4box\n"\r
174         txt=txt+ str(type(inst))+"\n"\r
175         txt=txt+str(inst)\r
176         recdblist.Commonlogex("Error", "excecmp4box(tv2mp4.py)", str(type(inst)), str(inst)+traceback.format_exc(),verbose_level=200,log_level=200)\r
177     recdblist.addlog(pin, cmdn, u"MP4Boxログ-コマンド")\r
178     recdblist.addlog(pin, txt, u"MP4Boxログ-詳細")\r
179     time.sleep(5)\r
180     shutil.move(ptin,pin)\r
181     shutil.move(ptout,pout)\r
182     time.sleep(5)\r
183 def addmp4(padd,pout,cmd):#without video\r
184     title=os.path.splitext(os.path.split(padd)[1])[0]\r
185     ext=os.path.splitext(os.path.split(padd)[1])[1]\r
186     nt=base64.b16encode(title.encode('utf-8'))\r
187     if len(nt)>200:\r
188         nt=nt[:180]\r
189     ptadd=os.path.join(os.path.dirname(padd),nt+ext)\r
190     ptoutb=os.path.join(os.path.dirname(pout),nt+"_b.mp4")\r
191     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
192     shutil.move(padd,ptadd)\r
193     if os.path.isfile(pout):\r
194         shutil.move(pout,ptoutb)\r
195     time.sleep(5)\r
196     cmdn=string.replace(cmd,padd,ptadd)\r
197     cmdn=string.replace(cmdn,u"-out \""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
198     cmdn=string.replace(cmdn,u"\""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
199     cmdn=string.replace(cmdn,pout,ptout)\r
200     recdblist.printutf8(cmdn)\r
201     txt=""\r
202     try:\r
203         txt=execcomd(cmdn)\r
204     except Exception, inst:\r
205         txt= "error occures in addmp4\n"\r
206         txt=txt+ str(type(inst))+"\n"\r
207         txt=txt+str(inst)\r
208     recdblist.addlog(pout, cmdn, u"MP4Box追加ログ-コマンド")\r
209     recdblist.addlog(pout, txt, u"MP4Box追加ログ-詳細")\r
210     time.sleep(5)\r
211     shutil.move(ptadd,padd)\r
212     if os.path.exists(ptout):\r
213         shutil.move(ptout,pout)\r
214         os.remove(ptoutb)\r
215     else:\r
216         txtt=padd+u"のインポートエラー"\r
217         recdblist.addlog(pout, txtt, u"MP4Box追加ログ-コマンド")\r
218         shutil.move(ptoutb,pout)\r
219     time.sleep(5)\r
220 def execcomd(cmd):\r
221     txt=""\r
222     try:\r
223         txt=u"Cmd : "+cmd+"\n"\r
224         txt2=commands.getoutput(cmd.encode('utf-8'))\r
225         txt=txt+unicode(txt2,"utf-8")+"\n"\r
226     except:\r
227         ""\r
228     return txt