OSDN Git Service

implement caption/audio 0 byte error auto skip system.
[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 tv2avi\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 recdblist\r
15 import configreader\r
16 import status\r
17 import subprocess\r
18 import signal\r
19 import tv2audio\r
20 \r
21 def ts2mp4(pin, pout, opt):\r
22     dir=os.path.split(pout)[0]\r
23     title=os.path.split(pout)[1]\r
24     title=os.path.splitext(title)[0]\r
25     tpraw=os.path.join(dir, title+".264")\r
26     tpmp4=os.path.join(dir, title+".mp4")\r
27     if os.path.isfile(pin) and os.path.getsize(pin)>10*1000:\r
28         tv2avi.ts2raw(pin, tpraw, opt)\r
29         time.sleep(10)\r
30         if os.path.isfile(tpraw) and os.path.getsize(tpraw)>10*1000:\r
31             raw2mp4(tpraw, tpmp4, opt)\r
32         time.sleep(10)\r
33         if os.path.exists(tpraw):\r
34             os.remove(tpraw)\r
35 def raw2mp4(pin,pout,opt):\r
36     dir=os.path.split(pout)[0]\r
37     title=os.path.split(pout)[1]\r
38     title=os.path.splitext(title)[0]\r
39     duration="-fps 29.970030 "\r
40     ffmpeg=configreader.getpath("ffmpeg")\r
41     isdualaac=0\r
42     ispentaaudio=0\r
43     if re.search("a",opt):\r
44         duration="-fps 23.976023 "\r
45     elif re.search("v",opt):\r
46         duration="-fps 23.976023 "\r
47     if re.search("d",opt):\r
48         isdualaac=1\r
49         duration="-fps 29.970030 "##ffmpegが24fpsに対応していないための措置\r
50     elif re.search("5",opt):\r
51         ispentaaudio=1\r
52         duration="-fps 29.970030 "##ffmpegが24fpsに対応していないための措置\r
53     exe = configreader.getpath("mp4box")\r
54     txt=""\r
55     os.environ['LANG']="ja_JP.UTF-8"\r
56     if isdualaac==1:\r
57         wineexe=configreader.getpath("wine")\r
58         #pincap=pin.replace(".264",".srt")\r
59         #try:\r
60         #    cap2ass=configreader.getpath("caption2ass")\r
61         #except:\r
62         #    cap2ass=""\r
63         pints=pin.replace(".264",".ts")\r
64         #paac1=pin.replace(".264","_1.aac")\r
65         #paac2=pin.replace(".264","_2.aac")\r
66         #recdblist.printutf8(paac1)\r
67         #if not os.path.exists(paac1):\r
68         #    paac1=pin.replace(".264","_1.mp3")\r
69         #if not os.path.exists(paac2):\r
70         #    paac2=pin.replace(".264","_2.mp3")\r
71         #e0=wineexe+u" "+cap2ass+u" -format srt \"Z:\\"+pints+"\" \"Z:\\"+pincap+"\""\r
72         e1=exe +u" "+duration+" -add \""+pin+"\" -new \""+pout+"\""\r
73         #e1a1=exe +u" -add \""+paac1+"\" \""+pout+"\""\r
74         #e1a2=exe +u" -add \""+paac2+"\" \""+pout+"\""\r
75         #e1s=exe +u" -add \""+pincap+"\" \""+pout+"\""\r
76         #if os.path.isfile(cap2ass):\r
77         #    txt=txt+execcomd(e0)\r
78         execmp4box(pin, pout, e1)\r
79         #addmp4(paac1, pout, e1a1)\r
80         #addmp4(paac2, pout, e1a2)\r
81         addAudio(pints, pout, opt)\r
82         addCaption(pints, pout)\r
83         #if os.path.exists(pincap) and (os.path.getsize(pincap)>1000):\r
84         #    addmp4(pincap, pout, e1s)\r
85     elif ispentaaudio==1:\r
86         #wineexe=configreader.getpath("wine")\r
87         #pincap=pin.replace(".264",".srt")\r
88         #try:\r
89         #    cap2ass=configreader.getpath("caption2ass")\r
90         #except:\r
91         #    cap2ass=""\r
92         pints=pin.replace(".264",".ts")\r
93         #paac1=pin.replace(".264","_1.aac")\r
94         #paac2=pin.replace(".264","_2.aac")\r
95         #recdblist.printutf8(paac1)\r
96         #if not os.path.exists(paac1):\r
97         #    paac1=pin.replace(".264","_1.mp3")\r
98         #if not os.path.exists(paac2):\r
99         #    paac2=pin.replace(".264","_2.mp3")\r
100         #e0=wineexe+u" "+cap2ass+u" -format srt \"Z:\\"+pints+"\" \"Z:\\"+pincap+"\""\r
101         e1=exe +u" "+duration+" -add \""+pin+"\" -new \""+pout+"\""\r
102         #e1a1=exe +u" -add \""+paac1+"\" \""+pout+"\""\r
103         #e1a2=exe +u" -add \""+paac2+"\" \""+pout+"\""\r
104         #e1s=exe +u" -add \""+pincap+"\" \""+pout+"\""\r
105         #if os.path.isfile(cap2ass):\r
106         #    txt=txt+execcomd(e0)\r
107         execmp4box(pin, pout, e1)\r
108         addAudio(pints, pout, opt)\r
109         #addmp4(paac1, pout, e1a1)\r
110         #addmp4(paac2, pout, e1a2)\r
111         addCaption(pints, pout)\r
112         #if os.path.exists(pincap) and (os.path.getsize(pincap)>1000):\r
113         #    addmp4(pincap, pout, e1s)\r
114     else:\r
115         #wineexe=configreader.getpath("wine")\r
116         #pincap=pin.replace(".264",".srt")\r
117         #try:\r
118         #    cap2ass=configreader.getpath("caption2ass")\r
119         #except:\r
120         #    cap2ass=""\r
121         pints=pin.replace(".264",".ts")\r
122         #pinaac=pin.replace(".264",".aac")\r
123         #e0=wineexe+u" "+cap2ass+u" -format srt \"Z:\\"+pints+"\" \"Z:\\"+pincap+"\""\r
124         #e1=ffmpeg+" -i \""+pints+"\" -vn -f aac -acodec copy \""+pinaac+"\""\r
125         e2=exe +u" "+duration+" -add \""+pin+"\" -new \""+pout+"\""\r
126         #e2a=exe +u" -add \""+pinaac+"\" \""+pout+"\""\r
127         #e2s=exe +u" -add \""+pincap+"\" \""+pout+"\""\r
128         #if os.path.isfile(cap2ass):\r
129         #    txt=txt+execcomd(e0)\r
130         #txttt=execcomd(e1)\r
131         #recdblist.addlog(pin, txttt, "get_aac")\r
132         execmp4box(pin, pout, e2)\r
133         addAudio(pints, pout, opt)\r
134         #addmp4(pinaac, pout, e2a)\r
135         addCaption(pints, pout)\r
136         #if os.path.exists(pincap) and (os.path.getsize(pincap)>1000):\r
137         #    addmp4(pincap, pout, e2s)\r
138     recdblist.addlog(pout, txt, "mp4box-log")\r
139     if status.getSettings_auto_del_tmp()==1:\r
140         if os.path.exists(pout):\r
141             if re.search(opt,"MW8") or re.search(opt,"MW9"):\r
142                 if os.path.getsize(pout)>50*1000*1000:\r
143                     deltitle(dir,title)\r
144             elif re.search(opt,"8") or re.search(opt,"9"):\r
145                 ""\r
146             else:\r
147                 if os.path.getsize(pout)>100*1000*1000:\r
148                     deltitle(dir,title)\r
149 def mkv2mp4(pin,pout):\r
150     exeb = configreader.getpath(u"mkvextract")\r
151     exe = configreader.getpath(u"mp4Box")\r
152     #dtsedit=configreader.getpath("DtsEdit")\r
153     wineexe=configreader.getpath("wine")\r
154     dir=os.path.split(pin)[0]\r
155     title=os.path.split(pin)[1]\r
156     title=os.path.splitext(title)[0]\r
157     etitle=base64.b16encode(title.encode('utf-8'))\r
158     audiopath=os.path.join(dir,etitle+u"_audio.aac")\r
159     videopath=os.path.join(dir,etitle+u"_video.264")\r
160     timecodepath=os.path.join(dir,etitle+u"_1_timecode.txt")\r
161     tmpmp4=os.path.join(dir,etitle+u".tmp.mp4")\r
162     exe0=exeb+u" tracks \'"+pin+u"\' 1:\'"+videopath+u"\' 2:\'"+audiopath+u"\'"\r
163     exe1=exeb+u" timecodes_v2 \'"+pin+"\' 1:\'"+timecodepath+"\'"\r
164     exe2=exe+u" -fps 29.970030 -add \'"+videopath+u"\' -add \'"+audiopath+u"\' -new \'"+tmpmp4+u"\'"\r
165     exe3=wineexe+u" "+dtsedit+u" -tc \'Z:\\"+timecodepath+u"\' \'Z:\\"+tmpmp4+u"\' -o \'Z:\\"+pout+u"\'"\r
166     os.environ['LANG']="ja_JP.UTF-8"\r
167     txt=""\r
168     try:\r
169         txt=txt+execcomd(exe0)+"\n"\r
170         txt=txt+execcomd(exe1)+"\n"\r
171         txt=txt+execcomd(exe2)+"\n"\r
172         txt=txt+execcomd(exe3)+"\n"\r
173     except:\r
174         ""\r
175     recdblist.addlog(pin, txt, "MKV2MP4-log")\r
176     txt = "\n####MKV2MP4-log####\n"+txt\r
177     time.sleep(10)\r
178     if status.getSettings_auto_del_tmp()==1:\r
179         if os.path.exists(pout):\r
180             if os.path.getsize(pout)>100*1000*1000:\r
181                 deltitle(dir,title)\r
182 \r
183 def addCaption(pts,pmp4):##字幕の追加を試みる。\r
184     wineexe=configreader.getpath("wine")\r
185     pincap=pts.replace(".ts",".srt")\r
186     try:\r
187         cap2ass=configreader.getpath("caption2ass")\r
188     except:\r
189         cap2ass=""\r
190     if os.path.isfile(cap2ass):\r
191         e0=wineexe+u" "+cap2ass+u" -format srt \"Z:\\"+pts+"\" \"Z:\\"+pincap+"\""\r
192         p0=subprocess.Popen(e0,shell=True)\r
193         time.sleep(120)\r
194         if p0.poll==-1:#実行中\r
195             if os.path.getsize(pincap)<1000:#2mで1kb以下の場合自動で終了\r
196                 os.kill(p0.pid,signal.SIGKILL)\r
197             else:\r
198                 os.waitpid(p0.pid, 0)\r
199     if os.path.getsize(pincap)>1000:\r
200         exe = configreader.getpath("mp4box")\r
201         e1s=exe +u" -add \""+pincap+"\" \""+pout+"\""\r
202         addmp4(pincap,pmp4,e1s)\r
203 def addAudio(pts,pmp4,opt):#オプションに応じた音声の追加を行う\r
204     exe = configreader.getpath("mp4box")\r
205     if re.search("d",opt) or re.search("5",opt):#二カ国語放送/5.1ch放送の場合\r
206         paac1=pts.replace(".ts","_1.aac")\r
207         paac2=pts.replace(".ts","_2.aac")\r
208         recdblist.printutf8(paac1)\r
209         if not os.path.exists(paac1):\r
210             paac1=pts.replace(".ts","_1.mp3")\r
211         if not os.path.exists(paac2):\r
212             paac2=pts.replace(".ts","_2.mp3")\r
213         e1a1=exe +u" -add \""+paac1+"\" \""+pmp4+"\""\r
214         e1a2=exe +u" -add \""+paac2+"\" \""+pmp4+"\""\r
215         addmp4(paac1, pmp4, e1a1)\r
216         addmp4(paac2, pmp4, e1a2)\r
217     else:\r
218         tv2audio.ts2single_audio(pts)\r
219         pinaac=pts.replace(".ts",".aac")\r
220         if os.path.exists(pinaac):\r
221             pinaac=pinaac.replace(".aac",".mp3")\r
222         e1a=exe +u" -add \""+pinaac+"\" \""+pmp4+"\""\r
223         addmp4(paac1, pmp4, e1a)\r
224 def execmp4box(pin,pout,cmd):\r
225     title=os.path.splitext(os.path.split(pin)[1])[0]\r
226     ptin=os.path.join(os.path.dirname(pin),base64.b16encode(title.encode('utf-8'))+".264")\r
227     recdblist.printutf8(ptin)\r
228     shutil.move(pin,ptin)\r
229     time.sleep(10)\r
230     ptout=os.path.join(os.path.dirname(pout),base64.b16encode(title.encode('utf-8'))+".mp4")\r
231     cmdn=string.replace(cmd,pin,ptin)\r
232     cmdn=string.replace(cmdn,pout,ptout)\r
233     recdblist.printutf8(cmdn)\r
234     txt=""\r
235     try:\r
236         txt=execcomd(cmdn)\r
237     except Exception, inst:\r
238         txt= "error occures in execmp4box\n"\r
239         txt=txt+ str(type(inst))+"\n"\r
240         txt=txt+str(inst)\r
241     recdblist.addlog(pin, txt, "MP4Box-log")\r
242     time.sleep(5)\r
243     shutil.move(ptin,pin)\r
244     shutil.move(ptout,pout)\r
245     time.sleep(5)\r
246 def addmp4(padd,pout,cmd):#without video\r
247     title=os.path.splitext(os.path.split(padd)[1])[0]\r
248     ext=os.path.splitext(os.path.split(padd)[1])[1]\r
249     ptadd=os.path.join(os.path.dirname(padd),base64.b16encode(title.encode('utf-8'))+ext)\r
250     ptoutb=os.path.join(os.path.dirname(pout),base64.b16encode(title.encode('utf-8'))+"_b.mp4")\r
251     ptout=os.path.join(os.path.dirname(pout),base64.b16encode(title.encode('utf-8'))+".mp4")\r
252     shutil.move(padd,ptadd)\r
253     if os.path.isfile(pout):\r
254         shutil.move(pout,ptoutb)\r
255     time.sleep(5)\r
256     cmdn=string.replace(cmd,padd,ptadd)\r
257     cmdn=string.replace(cmdn,u"-out \""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
258     cmdn=string.replace(cmdn,u"\""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
259     cmdn=string.replace(cmdn,pout,ptout)\r
260     recdblist.printutf8(cmdn)\r
261     txt=""\r
262     try:\r
263         txt=execcomd(cmdn)\r
264     except Exception, inst:\r
265         txt= "error occures in addmp4\n"\r
266         txt=txt+ str(type(inst))+"\n"\r
267         txt=txt+str(inst)\r
268     recdblist.addlog(pout, txt, "MP4Box-log-add")\r
269     time.sleep(5)\r
270     os.remove(ptoutb)\r
271     shutil.move(ptadd,padd)\r
272     shutil.move(ptout,pout)\r
273     time.sleep(5)\r
274 def execcomd(cmd):\r
275     txt=""\r
276     try:\r
277         txt=u"Cmd : "+cmd+"\n"\r
278         txt2=commands.getoutput(cmd.encode('utf-8'))\r
279         txt=txt+unicode(txt2,"utf-8")+"\n"\r
280     except:\r
281         ""\r
282     return txt\r
283 \r
284 def deltitle(path,title):\r
285     dp=[]\r
286     dp.append(os.path.join(path,title+".avi"))\r
287     dp.append(os.path.join(path,title+".264"))\r
288     dp.append(os.path.join(path,title+".120.avi"))\r
289     dp.append(os.path.join(path,title+".noodml.avi"))\r
290     dp.append(os.path.join(path,title+".aac"))\r
291     dp.append(os.path.join(path,title+".m2v"))\r
292     dp.append(os.path.join(path,title+"_1.aac"))\r
293     dp.append(os.path.join(path,title+"_2.aac"))\r
294     dp.append(os.path.join(path,title+"_1.mp3"))\r
295     dp.append(os.path.join(path,title+"_2.mp3"))\r
296     dp.append(os.path.join(path,title+".srt"))\r
297     if configreader.getenv("remove_ts")=="1":\r
298         dp.append(os.path.join(path,title+".ts"))\r
299     if os.path.exists(os.path.join(path,title+".ts"))and os.path.exists(os.path.join(path,title+".ts.b25")):\r
300         if os.path.getsize(os.path.join(path,title+".ts"))*10>os.path.getsize(os.path.join(path,title+".ts.b25")):\r
301             if os.path.getsize(os.path.join(path,title+".ts"))>1000*1000*100:\r
302                 dp.append(os.path.join(path,title+".ts.b25"))\r
303     if os.path.exists(os.path.join(path,title+".mp4")):\r
304         if os.path.getsize(os.path.join(path,title+".mp4"))>1000*1000*10:\r
305             for ip in dp:\r
306                 try:\r
307                     os.remove(ip)\r
308                 except:\r
309                     ""\r