OSDN Git Service

fix encode.
[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     if re.search("a",opt):\r
41         duration="-fps 23.976023 "\r
42     elif re.search("v",opt):\r
43         duration="-fps 23.976023 "\r
44     if re.search("d",opt):\r
45         duration="-fps 29.970030 "##ffmpegが24fpsに対応していないための措置\r
46     elif re.search("5",opt):\r
47         duration="-fps 29.970030 "##ffmpegが24fpsに対応していないための措置\r
48     exe = configreader.getpath("mp4box")\r
49     txt=""\r
50     os.environ['LANG']="ja_JP.UTF-8"\r
51     pints=pin.replace(".264",".ts")\r
52     e1=exe +u" "+duration+" -add \""+pin+"\" -new \""+pout+"\""\r
53     execmp4box(pin, pout, e1)\r
54     addAudio(pints, pout, opt)\r
55     addCaption(pints, pout)\r
56     recdblist.addlog(pout, txt, "mp4box-log")\r
57     if status.getSettings_auto_del_tmp()==1:\r
58         if os.path.exists(pout):\r
59             if re.search(opt,"MW8") or re.search(opt,"MW9"):\r
60                 if os.path.getsize(pout)>50*1000*1000:\r
61                     deltitle(dir,title)\r
62             elif re.search(opt,"8") or re.search(opt,"9"):\r
63                 ""\r
64             else:\r
65                 if os.path.getsize(pout)>100*1000*1000:\r
66                     deltitle(dir,title)\r
67 def mkv2mp4(pin,pout):\r
68     exeb = configreader.getpath(u"mkvextract")\r
69     exe = configreader.getpath(u"mp4Box")\r
70     #dtsedit=configreader.getpath("DtsEdit")\r
71     wineexe=configreader.getpath("wine")\r
72     dir=os.path.split(pin)[0]\r
73     title=os.path.split(pin)[1]\r
74     title=os.path.splitext(title)[0]\r
75     etitle=base64.b16encode(title.encode('utf-8'))\r
76     audiopath=os.path.join(dir,etitle+u"_audio.aac")\r
77     videopath=os.path.join(dir,etitle+u"_video.264")\r
78     timecodepath=os.path.join(dir,etitle+u"_1_timecode.txt")\r
79     tmpmp4=os.path.join(dir,etitle+u".tmp.mp4")\r
80     exe0=exeb+u" tracks \'"+pin+u"\' 1:\'"+videopath+u"\' 2:\'"+audiopath+u"\'"\r
81     exe1=exeb+u" timecodes_v2 \'"+pin+"\' 1:\'"+timecodepath+"\'"\r
82     exe2=exe+u" -fps 29.970030 -add \'"+videopath+u"\' -add \'"+audiopath+u"\' -new \'"+tmpmp4+u"\'"\r
83     exe3=wineexe+u" "+dtsedit+u" -tc \'Z:\\"+timecodepath+u"\' \'Z:\\"+tmpmp4+u"\' -o \'Z:\\"+pout+u"\'"\r
84     os.environ['LANG']="ja_JP.UTF-8"\r
85     txt=""\r
86     try:\r
87         txt=txt+execcomd(exe0)+"\n"\r
88         txt=txt+execcomd(exe1)+"\n"\r
89         txt=txt+execcomd(exe2)+"\n"\r
90         txt=txt+execcomd(exe3)+"\n"\r
91     except:\r
92         ""\r
93     recdblist.addlog(pin, txt, "MKV2MP4-log")\r
94     txt = "\n####MKV2MP4-log####\n"+txt\r
95     time.sleep(10)\r
96     if status.getSettings_auto_del_tmp()==1:\r
97         if os.path.exists(pout):\r
98             if os.path.getsize(pout)>100*1000*1000:\r
99                 deltitle(dir,title)\r
100 \r
101 def addCaption(pts,pmp4):##字幕の追加を試みる。\r
102     wineexe=configreader.getpath("wine")\r
103     pincap=pts.replace(".ts",".srt")\r
104     try:\r
105         cap2ass=configreader.getpath("caption2ass")\r
106     except:\r
107         cap2ass=""\r
108     if os.path.isfile(cap2ass):\r
109         e0=wineexe+u" "+cap2ass+u" -format srt \"Z:\\"+pts+"\" \"Z:\\"+pincap+"\""\r
110         recdblist.printutf8(e0)\r
111         p0=subprocess.Popen(e0,shell=True,stdout=subprocess.PIPE)\r
112         time.sleep(300)\r
113         if p0.poll==None:#実行中\r
114             #if os.path.getsize(pincap)<1000:#2mで1kb以下の場合自動で終了\r
115              #   os.kill(p0.pid,signal.SIGKILL)\r
116             #else:\r
117             os.waitpid(p0.pid, 0)\r
118             logt=unicode(p0.communicate()[0], "UTF-8")\r
119             recdblist.printutf8(logt)\r
120             recdblist.addlog(pts,logt, "Caption-Log")\r
121         if os.path.getsize(pincap)>1000:\r
122             exe = configreader.getpath("mp4box")\r
123             e1s=exe +u" -add \""+pincap+"\" \""+pmp4+"\""\r
124             addmp4(pincap,pmp4,e1s)\r
125 def addAudio(pts,pmp4,opt):#オプションに応じた音声の追加を行う\r
126     exe = configreader.getpath("mp4box")\r
127     if re.search("d",opt) or re.search("5",opt):#二カ国語放送/5.1ch放送の場合\r
128         paac1=pts.replace(".ts","_1.aac")\r
129         paac2=pts.replace(".ts","_2.aac")\r
130         recdblist.printutf8(paac1)\r
131         if not os.path.exists(paac1):\r
132             paac1=pts.replace(".ts","_1.mp3")\r
133         if not os.path.exists(paac2):\r
134             paac2=pts.replace(".ts","_2.mp3")\r
135         e1a1=exe +u" -add \""+paac1+"\" \""+pmp4+"\""\r
136         e1a2=exe +u" -add \""+paac2+"\" \""+pmp4+"\""\r
137         addmp4(paac1, pmp4, e1a1)\r
138         addmp4(paac2, pmp4, e1a2)\r
139     else:\r
140         tv2audio.ts2single_audio(pts)\r
141         pinaac=pts.replace(".ts",".aac")\r
142         if not os.path.exists(pinaac):\r
143             pinaac=pinaac.replace(".aac",".mp3")\r
144         e1a=exe +u" -add \""+pinaac+"\" \""+pmp4+"\""\r
145         addmp4(pinaac, pmp4, e1a)\r
146 def execmp4box(pin,pout,cmd):\r
147     title=os.path.splitext(os.path.split(pin)[1])[0]\r
148     nt=base64.b16encode(title.encode('utf-8'))\r
149     if len(nt)>200:\r
150         nt=nt[:180]\r
151     ptin=os.path.join(os.path.dirname(pin),nt+".264")\r
152     recdblist.printutf8(ptin)\r
153     shutil.move(pin,ptin)\r
154     time.sleep(10)\r
155     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
156     cmdn=string.replace(cmd,pin,ptin)\r
157     cmdn=string.replace(cmdn,pout,ptout)\r
158     recdblist.printutf8(cmdn)\r
159     txt=""\r
160     try:\r
161         txt=execcomd(cmdn)\r
162     except Exception, inst:\r
163         txt= "error occures in execmp4box\n"\r
164         txt=txt+ str(type(inst))+"\n"\r
165         txt=txt+str(inst)\r
166     recdblist.addlog(pin, txt, "MP4Box-log")\r
167     time.sleep(5)\r
168     shutil.move(ptin,pin)\r
169     shutil.move(ptout,pout)\r
170     time.sleep(5)\r
171 def addmp4(padd,pout,cmd):#without video\r
172     title=os.path.splitext(os.path.split(padd)[1])[0]\r
173     ext=os.path.splitext(os.path.split(padd)[1])[1]\r
174     nt=base64.b16encode(title.encode('utf-8'))\r
175     if len(nt)>200:\r
176         nt=nt[:180]\r
177     ptadd=os.path.join(os.path.dirname(padd),nt+ext)\r
178     ptoutb=os.path.join(os.path.dirname(pout),nt+"_b.mp4")\r
179     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
180     shutil.move(padd,ptadd)\r
181     if os.path.isfile(pout):\r
182         shutil.move(pout,ptoutb)\r
183     time.sleep(5)\r
184     cmdn=string.replace(cmd,padd,ptadd)\r
185     cmdn=string.replace(cmdn,u"-out \""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
186     cmdn=string.replace(cmdn,u"\""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
187     cmdn=string.replace(cmdn,pout,ptout)\r
188     recdblist.printutf8(cmdn)\r
189     txt=""\r
190     try:\r
191         txt=execcomd(cmdn)\r
192     except Exception, inst:\r
193         txt= "error occures in addmp4\n"\r
194         txt=txt+ str(type(inst))+"\n"\r
195         txt=txt+str(inst)\r
196     recdblist.addlog(pout, txt, "MP4Box-log-add")\r
197     time.sleep(5)\r
198     os.remove(ptoutb)\r
199     shutil.move(ptadd,padd)\r
200     shutil.move(ptout,pout)\r
201     time.sleep(5)\r
202 def execcomd(cmd):\r
203     txt=""\r
204     try:\r
205         txt=u"Cmd : "+cmd+"\n"\r
206         txt2=commands.getoutput(cmd.encode('utf-8'))\r
207         txt=txt+unicode(txt2,"utf-8")+"\n"\r
208     except:\r
209         ""\r
210     return txt\r
211 \r
212 def deltitle(path,title):\r
213     dp=[]\r
214     dp.append(os.path.join(path,title+".avi"))\r
215     dp.append(os.path.join(path,title+".264"))\r
216     dp.append(os.path.join(path,title+".120.avi"))\r
217     dp.append(os.path.join(path,title+".noodml.avi"))\r
218     dp.append(os.path.join(path,title+".aac"))\r
219     dp.append(os.path.join(path,title+".m2v"))\r
220     dp.append(os.path.join(path,title+"_1.aac"))\r
221     dp.append(os.path.join(path,title+"_2.aac"))\r
222     dp.append(os.path.join(path,title+"_1.mp3"))\r
223     dp.append(os.path.join(path,title+"_2.mp3"))\r
224     dp.append(os.path.join(path,title+".srt"))\r
225     if configreader.getenv("remove_ts")=="1":\r
226         dp.append(os.path.join(path,title+".ts"))\r
227     if os.path.exists(os.path.join(path,title+".ts"))and os.path.exists(os.path.join(path,title+".ts.b25")):\r
228         if os.path.getsize(os.path.join(path,title+".ts"))*10>os.path.getsize(os.path.join(path,title+".ts.b25")):\r
229             if os.path.getsize(os.path.join(path,title+".ts"))>1000*1000*100:\r
230                 dp.append(os.path.join(path,title+".ts.b25"))\r
231     if os.path.exists(os.path.join(path,title+".mp4")):\r
232         if os.path.getsize(os.path.join(path,title+".mp4"))>1000*1000*10:\r
233             for ip in dp:\r
234                 try:\r
235                     os.remove(ip)\r
236                 except:\r
237                     ""\r