python整合ffmpeg实现视频文件的批量转换
转换工具层出不穷,ffmpeg才是全能的转换工具,只是不支持图形操作。
没有关系,命令行方式,在freebsd/linux下直接来
我们的思路是,设定一个文件夹存放源视频文件,python读取该文件夹下的全部文件,并对文件通过ffmpeg进行分析,根据需要,修改目标文件的编码、分辨率等等,调用ffmpeg转换。
我这次的需求是,我家液晶电视只支持分辨来,长宽均小于720,编码只支持divx/xvid的avi文件,且fps只能小于25——多次实践,才总结出来的,电视说明书也没说!!
下面的程序将
/root//root2/video/origin
下存在的全部文件转换成液晶电视需要的avi格式电影
以下是最新的修改,引入了OptionParser 参数分析工具。能指定最大宽度,音视频编码,视频质量,原路径,目的路径,工作路径等
#coding=gb2312 importstring importos importtime importre importsys fromoptparseimportOptionParser parser=OptionParser() #parser.add_option("-i","--input",dest="input",action="store_true",help="inputxyforeachfilebyuser") parser.add_option("-q","--quality",dest="q",action="store",help="inputxvidqarg",default="24") parser.add_option("-v","--vcodec",dest="vcodec",action="store",help="inputvideocodec",default="x264") parser.add_option("-n","--noaudio",dest="an",action="store_true",help="noaudio") parser.add_option("-p","--preset",dest="preset",action="store",help="",default="") parser.add_option("-m","--maxWidth",dest="maxWidth",action="store",help="inputmaxwidthforoutputvideo",default="") parser.add_option("-f","--fileType",dest="fileType",action="store",help="",default="mp4") parser.add_option("-o","--ogg",dest="ogg",action="store_true",help="userogginsteadofaac",default="") parser.add_option("-3","--mp3",dest="mp3",action="store_true",help="usermp3insteadofaac",default="") parser.add_option("-1","--pad",dest="pad",action="store_true",help="padto16:9",default="") parser.add_option("-s","--src",dest="srcD",action="store",help="sourcedir",default="/usr/disk2/root/video/origin") parser.add_option("-t","--target",dest="targetD",action="store",help="targetdir",default="/usr/disk2/root/video/ok") parser.add_option("-w","--workdir",dest="workdir",action="store",help="workdir",default="/root/root2/video") (options,args)=parser.parse_args() ifoptions.srcD==Noneoroptions.srcD[0:1]=='-': print'srcDErr,quit' exit() ifoptions.targetD==Noneoroptions.targetD[0:1]=='-': print'targetDErr,quit' exit() ifoptions.fileType==Noneoroptions.fileType[0:1]=='-': print'fileTypeErr,quit' exit() ifoptions.workdir==Noneoroptions.workdir[0:1]=='-': print'workdirErr,quit' exit() #遍历origin下的文件 forroot,dirs,filesinos.walk(options.srcD): fornameinfiles: name=name.replace('[','''\[''')#对文件名中的[进行转义 newname=name[0:name.rindex('.')] #运行一次ffmpeg,获取分辨率 (si,so,se)=os.popen3('cd'+options.workdir+';mkdir-pffm;rm-fffm/ffm.txt;csh-c"(ffmpeg-i'+options.srcD+'/'+name+'>&ffm/ffm.txt)";grepStreamffm/ffm.txt') t=so.readlines() ti=0 forlineinse.readlines(): printline width=0 height=0 reg='''^\s*Stream.*,\s*(\d+)x(\d+)(?:\[SAR|,)''' #Stream#0.0:Video:RV40/0x30345652,1020x572,23fps,23tbr,23tbn,23tbc forlineint: result=re.compile(reg).findall(line) forcinresult: printname+''+c[0]+'x'+c[1] width=string.atoi(c[0]) height=string.atoi(c[1]) ifname[0:3]=='M2U'andwidth==720andheight==576:#m2U开头的,宽度是720x576的,是4:3存储16:9的,将其转换为16:9 width=1024 ifwidth==0: print'errorparsingwidthandheight' exit() vc='' qstr='' astr='' vpre='' s='' ifoptions.maxWidth!='': ifwidth>string.atoi(options.maxWidth): height=height*string.atoi(options.maxWidth)/width width=string.atoi(options.maxWidth) padStr='' ifoptions.pad==True: ifheight*16/9-width>10:#宽度不够 padStr='-vf"pad='+str(height*16/9)+':'+str(height)+':'+str((height*16/9-width)/2)+':0:black"' elifwidth-height*16/9>10:#高度不够 padStr='-vf"pad='+str(width)+':'+str(width*9/16)+':0:'+str((width-height*16/9)/2)+':black"' s='-s'+str(width)+'x'+str(height)+padStr print'adjust',s ifoptions.preset!='': vpre='-vpre'+options.preset ifoptions.an==True: astr='-an' elifoptions.ogg==True: astr='-acodeclibvorbis-ar44100-ab64K' elifoptions.mp3==True: astr='-acodeclibmp3lame-ar44100-ab64K' else: astr='-acodeclibfaac-ar44100-ab64K' ifoptions.vcodec=='vp8': vc='libvpx' qstr="-qmin"+options.q+"-qmax"+options.q elifoptions.vcodec=='x264': vc='libx264' qstr="-crf"+options.q elifoptions.vcodec=='xvid': vc='libxvid' qstr="-qmin"+options.q+"-qmax"+options.q cmd='csh-c"'+"cd"+options.workdir+";touchffm/output.log;(ffmpeg-y-i"+options.srcD+"/"+name+astr+"-vcodec"+vc+vpre+qstr+s+"-r25-threads8"+options.targetD+"/"+newname+"."+options.fileType+'>>&ffm/output.log)"' printcmd #运行 (si,so,se)=os.popen3(cmd) forlineinse.readlines():#打印输出 printline forlineinso.readlines():#打印输出 printline #printcmd,'finish'#再显示一次命令
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。