python整合ffmpeg实现视频文件的批量转换


Posted in Python onMay 31, 2019

转换工具层出不穷,ffmpeg才是全能的转换工具,只是不支持图形操作。

没有关系,命令行方式,在freebsd/linux下直接来

我们的思路是,设定一个文件夹存放源视频文件,python读取该文件夹下的全部文件,并对文件通过ffmpeg进行分析,根据需要,修改目标文件的编码、分辨率等等,调用ffmpeg转换。

我这次的需求是,我家液晶电视只支持分辨来,长宽均小于720,编码只支持divx/xvid的avi文件,且fps只能小于25——多次实践,才总结出来的,电视说明书也没说!!

下面的程序将

/root//root2/video/origin

下存在的全部文件转换成液晶电视需要的avi格式电影

以下是最新的修改,引入了OptionParser  参数分析工具。能指定最大宽度,音视频编码,视频质量,原路径,目的路径,工作路径等

# coding=gb2312
import string
import os 
import time
import re
import sys
from optparse import OptionParser
 
parser = OptionParser()
#parser.add_option("-i", "--input", dest="input",action="store_true",help="input x y for each file by user")
parser.add_option("-q", "--quality", dest="q",action="store",help="input xvid q arg",default="24")
parser.add_option("-v", "--vcodec", dest="vcodec",action="store",help="input video codec",default="x264")
parser.add_option("-n", "--noaudio", dest="an",action="store_true",help="no audio")
parser.add_option("-p", "--preset", dest="preset",action="store",help="",default="")
parser.add_option("-m", "--maxWidth", dest="maxWidth",action="store",help="input max width for output video",default="")
parser.add_option("-f", "--fileType", dest="fileType",action="store",help="",default="mp4")
parser.add_option("-o", "--ogg", dest="ogg",action="store_true",help="user ogg instead of aac",default="")
parser.add_option("-3", "--mp3", dest="mp3",action="store_true",help="user mp3 instead of aac",default="")
parser.add_option("-1", "--pad", dest="pad",action="store_true",help="pad to 16:9",default="")
parser.add_option("-s", "--src", dest="srcD",action="store",help="source dir",default="/usr/disk2/root/video/origin")
parser.add_option("-t", "--target", dest="targetD",action="store",help="target dir",default="/usr/disk2/root/video/ok")
parser.add_option("-w", "--workdir", dest="workdir",action="store",help="work dir",default="/root/root2/video")
 
(options, args) = parser.parse_args()
 
if options.srcD==None or options.srcD[0:1]=='-':
 print 'srcD Err, quit'
 exit() 
if options.targetD==None or options.targetD[0:1]=='-':
 print 'targetD Err, quit'
 exit() 
if options.fileType==None or options.fileType[0:1]=='-':
 print 'fileType Err, quit'
 exit() 
if options.workdir==None or options.workdir[0:1]=='-':
 print 'workdir Err, quit'
 exit() 
 
#遍历origin下的文件
for root,dirs,files in os.walk(options.srcD): 
 for name in files:
 name= name.replace('[','''\[''')#对文件名中的[进行转义
 newname =name[0: name.rindex('.')] 
 
 #运行一次ffmpeg,获取分辨率
 (si, so, se) = os.popen3('cd '+options.workdir+';mkdir -p ffm; rm -f ffm/ffm.txt ; csh -c "(ffmpeg -i '+options.srcD+'/' +name+ ' >& ffm/ffm.txt)"; grep Stream ffm/ffm.txt') 
 t=so.readlines() 
 ti=0
 for line in se.readlines() :
  print line
  
 width=0
 height=0
 
 reg='''^\s*Stream.*,\s*(\d+)x(\d+)(?: \[SAR|,)'''
 #Stream #0.0: Video: RV40 / 0x30345652, 1020x572, 23 fps, 23 tbr, 23 tbn, 23 tbc
 for line in t:
  result = re.compile(reg).findall(line)
 
  for c in result:
  print name+' '+c[0] + 'x' + c[1]
  width=string.atoi(c[0])
  height=string.atoi(c[1])
  if name[0:3]=='M2U' and width==720 and height==576:#m2U开头的,宽度是720x576的,是4:3存储16:9的,将其转换为16:9
   width=1024 
   
 if width==0:
  print 'error parsing width and height'
  exit()
 
 vc=''
 qstr=''
 astr=''
 vpre='' 
 s=''
 
 if options.maxWidth!='':
  if width>string.atoi(options.maxWidth):
  height = height * string.atoi(options.maxWidth) / width
  width = string.atoi(options.maxWidth)
  
 padStr=''
 if options.pad==True:
  if height*16/9 - width>10:#宽度不够
  padStr=' -vf "pad='+str(height*16/9)+':'+str(height)+':'+str((height*16/9 - width)/2)+':0:black"'
  elif width - 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
 
 if options.preset!='':
  vpre=' -vpre '+options.preset
 
 if options.an==True:
  astr=' -an'
 elif options.ogg==True:
  astr=' -acodec libvorbis -ar 44100 -ab 64K'
 elif options.mp3==True:
  astr=' -acodec libmp3lame -ar 44100 -ab 64K'
 else:
  astr=' -acodec libfaac -ar 44100 -ab 64K'
  
 if options.vcodec=='vp8':
  vc='libvpx'
  qstr=" -qmin "+options.q+" -qmax "+options.q
 elif options.vcodec=='x264':
  vc='libx264'
  qstr=" -crf "+options.q
 elif options.vcodec=='xvid':
  vc='libxvid'
  qstr=" -qmin "+options.q+" -qmax "+options.q
  
 cmd ='csh -c "' + "cd "+options.workdir+";touch ffm/output.log;(ffmpeg -y -i "+options.srcD+"/"+name+astr+" -vcodec "+vc+vpre+qstr+s+" -r 25 -threads 8 "+options.targetD+"/"+newname+"."+options.fileType + ' >>& ffm/output.log)"'
 print cmd
 
 #运行
 (si, so, se) = os.popen3(cmd)
 for line in se.readlines() :#打印输出
  print line
 for line in so.readlines() :#打印输出
  print line
  
 #print cmd,'  finish'#再显示一次命令

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python深入学习之闭包
Aug 31 Python
Python中处理unchecked未捕获异常实例
Jan 17 Python
Python使用MYSQLDB实现从数据库中导出XML文件的方法
May 11 Python
深入解析Python的Tornado框架中内置的模板引擎
Jul 11 Python
详解python中 os._exit() 和 sys.exit(), exit(0)和exit(1) 的用法和区别
Jun 23 Python
python GUI实例学习
Nov 21 Python
python实现网站用户名密码自动登录功能
Aug 09 Python
python实现的汉诺塔算法示例
Oct 23 Python
Python打包模块wheel的使用方法与将python包发布到PyPI的方法详解
Feb 12 Python
使用Python发现隐藏的wifi
Mar 04 Python
jupyter notebook 添加kernel permission denied的操作
Apr 21 Python
keras topN显示,自编写代码案例
Jul 03 Python
python自动发邮件总结及实例说明【推荐】
May 31 #Python
python实现视频分帧效果
May 31 #Python
使用Python实现跳帧截取视频帧
May 31 #Python
python tools实现视频的每一帧提取并保存
Mar 20 #Python
Python从list类型、range()序列简单认识类(class)【可迭代】
May 31 #Python
实例详解python函数的对象、函数嵌套、名称空间和作用域
May 31 #Python
Python可变和不可变、类的私有属性实例分析
May 31 #Python
You might like
PHP连接SQLServer2005的实现方法(附ntwdblib.dll下载)
2012/07/02 PHP
Laravel框架使用技巧之使用url()全局函数返回前一个页面的地址方法详解
2020/04/06 PHP
Extjs学习笔记之八 继承和事件基础
2010/01/08 Javascript
javascript 使用 NodeList需要注意的问题
2013/03/04 Javascript
使用jQuery避免鼠标双击的解决方案
2013/08/21 Javascript
JavaScript按值删除数组元素的方法
2015/04/24 Javascript
AngularJS基础 ng-dblclick 指令用法
2016/08/01 Javascript
详解vue mint-ui源码解析之loadmore组件
2017/10/11 Javascript
不使用 JS 匿名函数理由
2017/11/17 Javascript
javaScript中"=="和"==="的区别详解
2018/03/16 Javascript
jQuery+PHP实现上传裁剪图片
2020/06/29 jQuery
nodejs提示:cross-device link not permitted, rename错误的解决方法
2019/06/10 NodeJs
vue.js中ref和$refs的使用及示例讲解
2019/08/14 Javascript
JS如何把字符串转换成json
2020/02/21 Javascript
[38:54]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第一场 11.28
2020/12/01 DOTA
python通过函数属性实现全局变量的方法
2015/05/16 Python
Django ForeignKey与数据库的FOREIGN KEY约束详解
2020/05/20 Python
Python pip install之SSL异常处理操作
2020/09/03 Python
HTML5中外部浏览器唤起微信分享功能的代码
2020/09/15 HTML / CSS
丝芙兰法国官网:SEPHORA法国
2016/09/01 全球购物
美国波西米亚风格服装品牌:Show Me Your Mumu
2018/01/05 全球购物
英国50岁以上人群的交友网站:Ourtime
2018/03/28 全球购物
俄罗斯香水和化妆品网上商店:NOTINO.ru
2019/12/17 全球购物
中专生毕业自我鉴定
2013/11/01 职场文书
机械制造与自动化应届生求职信
2013/11/16 职场文书
无工作经验者个人求职信范文
2013/12/22 职场文书
军训自我鉴定
2014/01/22 职场文书
计算机应届毕业生自荐信范文
2014/02/23 职场文书
2014年环卫工作总结
2014/11/22 职场文书
2014年幼儿园园长工作总结
2014/12/17 职场文书
共青团员自我评价
2015/03/10 职场文书
行政介绍信范文
2015/05/04 职场文书
不服劳动仲裁起诉书
2015/05/20 职场文书
高中升旗仪式主持词
2015/07/03 职场文书
Redis5之后版本的高可用集群搭建的实现
2021/04/27 Redis
Docker 镜像介绍以及commit相关操作
2022/04/13 Servers