OSDN Git Service

ff66102ad46ca470f044255ccac83f2211d55aa2
[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     nt=base64.b16encode(title.encode('utf-8'))\r
227     if len(nt)>200:\r
228         nt=nt[:180]\r
229     ptin=os.path.join(os.path.dirname(pin),nt+".264")\r
230     recdblist.printutf8(ptin)\r
231     shutil.move(pin,ptin)\r
232     time.sleep(10)\r
233     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
234     cmdn=string.replace(cmd,pin,ptin)\r
235     cmdn=string.replace(cmdn,pout,ptout)\r
236     recdblist.printutf8(cmdn)\r
237     txt=""\r
238     try:\r
239         txt=execcomd(cmdn)\r
240     except Exception, inst:\r
241         txt= "error occures in execmp4box\n"\r
242         txt=txt+ str(type(inst))+"\n"\r
243         txt=txt+str(inst)\r
244     recdblist.addlog(pin, txt, "MP4Box-log")\r
245     time.sleep(5)\r
246     shutil.move(ptin,pin)\r
247     shutil.move(ptout,pout)\r
248     time.sleep(5)\r
249 def addmp4(padd,pout,cmd):#without video\r
250     title=os.path.splitext(os.path.split(padd)[1])[0]\r
251     ext=os.path.splitext(os.path.split(padd)[1])[1]\r
252     nt=base64.b16encode(title.encode('utf-8'))\r
253     if len(nt)>200:\r
254         nt=nt[:180]\r
255     ptadd=os.path.join(os.path.dirname(padd),nt+ext)\r
256     ptoutb=os.path.join(os.path.dirname(pout),nt+"_b.mp4")\r
257     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
258     shutil.move(padd,ptadd)\r
259     if os.path.isfile(pout):\r
260         shutil.move(pout,ptoutb)\r
261     time.sleep(5)\r
262     cmdn=string.replace(cmd,padd,ptadd)\r
263     cmdn=string.replace(cmdn,u"-out \""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
264     cmdn=string.replace(cmdn,u"\""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
265     cmdn=string.replace(cmdn,pout,ptout)\r
266     recdblist.printutf8(cmdn)\r
267     txt=""\r
268     try:\r
269         txt=execcomd(cmdn)\r
270     except Exception, inst:\r
271         txt= "error occures in addmp4\n"\r
272         txt=txt+ str(type(inst))+"\n"\r
273         txt=txt+str(inst)\r
274     recdblist.addlog(pout, txt, "MP4Box-log-add")\r
275     time.sleep(5)\r
276     os.remove(ptoutb)\r
277     shutil.move(ptadd,padd)\r
278     shutil.move(ptout,pout)\r
279     time.sleep(5)\r
280 def execcomd(cmd):\r
281     txt=""\r
282     try:\r
283         txt=u"Cmd : "+cmd+"\n"\r
284         txt2=commands.getoutput(cmd.encode('utf-8'))\r
285         txt=txt+unicode(txt2,"utf-8")+"\n"\r
286     except:\r
287         ""\r
288     return txt\r
289 \r
290 def deltitle(path,title):\r
291     dp=[]\r
292     dp.append(os.path.join(path,title+".avi"))\r
293     dp.append(os.path.join(path,title+".264"))\r
294     dp.append(os.path.join(path,title+".120.avi"))\r
295     dp.append(os.path.join(path,title+".noodml.avi"))\r
296     dp.append(os.path.join(path,title+".aac"))\r
297     dp.append(os.path.join(path,title+".m2v"))\r
298     dp.append(os.path.join(path,title+"_1.aac"))\r
299     dp.append(os.path.join(path,title+"_2.aac"))\r
300     dp.append(os.path.join(path,title+"_1.mp3"))\r
301     dp.append(os.path.join(path,title+"_2.mp3"))\r
302     dp.append(os.path.join(path,title+".srt"))\r
303     if configreader.getenv("remove_ts")=="1":\r
304         dp.append(os.path.join(path,title+".ts"))\r
305     if os.path.exists(os.path.join(path,title+".ts"))and os.path.exists(os.path.join(path,title+".ts.b25")):\r
306         if os.path.getsize(os.path.join(path,title+".ts"))*10>os.path.getsize(os.path.join(path,title+".ts.b25")):\r
307             if os.path.getsize(os.path.join(path,title+".ts"))>1000*1000*100:\r
308                 dp.append(os.path.join(path,title+".ts.b25"))\r
309     if os.path.exists(os.path.join(path,title+".mp4")):\r
310         if os.path.getsize(os.path.join(path,title+".mp4"))>1000*1000*10:\r
311             for ip in dp:\r
312                 try:\r
313                     os.remove(ip)\r
314                 except:\r
315                     ""\r