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'#再显示一次命令
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。