OSDN Git Service

implement caption/audio 0 byte error auto skip system.
[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)\r
112         time.sleep(120)\r
113         if p0.poll==-1:#実行中\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     if os.path.getsize(pincap)>1000:\r
119         exe = configreader.getpath("mp4box")\r
120         e1s=exe +u" -add \""+pincap+"\" \""+pout+"\""\r
121         addmp4(pincap,pmp4,e1s)\r
122 def addAudio(pts,pmp4,opt):#オプションに応じた音声の追加を行う\r
123     exe = configreader.getpath("mp4box")\r
124     if re.search("d",opt) or re.search("5",opt):#二カ国語放送/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         addmp4(paac1, pmp4, e1a1)\r
135         addmp4(paac2, pmp4, e1a2)\r
136     else:\r
137         tv2audio.ts2single_audio(pts)\r
138         pinaac=pts.replace(".ts",".aac")\r
139         if os.path.exists(pinaac):\r
140             pinaac=pinaac.replace(".aac",".mp3")\r
141         e1a=exe +u" -add \""+pinaac+"\" \""+pmp4+"\""\r
142         addmp4(paac1, pmp4, e1a)\r
143 def execmp4box(pin,pout,cmd):\r
144     title=os.path.splitext(os.path.split(pin)[1])[0]\r
145     nt=base64.b16encode(title.encode('utf-8'))\r
146     if len(nt)>200:\r
147         nt=nt[:180]\r
148     ptin=os.path.join(os.path.dirname(pin),nt+".264")\r
149     recdblist.printutf8(ptin)\r
150     shutil.move(pin,ptin)\r
151     time.sleep(10)\r
152     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
153     cmdn=string.replace(cmd,pin,ptin)\r
154     cmdn=string.replace(cmdn,pout,ptout)\r
155     recdblist.printutf8(cmdn)\r
156     txt=""\r
157     try:\r
158         txt=execcomd(cmdn)\r
159     except Exception, inst:\r
160         txt= "error occures in execmp4box\n"\r
161         txt=txt+ str(type(inst))+"\n"\r
162         txt=txt+str(inst)\r
163     recdblist.addlog(pin, txt, "MP4Box-log")\r
164     time.sleep(5)\r
165     shutil.move(ptin,pin)\r
166     shutil.move(ptout,pout)\r
167     time.sleep(5)\r
168 def addmp4(padd,pout,cmd):#without video\r
169     title=os.path.splitext(os.path.split(padd)[1])[0]\r
170     ext=os.path.splitext(os.path.split(padd)[1])[1]\r
171     nt=base64.b16encode(title.encode('utf-8'))\r
172     if len(nt)>200:\r
173         nt=nt[:180]\r
174     ptadd=os.path.join(os.path.dirname(padd),nt+ext)\r
175     ptoutb=os.path.join(os.path.dirname(pout),nt+"_b.mp4")\r
176     ptout=os.path.join(os.path.dirname(pout),nt+".mp4")\r
177     shutil.move(padd,ptadd)\r
178     if os.path.isfile(pout):\r
179         shutil.move(pout,ptoutb)\r
180     time.sleep(5)\r
181     cmdn=string.replace(cmd,padd,ptadd)\r
182     cmdn=string.replace(cmdn,u"-out \""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
183     cmdn=string.replace(cmdn,u"\""+pout,u"-add \""+ptoutb+"\" -new \""+ptout)\r
184     cmdn=string.replace(cmdn,pout,ptout)\r
185     recdblist.printutf8(cmdn)\r
186     txt=""\r
187     try:\r
188         txt=execcomd(cmdn)\r
189     except Exception, inst:\r
190         txt= "error occures in addmp4\n"\r
191         txt=txt+ str(type(inst))+"\n"\r
192         txt=txt+str(inst)\r
193     recdblist.addlog(pout, txt, "MP4Box-log-add")\r
194     time.sleep(5)\r
195     os.remove(ptoutb)\r
196     shutil.move(ptadd,padd)\r
197     shutil.move(ptout,pout)\r
198     time.sleep(5)\r
199 def execcomd(cmd):\r
200     txt=""\r
201     try:\r
202         txt=u"Cmd : "+cmd+"\n"\r
203         txt2=commands.getoutput(cmd.encode('utf-8'))\r
204         txt=txt+unicode(txt2,"utf-8")+"\n"\r
205     except:\r
206         ""\r
207     return txt\r
208 \r
209 def deltitle(path,title):\r
210     dp=[]\r
211     dp.append(os.path.join(path,title+".avi"))\r
212     dp.append(os.path.join(path,title+".264"))\r
213     dp.append(os.path.join(path,title+".120.avi"))\r
214     dp.append(os.path.join(path,title+".noodml.avi"))\r
215     dp.append(os.path.join(path,title+".aac"))\r
216     dp.append(os.path.join(path,title+".m2v"))\r
217     dp.append(os.path.join(path,title+"_1.aac"))\r
218     dp.append(os.path.join(path,title+"_2.aac"))\r
219     dp.append(os.path.join(path,title+"_1.mp3"))\r
220     dp.append(os.path.join(path,title+"_2.mp3"))\r
221     dp.append(os.path.join(path,title+".srt"))\r
222     if configreader.getenv("remove_ts")=="1":\r
223         dp.append(os.path.join(path,title+".ts"))\r
224     if os.path.exists(os.path.join(path,title+".ts"))and os.path.exists(os.path.join(path,title+".ts.b25")):\r
225         if os.path.getsize(os.path.join(path,title+".ts"))*10>os.path.getsize(os.path.join(path,title+".ts.b25")):\r
226             if os.path.getsize(os.path.join(path,title+".ts"))>1000*1000*100:\r
227                 dp.append(os.path.join(path,title+".ts.b25"))\r
228     if os.path.exists(os.path.join(path,title+".mp4")):\r
229         if os.path.getsize(os.path.join(path,title+".mp4"))>1000*1000*10:\r
230             for ip in dp:\r
231                 try:\r
232                     os.remove(ip)\r
233                 except:\r
234                     ""\r