X-Git-Url: http://git.osdn.net/view?p=rec10%2Frec10-git.git;a=blobdiff_plain;f=rec10%2Ftrunk%2Fsrc%2Ftv2mp4.py;h=57864bbd59c1d635647dd3e63664f520eeff80b0;hp=4b231f860999157bc722c6aa99a0c2ab3cd890d5;hb=d63ca135202a679bd918561b65e806966f94546e;hpb=7160b23094399ee7fdc186331aa3096c353447c3 diff --git a/rec10/trunk/src/tv2mp4.py b/rec10/trunk/src/tv2mp4.py index 4b231f8..57864bb 100644 --- a/rec10/trunk/src/tv2mp4.py +++ b/rec10/trunk/src/tv2mp4.py @@ -1,223 +1,239 @@ -#!/usr/bin/python -# coding: UTF-8 -# Rec10 TS Recording Tools -# Copyright (C) 2009-2010 Yukikaze -import commands -import shutil -import auto_process -import os -import re -import os.path -import string -import base64 -import time -import subprocess -import traceback - -import tv2avi -import recdblist -import configreader -import status -import tv2audio - -def ts2mp4(pin, pout, opt): - dir=os.path.split(pout)[0] - title=os.path.split(pout)[1] - title=os.path.splitext(title)[0] - tpraw=os.path.join(dir, title+".264") - tpmp4=os.path.join(dir, title+".mp4") - if re.search("d",opt) and not os.path.exists(pin.replace(".ts",".m2v")): - tv2audio.ts2dualaudio_BonTsDemux(pin,recdblist.BONTSDEMUX_DELAY, opt) - if os.path.isfile(pin) and os.path.getsize(pin)>10*1000: - tv2avi.ts2raw(pin, tpraw, opt) - time.sleep(10) - if os.path.isfile(tpraw) and os.path.getsize(tpraw)>10*1000: - raw2mp4(tpraw, tpmp4, opt) - time.sleep(10) - if os.path.exists(tpraw): - os.remove(tpraw) -def raw2mp4(pin,pout,opt): - dir=os.path.split(pout)[0] - title=os.path.split(pout)[1] - title=os.path.splitext(title)[0] - duration="-fps 29.970030 " - if re.search("a",opt): - duration="-fps 23.976023 " - elif re.search("v",opt): - duration="-fps 23.976023 " - if re.search("d",opt): - duration="-fps 29.970030 "##ffmpegが24fpsに対応していないための措置 - elif re.search("5",opt): - duration="-fps 29.970030 "##ffmpegが24fpsに対応していないための措置 - if re.search("I",opt): - duration="-fps 29.970030 " - exe = configreader.getPathSetting("mp4box") - txt="" - os.environ['LANG']="ja_JP.UTF-8" - pints=pin.replace(".264",".ts") - e1=exe +u" "+duration+" -add \""+pin+"\" -new \""+pout+"\"" - execmp4box(pin, pout, e1) - addAudio(pints, pout, opt) - addCaption(pints, pout) - #recdblist.addlog(pout, txt, "mp4boxログ-コマンド") - #recdblist.addlog(pout, txt, "mp4boxログ-詳細") - if status.getSettings_auto_del_tmp()==1: - if os.path.exists(pout): - if re.search(opt,"1") or re.search(opt,"2"): - auto_process.deltmpfile(dir, title, ".mp4") - else: - auto_process.deltmpfile(dir, title, ".mp4") -def mkv2mp4(pin,pout): - exeb = configreader.getPathSetting(u"mkvextract") - exe = configreader.getPath(u"mp4Box") - #dtsedit=configreader.getPath("DtsEdit") - wineexe=configreader.getPathSetting("wine") - dir=os.path.split(pin)[0] - title=os.path.split(pin)[1] - title=os.path.splitext(title)[0] - etitle=base64.b16encode(title.encode('utf-8')) - audiopath=os.path.join(dir,etitle+u"_audio.aac") - videopath=os.path.join(dir,etitle+u"_video.264") - timecodepath=os.path.join(dir,etitle+u"_1_timecode.txt") - tmpmp4=os.path.join(dir,etitle+u".tmp.mp4") - exe0=exeb+u" tracks \'"+pin+u"\' 1:\'"+videopath+u"\' 2:\'"+audiopath+u"\'" - exe1=exeb+u" timecodes_v2 \'"+pin+"\' 1:\'"+timecodepath+"\'" - exe2=exe+u" -fps 29.970030 -add \'"+videopath+u"\' -add \'"+audiopath+u"\' -new \'"+tmpmp4+u"\'" - exe3=wineexe+u" "+dtsedit+u" -tc \'Z:\\"+timecodepath+u"\' \'Z:\\"+tmpmp4+u"\' -o \'Z:\\"+pout+u"\'" - os.environ['LANG']="ja_JP.UTF-8" - txt="" - try: - txt=txt+execcomd(exe0)+"\n" - txt=txt+execcomd(exe1)+"\n" - txt=txt+execcomd(exe2)+"\n" - txt=txt+execcomd(exe3)+"\n" - except: - "" - recdblist.addlog(pin, txt, u"MKV2MP4-log") - txt = "\n####MKV2MP4-log####\n"+txt - time.sleep(10) - if status.getSettings_auto_del_tmp()==1: - if os.path.exists(pout): - auto_process.deltmpfile(dir, title, ".mp4") -def addCaption(pts,pmp4):##字幕の追加を試みる。 - wineexe=configreader.getPathSetting("wine") - pincap=pts.replace(".ts",".srt") - try: - cap2ass=configreader.getPathSetting("caption2ass") - except: - cap2ass="" - if os.path.isfile(cap2ass): - e0=wineexe+u" "+cap2ass+u" -format srt \"Z:\\"+pts+"\" \"Z:\\"+pincap+"\"" - recdblist.printutf8(e0) - p0=subprocess.Popen(e0,shell=True,stdout=subprocess.PIPE) - time.sleep(100) - if p0.poll==None:#実行中 - #if os.path.getsize(pincap)<1000:#2mで1kb以下の場合自動で終了 - # os.kill(p0.pid,signal.SIGKILL) - #else: - os.waitpid(p0.pid, 0) - logt=unicode(p0.communicate()[0], "UTF-8") - recdblist.addlog(pts,e0, u"Captionログ-コマンド") - recdblist.addlog(pts,logt, u"Captionログ-詳細") - if os.path.exists(pincap): - if os.path.getsize(pincap)>1000: - exe = configreader.getPathSetting("mp4box") - e1s=exe +u" -add \""+pincap+"\" \""+pmp4+"\"" - addmp4(pincap,pmp4,e1s) -def addAudio(pts,pmp4,opts):#オプションに応じた音声の追加を行う - exe = configreader.getPathSetting("mp4box") - if re.search("d",opts) or re.search("5",opts):#二カ国語放送/5.1ch放送の場合 - paac1=pts.replace(".ts","_1.aac") - paac2=pts.replace(".ts","_2.aac") - recdblist.printutf8(paac1) - if not os.path.exists(paac1): - paac1=pts.replace(".ts","_1.mp3") - if not os.path.exists(paac2): - paac2=pts.replace(".ts","_2.mp3") - e1a1=exe +u" -add \""+paac1+"\" \""+pmp4+"\"" - e1a2=exe +u" -add \""+paac2+"\" \""+pmp4+"\"" - if os.path.exists(paac1): - addmp4(paac1, pmp4, e1a1) - if os.path.exists(paac2): - addmp4(paac2, pmp4, e1a2) - else: - tv2audio.ts2single_audio(pts,opts) - pinaac=pts.replace(".ts",".aac") - if not os.path.exists(pinaac): - pinaac=pinaac.replace(".aac",".mp3") - e1a=exe +u" -add \""+pinaac+"\" \""+pmp4+"\"" - if os.path.exists(pinaac): - addmp4(pinaac, pmp4, e1a) -def execmp4box(pin,pout,cmd): - title=os.path.splitext(os.path.split(pin)[1])[0] - nt=base64.b16encode(title.encode('utf-8')) - if len(nt)>200: - nt=nt[:180] - ptin=os.path.join(os.path.dirname(pin),nt+".264") - recdblist.printutf8(ptin) - shutil.move(pin,ptin) - time.sleep(10) - ptout=os.path.join(os.path.dirname(pout),nt+".mp4") - cmdn=string.replace(cmd,pin,ptin) - cmdn=string.replace(cmdn,pout,ptout) - recdblist.printutf8(cmdn) - txt="" - try: - txt=execcomd(cmdn) - except Exception, inst: - txt= "error occures in execmp4box\n" - txt=txt+ str(type(inst))+"\n" - txt=txt+str(inst) - recdblist.Commonlogex("Error", "excecmp4box(tv2mp4.py)", str(type(inst)), str(inst)+traceback.format_exc(),verbose_level=200,log_level=200) - recdblist.addlog(pin, cmdn, u"MP4Boxログ-コマンド") - recdblist.addlog(pin, txt, u"MP4Boxログ-詳細") - time.sleep(5) - shutil.move(ptin,pin) - shutil.move(ptout,pout) - time.sleep(5) -def addmp4(padd,pout,cmd):#without video - title=os.path.splitext(os.path.split(padd)[1])[0] - ext=os.path.splitext(os.path.split(padd)[1])[1] - nt=base64.b16encode(title.encode('utf-8')) - if len(nt)>200: - nt=nt[:180] - ptadd=os.path.join(os.path.dirname(padd),nt+ext) - ptoutb=os.path.join(os.path.dirname(pout),nt+"_b.mp4") - ptout=os.path.join(os.path.dirname(pout),nt+".mp4") - shutil.move(padd,ptadd) - if os.path.isfile(pout): - shutil.move(pout,ptoutb) - time.sleep(5) - cmdn=string.replace(cmd,padd,ptadd) - cmdn=string.replace(cmdn,u"-out \""+pout,u"-add \""+ptoutb+"\" -new \""+ptout) - cmdn=string.replace(cmdn,u"\""+pout,u"-add \""+ptoutb+"\" -new \""+ptout) - cmdn=string.replace(cmdn,pout,ptout) - recdblist.printutf8(cmdn) - txt="" - try: - txt=execcomd(cmdn) - except Exception, inst: - txt= "error occures in addmp4\n" - txt=txt+ str(type(inst))+"\n" - txt=txt+str(inst) - recdblist.addlog(pout, cmdn, u"MP4Box追加ログ-コマンド") - recdblist.addlog(pout, txt, u"MP4Box追加ログ-詳細") - time.sleep(5) - shutil.move(ptadd,padd) - if os.path.exists(ptout): - shutil.move(ptout,pout) - os.remove(ptoutb) - else: - txtt=padd+u"のインポートエラー" - recdblist.addlog(pout, txtt, u"MP4Box追加ログ-コマンド") - shutil.move(ptoutb,pout) - time.sleep(5) -def execcomd(cmd): - txt="" - try: - txt=u"Cmd : "+cmd+"\n" - txt2=commands.getoutput(cmd.encode('utf-8')) - txt=txt+unicode(txt2,"utf-8")+"\n" - except: - "" - return txt \ No newline at end of file +#!/usr/bin/python +# coding: UTF-8 +# Rec10 TS Recording Tools +# Copyright (C) 2009-2011 Yukikaze +import commands +import shutil +import auto_process +import os +import re +import os.path +import string +import base64 +import time +import subprocess +import traceback +import zip + +import tv2avi +import recdblist +import configreader +import status +import tv2audio +path = str(os.path.dirname(os.path.abspath(__file__))) + "/" +tmppath = configreader.getConfPath("tmp")+"/" +if tmppath=="/": + tmppath=path +if not os.path.exists(tmppath): + os.mkdir(tmppath) +def ts2mp4(pin, pout, opt): + dir=os.path.split(pout)[0] + title=os.path.split(pout)[1] + title=os.path.splitext(title)[0] + tpraw=os.path.join(dir, title+".264") + tpmp4=os.path.join(dir, title+".mp4") + if os.path.isfile(pin) and os.path.getsize(pin)>10*1000: + tv2avi.ts2raw(pin, tpraw, opt) + time.sleep(10) + if os.path.isfile(tpraw) and os.path.getsize(tpraw)>10*1000: + raw2mp4(tpraw, tpmp4, opt) + time.sleep(10) + if os.path.exists(tpraw) and not re.search("B",opt): + os.remove(tpraw) + zip.addFile2FileZip(recdblist.getLogTitle(pin)+".command.log", recdblist.getLogTitle(pin)+".log.zip") + if os.path.exists(recdblist.getLogTitle(pin)+".command.log"): + os.remove(recdblist.getLogTitle(pin)+".command.log") +def raw2mp4(pin,pout,opt): + dir=os.path.split(pout)[0] + title=os.path.split(pout)[1] + title=os.path.splitext(title)[0] + duration="-fps 29.970030 " + if re.search("a",opt): + duration="-fps 23.976023 " + if re.search("I",opt): + duration="-fps 29.970030 " + exe = configreader.getConfPath("mp4box")+u" -tmp "+tmppath + txt="" + os.environ['LANG']="ja_JP.UTF-8" + pints=pin.replace(".264",".ts") + e1=exe +u" "+duration+" -add \""+pin+"\" -new \""+pout+"\"" + execmp4box(pin, pout, e1) + addAudio(pints, pout, opt) + addCaption(pints, pout) + if status.getSettings_auto_del_tmp()==1: + if os.path.exists(pout): + if re.search("t",opt): + auto_process.deleteTmpFile(dir, title, ".264") + elif re.search("k",opt): + ""#削除しない + else: + auto_process.deleteTmpFile(dir, title, ".mp4") +def mkv2mp4(pin,pout): + exeb = configreader.getConfPath(u"mkvextract") + exe = configreader.getConfPath(u"mp4Box") + #dtsedit=configreader.getConfPath("DtsEdit") + wineexe=configreader.getConfPath("wine") + dir=os.path.split(pin)[0] + title=os.path.split(pin)[1] + title=os.path.splitext(title)[0] + etitle=base64.b16encode(title.encode('utf-8')) + audiopath=os.path.join(dir,etitle+u"_audio.aac") + videopath=os.path.join(dir,etitle+u"_video.264") + timecodepath=os.path.join(dir,etitle+u"_1_timecode.txt") + tmpmp4=os.path.join(dir,etitle+u".tmp.mp4") + exe0=exeb+u" tracks \'"+pin+u"\' 1:\'"+videopath+u"\' 2:\'"+audiopath+u"\'" + exe1=exeb+u" timecodes_v2 \'"+pin+"\' 1:\'"+timecodepath+"\'" + exe2=exe+u" -fps 29.970030 -add \'"+videopath+u"\' -add \'"+audiopath+u"\' -new \'"+tmpmp4+u"\'" + exe3=wineexe+u" "+dtsedit+u" -tc \'Z:\\"+timecodepath+u"\' \'Z:\\"+tmpmp4+u"\' -o \'Z:\\"+pout+u"\'" + os.environ['LANG']="ja_JP.UTF-8" + txt="" + try: + txt=txt+execcomd(exe0)+"\n" + txt=txt+execcomd(exe1)+"\n" + txt=txt+execcomd(exe2)+"\n" + txt=txt+execcomd(exe3)+"\n" + except: + "" + recdblist.addLog(pin, txt, u"MKV2MP4-log") + txt = "\n####MKV2MP4-log####\n"+txt + time.sleep(10) + if status.getSettings_auto_del_tmp()==1: + if os.path.exists(pout): + auto_process.deleteTmpFile(dir, title, ".mp4") +def addCaption(pts,pmp4):##字幕の追加を試みる。 + wineexe=configreader.getConfPath("wine") + pincap=pts.replace(".ts",".srt") + try: + cap2ass=configreader.getConfPath("caption2ass") + except: + cap2ass="" + if os.path.isfile(cap2ass): + e0=wineexe+u" "+cap2ass+u" -format srt \"Z:\\"+pts+"\" \"Z:\\"+pincap+"\"" + recdblist.printutf8(e0) + p0=subprocess.Popen(e0,shell=True,stdout=subprocess.PIPE) + time.sleep(100) + if p0.poll==None:#実行中 + #if os.path.getsize(pincap)<1000:#2mで1kb以下の場合自動で終了 + # os.kill(p0.pid,signal.SIGKILL) + #else: + os.waitpid(p0.pid, 0) + logt=unicode(p0.communicate()[0], "UTF-8") + recdblist.addLog(pts,e0, u"Captionログ-コマンド") + recdblist.addLog(pts,logt, u"Captionログ-詳細") + recdblist.addCommandLogZip(pts, "mp4box_caption", "mp4box_caption", e0, logt) + if os.path.exists(pincap): + if os.path.getsize(pincap)>1000: + exe = configreader.getConfPath("mp4box")+u" -tmp "+tmppath + e1s=exe +u" -add \""+pincap+"\" \""+pmp4+"\"" + addmp4(pincap,pmp4,e1s) +def addAudio(pts,pmp4,opts):#オプションに応じた音声の追加を行う + exe = configreader.getConfPath("mp4box")+u" -tmp "+tmppath + if re.search("d",opts) or re.search("5",opts):#二カ国語放送/5.1ch放送の場合 + paac1=pts.replace(".ts","_1.aac") + paac2=pts.replace(".ts","_2.aac") + recdblist.printutf8(paac1) + e1a1=exe +u" -add \""+paac1+"\":mpeg4 \""+pmp4+"\"" + e1a2=exe +u" -add \""+paac2+"\":mpeg4 \""+pmp4+"\"" + if not os.path.exists(paac1): + paac1=pts.replace(".ts","_1.mp3") + e1a1=exe +u" -add \""+paac1+"\" \""+pmp4+"\"" + if not os.path.exists(paac2): + paac2=pts.replace(".ts","_2.mp3") + e1a1=exe +u" -add \""+paac2+"\" \""+pmp4+"\"" + if os.path.exists(paac1): + addmp4(paac1, pmp4, e1a1) + if os.path.exists(paac2): + addmp4(paac2, pmp4, e1a2) + elif re.search("b",opts):#BonTsDemuxを使って音声をスプリットした場合 + paac=pts.replace(".ts",".aac") + e1a=exe +u" -add \""+pinaac+"\":mpeg4 \""+pmp4+"\"" + if not os.path.exists(paac): + paac=pts.replace(".ts",".mp3") + e1a1=exe +u" -add \""+paac+"\" \""+pmp4+"\"" + if os.path.exists(paac): + addmp4(paac, pmp4, e1a1) + else: + tv2audio.ts2single_audio(pts,opts) + pinaac=pts.replace(".ts",".aac") + e1a=exe +u" -add \""+pinaac+"\":mpeg4 \""+pmp4+"\"" + if not os.path.exists(pinaac): + pinaac=pinaac.replace(".aac",".mp3") + e1a=exe +u" -add \""+pinaac+"\" \""+pmp4+"\"" + if os.path.exists(pinaac): + addmp4(pinaac, pmp4, e1a) +def execmp4box(pin,pout,cmd): + title=os.path.splitext(os.path.split(pin)[1])[0] + nt=base64.b16encode(title.encode('utf-8')) + if len(nt)>200: + nt=nt[:180] + ptin=os.path.join(os.path.dirname(pin),nt+".264") + recdblist.printutf8(ptin) + shutil.move(pin,ptin) + time.sleep(10) + ptout=os.path.join(os.path.dirname(pout),nt+".mp4") + cmdn=string.replace(cmd,pin,ptin) + cmdn=string.replace(cmdn,pout,ptout) + recdblist.printutf8(cmdn) + recdblist.addCommandSelfLog(pin, cmdn) + txt="" + try: + txt=execcomd(cmdn) + except Exception, inst: + txt= "error occures in execmp4box\n" + txt=txt+ str(type(inst))+"\n" + txt=txt+str(inst) + recdblist.addCommonlogEX("Error", "excecmp4box(tv2mp4.py)", str(type(inst)), str(inst)+traceback.format_exc(),verbose_level=200,log_level=200) + recdblist.addLog(pin, cmdn, u"MP4Boxログ-コマンド") + recdblist.addLog(pin, txt, u"MP4Boxログ-詳細") + recdblist.addCommandLogZip(pin, "MP4Box", "mp4box", cmdn,txt) + time.sleep(5) + shutil.move(ptin,pin) + shutil.move(ptout,pout) + time.sleep(5) +def addmp4(padd,pout,cmd):#without video + title=os.path.splitext(os.path.split(padd)[1])[0] + ext=os.path.splitext(os.path.split(padd)[1])[1] + nt=base64.b16encode(title.encode('utf-8')) + if len(nt)>200: + nt=nt[:180] + ptadd=os.path.join(os.path.dirname(padd),nt+ext) + ptoutb=os.path.join(os.path.dirname(pout),nt+"_b.mp4") + ptout=os.path.join(os.path.dirname(pout),nt+".mp4") + shutil.move(padd,ptadd) + if os.path.isfile(pout): + shutil.move(pout,ptoutb) + time.sleep(5) + cmdn=string.replace(cmd,padd,ptadd) + cmdn=string.replace(cmdn,u"-out \""+pout,u"-add \""+ptoutb+"\" -new \""+ptout) + cmdn=string.replace(cmdn,u"\""+pout,u"-add \""+ptoutb+"\" -new \""+ptout) + cmdn=string.replace(cmdn,pout,ptout) + recdblist.printutf8(cmdn) + txt="" + try: + txt=execcomd(cmdn) + except Exception, inst: + txt= "error occures in addmp4\n" + txt=txt+ str(type(inst))+"\n" + txt=txt+str(inst) + recdblist.addLog(pout, cmdn, u"MP4Box追加ログ-コマンド") + recdblist.addLog(pout, txt, u"MP4Box追加ログ-詳細") + recdblist.addCommandLogZip(pout, "MP4Box_add", "mp4box_add", cmdn, txt) + time.sleep(5) + shutil.move(ptadd,padd) + if os.path.exists(ptout): + shutil.move(ptout,pout) + os.remove(ptoutb) + else: + txtt=padd+u"のインポートエラー" + recdblist.addLog(pout, txtt, u"MP4Box追加ログ-コマンド") + shutil.move(ptoutb,pout) + time.sleep(5) +def execcomd(cmd): + txt="" + try: + txt=u"Cmd : "+cmd+"\n" + txt2=commands.getoutput(cmd.encode('utf-8')) + txt=txt+unicode(txt2,"utf-8")+"\n" + except: + "" + return txt