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的Treq on Twisted来进行HTTP压力测试
Apr 16 Python
Python元组及文件核心对象类型详解
Feb 11 Python
Python 中导入csv数据的三种方法
Nov 01 Python
django的ORM模型的实现原理
Mar 04 Python
python try 异常处理(史上最全)
Mar 07 Python
Python获取一个用户名的组ID过程解析
Sep 03 Python
Jupyter Notebook 实现正常显示中文和负号
Apr 24 Python
Python JSON常用编解码方法代码实例
Sep 05 Python
Python中return函数返回值实例用法
Nov 19 Python
selenium框架中driver.close()和driver.quit()关闭浏览器
Dec 08 Python
python中温度单位转换的实例方法
Dec 27 Python
python-jwt用户认证食用教学的实现方法
Jan 19 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的ob_start() 控制您的浏览器cache
2009/08/03 PHP
php跨域cookie共享使用方法
2014/02/20 PHP
ThinkPHP基于PHPExcel导入Excel文件的方法
2014/10/15 PHP
Thinkphp 空操作、空控制器、命名空间(详解)
2017/05/05 PHP
解析 thinkphp 框架中的部分方法
2017/05/07 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
自定义一个jquery插件[鼠标悬浮时候 出现说明label]
2011/06/27 Javascript
深入理解JavaScript系列(3) 全面解析Module模式
2012/01/15 Javascript
web的各种前端打印方法之jquery打印插件jqprint实现网页打印
2013/01/09 Javascript
Jquery中使用setInterval和setTimeout的方法
2013/04/08 Javascript
javascript时间函数大全
2014/06/30 Javascript
js/jquery判断浏览器的方法小结
2014/09/02 Javascript
JQuery实现防止退格键返回的方法
2015/02/12 Javascript
Ajax中解析Json的两种方法对比分析
2015/06/25 Javascript
jQuery+正则+文本框只能输入数字的实现方法
2016/10/07 Javascript
webpack4 + react 搭建多页面应用示例
2018/08/03 Javascript
Vue父组件向子组件传值以及data和props的区别详解
2020/03/02 Javascript
基于canvas实现手写签名(vue)
2020/05/21 Javascript
JavaScript中展开运算符及应用的实例代码
2021/01/14 Javascript
[01:52]2014DOTA2西雅图邀请赛 V社开大会你不知道的小秘密
2014/07/08 DOTA
Python通过90行代码搭建一个音乐搜索工具
2015/07/29 Python
pandas 条件搜索返回列表的方法
2018/10/30 Python
使用Python获取网段IP个数以及地址清单的方法
2018/11/01 Python
python基础梳理(一)(推荐)
2019/04/06 Python
python3中的eval和exec的区别与联系
2019/10/10 Python
通过实例学习Python Excel操作
2020/01/06 Python
Django 自定义404 500等错误页面的实现
2020/03/08 Python
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
.NET方向面试题
2014/11/20 面试题
地质工程专业毕业生求职信
2014/08/08 职场文书
校园主题婚礼活动策划方案
2014/09/15 职场文书
个人贷款收入证明
2014/10/26 职场文书
PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
2021/04/16 PHP
html5实现点击弹出图片功能
2021/07/16 HTML / CSS
Win11安全功能升级:内置防网络钓鱼功能
2022/04/08 数码科技
JS setTimeout与setInterval的区别
2022/04/20 Javascript