OSDN Git Service

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