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中的并发编程实例
Jul 07 Python
将Django框架和遗留的Web应用集成的方法
Jul 24 Python
Python面向对象编程基础解析(二)
Oct 26 Python
Python3.4实现远程控制电脑开关机
Feb 22 Python
PyQt5+requests实现车票查询工具
Jan 21 Python
几个适合python初学者的简单小程序,看完受益匪浅!(推荐)
Apr 16 Python
解决Django生产环境无法加载静态文件问题的解决
Apr 23 Python
Python+threading模块对单个接口进行并发测试
Jun 25 Python
Django 反向生成url实例详解
Jul 30 Python
基于Python获取照片的GPS位置信息
Jan 20 Python
python实现批量转换图片为黑白
Jun 16 Python
Python 中的单分派泛函数你真的了解吗
Jun 22 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 eval函数一句话木马代码
2015/05/21 PHP
PHP后台微信支付和支付宝支付开发
2017/04/28 PHP
thinkPHP5框架实现基于ajax的分页功能示例
2018/06/12 PHP
Javascript 更新 JavaScript 数组的 uniq 方法
2008/01/23 Javascript
2010年最佳jQuery插件整理
2010/12/06 Javascript
仅IE9/10同时支持script元素的onload和onreadystatechange事件分析
2011/04/27 Javascript
js获取浏览器的可视区域尺寸的实现代码
2011/11/30 Javascript
Angularjs在初始化未完毕时出现闪烁问题的解决方法分析
2016/08/05 Javascript
原生js实现addclass,removeclass,toggleclasss实例
2016/11/24 Javascript
bootstrap的常用组件和栅格式布局详解
2017/05/02 Javascript
jquery append与appendTo方法比较
2017/05/24 jQuery
深入学习nodejs中的async模块的使用方法
2017/07/12 NodeJs
JavaScript 中定义函数用 var foo = function () {} 和 function foo()区别介绍
2018/03/01 Javascript
为jquery的ajax请求添加超时timeout时间的操作方法
2018/09/04 jQuery
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
三步搞定:Vue.js调用Android原生操作
2020/09/07 Javascript
python使用正则搜索字符串或文件中的浮点数代码实例
2014/07/11 Python
归纳整理Python中的控制流语句的知识点
2015/04/14 Python
K-means聚类算法介绍与利用python实现的代码示例
2017/11/13 Python
pandas数据处理基础之筛选指定行或者指定列的数据
2018/05/03 Python
详解Python 函数如何重载?
2019/04/23 Python
pybind11在Windows下的使用教程
2019/07/04 Python
Python导入模块包原理及相关注意事项
2020/03/25 Python
潘多拉珠宝英国官方网上商店:PANDORA英国
2018/06/12 全球购物
给酒店员工的表扬信
2014/01/11 职场文书
岳父生日宴会答谢词
2014/01/13 职场文书
干部下基层实施方案
2014/03/14 职场文书
社区清明节活动总结
2014/07/04 职场文书
岗位说明书标准范本
2014/07/30 职场文书
学生检讨书范文
2014/10/30 职场文书
财务会计岗位职责
2015/02/03 职场文书
2015年小学辅导员工作总结
2015/05/27 职场文书
基石观后感
2015/06/12 职场文书
申请吧主发表的感言
2015/08/03 职场文书
Spring Boot 启动、停止、重启、状态脚本
2021/06/26 Java/Android
为什么MySQL选择Repeatable Read作为默认隔离级别
2021/07/26 MySQL