OSDN Git Service

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