OSDN Git Service

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