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利用rsa库做公钥解密的方法教程
Dec 10 Python
Python 网络爬虫--关于简单的模拟登录实例讲解
Jun 01 Python
对python中的控制条件、循环和跳出详解
Jun 24 Python
python实现接口并发测试脚本
Jun 25 Python
Pytorch根据layers的name冻结训练方式
Jan 06 Python
在pytorch中实现只让指定变量向后传播梯度
Feb 29 Python
Python函数生成器原理及使用详解
Mar 12 Python
Python HTMLTestRunner可视化报告实现过程解析
Apr 10 Python
pip安装tensorflow的坑的解决
Apr 19 Python
python根据字典的键来删除元素的方法
Aug 16 Python
细说NumPy数组的四种乘法的使用
Dec 18 Python
Python Numpy库的超详细教程
Apr 06 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
BBS(php & mysql)完整版(一)
2006/10/09 PHP
php session 检测和注销
2009/03/16 PHP
PHP spl_autoload_register实现自动加载研究
2011/12/06 PHP
解析PHP中数组元素升序、降序以及重新排序的函数
2013/06/20 PHP
php实现用于验证所有类型的信用卡类
2015/03/24 PHP
简单的php+mysql聊天室实现方法(附源码)
2016/01/05 PHP
在Yii2中使用Pjax导致Yii2内联脚本载入失败的原因分析
2016/03/06 PHP
PHP编程求最大公约数与最小公倍数的方法示例
2017/05/29 PHP
深入学习微信网址链接解封的防封原理visit_type
2019/08/15 PHP
laravel-admin select框默认选中的方法
2019/10/03 PHP
windows系统php环境安装swoole具体步骤
2021/03/04 PHP
PNG背景在不同浏览器下的应用
2009/06/22 Javascript
关于Aptana Studio生成自动备份文件的解决办法
2009/12/23 Javascript
jquery插件如何使用 jQuery操作Cookie插件使用介绍
2012/12/15 Javascript
Jquery实现自定义tooltip示例代码
2014/02/12 Javascript
node.js中的fs.fstatSync方法使用说明
2014/12/15 Javascript
JS实现网页上随滚动条滚动的层效果代码
2015/11/04 Javascript
详解javascript中的事件处理
2015/11/06 Javascript
jquery自定义表单验证插件
2016/10/12 Javascript
js常用的继承--组合式继承
2017/03/06 Javascript
浅谈angularJS2中的界面跳转方法
2018/08/31 Javascript
jQuery实现数字华容道小游戏(实例代码)
2020/01/16 jQuery
Python random模块(获取随机数)常用方法和使用例子
2014/05/13 Python
在matplotlib的图中设置中文标签的方法
2018/12/13 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
Python利用WMI实现ping命令的例子
2019/08/14 Python
美国汽车交易网站:Edmunds
2016/08/17 全球购物
Parfume Klik丹麦:香水网上商店
2018/07/10 全球购物
相亲大会策划方案
2014/06/05 职场文书
人口与计划生育目标管理责任书
2014/07/29 职场文书
2014银行领导班子群众路线对照检查材料思想汇报
2014/09/17 职场文书
机关职员工作检讨书
2014/10/23 职场文书
就业意向书范本
2015/05/11 职场文书
优秀新员工事迹材料
2019/05/13 职场文书
浅谈Redis的事件驱动模型
2022/05/30 Redis
Vue3实现简易音乐播放器组件
2022/08/14 Vue.js