OSDN Git Service

change MP4Box option to make videos more familiar for iPad
[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         e1a1=exe +u" -add \""+paac1+"\":mpeg4 \""+pmp4+"\""\r
136         e1a2=exe +u" -add \""+paac2+"\":mpeg4 \""+pmp4+"\""\r
137         if not os.path.exists(paac1):\r
138             paac1=pts.replace(".ts","_1.mp3")\r
139             e1a1=exe +u" -add \""+paac1+"\" \""+pmp4+"\""\r
140         if not os.path.exists(paac2):\r
141             paac2=pts.replace(".ts","_2.mp3")\r
142             e1a1=exe +u" -add \""+paac2+"\" \""+pmp4+"\""\r
143         if os.path.exists(paac1):\r
144             addmp4(paac1, pmp4, e1a1)\r
145         if os.path.exists(paac2):\r
146             addmp4(paac2, pmp4, e1a2)\r
147     elif re.search("b",opts):#BonTsDemuxを使って音声をスプリットした場合\r
148         paac=pts.replace(".ts",".aac")\r
149         e1a=exe +u" -add \""+pinaac+"\":mpeg4 \""+pmp4+"\""\r
150         if not os.path.exists(paac):\r
151             paac=pts.replace(".ts",".mp3")\r
152             e1a1=exe +u" -add \""+paac+"\" \""+pmp4+"\""\r
153         if os.path.exists(paac):\r
154             addmp4(paac, pmp4, e1a1)\r
155     else:\r
156         tv2audio.ts2single_audio(pts,opts)\r
157         pinaac=pts.replace(".ts",".aac")\r
158         e1a=exe +u" -add \""+pinaac+"\":mpeg4 \""+pmp4+"\""\r
159         if not os.path.exists(pinaac):\r
160             pinaac=pinaac.replace(".aac",".mp3")\r
161             e1a=exe +u" -add \""+pinaac+"\" \""+pmp4+"\""\r
162         if os.path.exists(pinaac):\r
163             addmp4(pinaac, pmp4, e1a)\r
164 def execmp4box(pin,pout,cmd):\r
165     title=os.path.splitext(os.path.split(pin)[1])[0]\r
166     nt=base64.b16encode(title.encode('utf-8'))\r
167     if len(nt)>200:\r
168         nt=nt[:180]\r
169     ptin=os.path.join(os.path.dirname(pin),nt+".264")\r
170     recdblist.printutf8(ptin)\r
171     shutil.move(pin,ptin)\r
172     time.sleep(10)\r
173     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
174     cmdn=string.replace(cmd,pin,ptin)\r
175     cmdn=string.replace(cmdn,pout,ptout)\r
176     recdblist.printutf8(cmdn)\r
177     recdblist.addCommandSelfLog(pin, cmdn)\r
178     txt=""\r
179     try:\r
180         txt=execcomd(cmdn)\r
181     except Exception, inst:\r
182         txt= "error occures in execmp4box\n"\r
183         txt=txt+ str(type(inst))+"\n"\r
184         txt=txt+str(inst)\r
185         recdblist.addCommonlogEX("Error", "excecmp4box(tv2mp4.py)", str(type(inst)), str(inst)+traceback.format_exc(),verbose_level=200,log_level=200)\r
186     recdblist.addLog(pin, cmdn, u"MP4Boxログ-コマンド")\r
187     recdblist.addLog(pin, txt, u"MP4Boxログ-詳細")\r
188     recdblist.addCommandLogZip(pin, "MP4Box", "mp4box", cmdn,txt)\r
189     time.sleep(5)\r
190     shutil.move(ptin,pin)\r
191     shutil.move(ptout,pout)\r
192     time.sleep(5)\r
193 def addmp4(padd,pout,cmd):#without video\r
194     title=os.path.splitext(os.path.split(padd)[1])[0]\r
195     ext=os.path.splitext(os.path.split(padd)[1])[1]\r
196     nt=base64.b16encode(title.encode('utf-8'))\r
197     if len(nt)>200:\r
198         nt=nt[:180]\r
199     ptadd=os.path.join(os.path.dirname(padd),nt+ext)\r
200     ptoutb=os.path.join(os.path.dirname(pout),nt+"_b.mp4")\r
201     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
202     shutil.move(padd,ptadd)\r
203     if os.path.isfile(pout):\r
204         shutil.move(pout,ptoutb)\r
205     time.sleep(5)\r
206     cmdn=string.replace(cmd,padd,ptadd)\r
207     cmdn=string.replace(cmdn,u"-out \""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
208     cmdn=string.replace(cmdn,u"\""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
209     cmdn=string.replace(cmdn,pout,ptout)\r
210     recdblist.printutf8(cmdn)\r
211     txt=""\r
212     try:\r
213         txt=execcomd(cmdn)\r
214     except Exception, inst:\r
215         txt= "error occures in addmp4\n"\r
216         txt=txt+ str(type(inst))+"\n"\r
217         txt=txt+str(inst)\r
218     recdblist.addLog(pout, cmdn, u"MP4Box追加ログ-コマンド")\r
219     recdblist.addLog(pout, txt, u"MP4Box追加ログ-詳細")\r
220     recdblist.addCommandLogZip(pout, "MP4Box_add", "mp4box_add", cmdn, txt)\r
221     time.sleep(5)\r
222     shutil.move(ptadd,padd)\r
223     if os.path.exists(ptout):\r
224         shutil.move(ptout,pout)\r
225         os.remove(ptoutb)\r
226     else:\r
227         txtt=padd+u"のインポートエラー"\r
228         recdblist.addLog(pout, txtt, u"MP4Box追加ログ-コマンド")\r
229         shutil.move(ptoutb,pout)\r
230     time.sleep(5)\r
231 def execcomd(cmd):\r
232     txt=""\r
233     try:\r
234         txt=u"Cmd : "+cmd+"\n"\r
235         txt2=commands.getoutput(cmd.encode('utf-8'))\r
236         txt=txt+unicode(txt2,"utf-8")+"\n"\r
237     except:\r
238         ""\r
239     return txt\r