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中用startswith()函数判断字符串开头的教程
Apr 07 Python
Python使用ntplib库同步校准当地时间的方法
Jul 02 Python
Scrapy爬虫实例讲解_校花网
Oct 23 Python
python实现隐马尔科夫模型HMM
Mar 25 Python
python3+PyQt5实现支持多线程的页面索引器应用程序
Apr 20 Python
对Python中列表和数组的赋值,浅拷贝和深拷贝的实例讲解
Jun 28 Python
对python3中, print横向输出的方法详解
Jan 28 Python
python实现计数排序与桶排序实例代码
Mar 28 Python
Python 脚本实现淘宝准点秒杀功能
Nov 13 Python
简单了解Python读取大文件代码实例
Dec 18 Python
Python定义函数实现累计求和操作
May 03 Python
python 判断文件或文件夹是否存在
Mar 18 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 代价太高
2016/04/26 PHP
PHP CURL与java http使用方法详解
2018/01/26 PHP
PJBlog插件 防刷新的在线播放器
2006/10/25 Javascript
javascript获取元素偏移量的方法有哪些
2014/06/24 Javascript
分享一则javascript 调试技巧
2015/01/02 Javascript
JavaScript让Textarea支持tab按键的方法
2015/06/26 Javascript
JS获取数组最大值、最小值及长度的方法
2015/11/24 Javascript
javascript iframe跨域详解
2016/10/26 Javascript
微信小程序技巧之show内容展示,上传文件编码问题
2017/01/23 Javascript
Vue-Router实现页面正在加载特效方法示例
2017/02/12 Javascript
bootstrap实现动态进度条效果
2017/03/08 Javascript
Node.js 8 中的重要新特性
2017/06/28 Javascript
npm全局模块卸载及默认安装目录修改方法
2018/05/15 Javascript
小程序自定义组件实现城市选择功能
2018/07/18 Javascript
vue-drag-chart 拖动/缩放图表组件的实例代码
2020/04/10 Javascript
js实现轮播图效果 纯js实现图片自动切换
2020/08/09 Javascript
elementUI同一页面展示多个Dialog的实现
2020/11/19 Javascript
[01:03]DOTA2新的征程 你的脚印值得踏上
2014/08/13 DOTA
python self,cls,decorator的理解
2009/07/13 Python
python实现电子词典
2020/04/23 Python
python生成日历实例解析
2014/08/21 Python
使用Django和Python创建Json response的方法
2018/03/26 Python
Python 内置函数进制转换的用法(十进制转二进制、八进制、十六进制)
2018/04/30 Python
Python定义二叉树及4种遍历方法实例详解
2018/07/05 Python
Python中的list与tuple集合区别解析
2019/10/12 Python
基于python爬取梨视频实现过程解析
2020/11/09 Python
Omio意大利:全欧洲低价大巴、火车和航班搜索和比价
2017/12/02 全球购物
Tory Burch德国官网:美国时尚生活品牌
2018/01/03 全球购物
Laura Geller官网:美国彩妆品牌
2018/12/29 全球购物
班主任新年寄语
2014/04/04 职场文书
体操比赛口号
2014/06/10 职场文书
校园游戏活动新闻稿
2014/10/15 职场文书
机关作风建设工作总结
2014/10/23 职场文书
教师工作决心书
2015/02/04 职场文书
2016大学生优秀志愿者事迹材料
2016/02/25 职场文书
JavaScript 与 TypeScript之间的联系
2021/11/27 Javascript