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脚本在Linux下实现部分Bash Shell的教程
Apr 17 Python
在VS Code上搭建Python开发环境的方法
Apr 06 Python
Python针对给定列表中元素进行翻转操作的方法分析
Apr 27 Python
python字符串与url编码的转换实例
May 10 Python
Python3+django2.0+apache2+ubuntu14部署网站上线的方法
Jul 07 Python
Tornado实现多进程/多线程的HTTP服务详解
Jul 25 Python
Django REST Framework之频率限制的使用
Sep 29 Python
pygame实现打字游戏
Feb 19 Python
Python插入Elasticsearch操作方法解析
Jan 19 Python
python右对齐的实例方法
Jul 05 Python
Python xlwings插入Excel图片的实现方法
Feb 26 Python
尝试使用Python爬取城市租房信息
Apr 12 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-accelerator网站加速PHP缓冲的方法
2008/07/30 PHP
php中的Base62类(适用于数值转字符串)
2013/08/12 PHP
php eval函数一句话木马代码
2015/05/21 PHP
PHP测试成功的邮件发送案例
2015/10/26 PHP
Zend Framework教程之分发器Zend_Controller_Dispatcher用法详解
2016/03/07 PHP
Windows2003下php5.4安装配置教程(Apache2.4)
2016/06/30 PHP
关于laravel 数据库迁移中integer类型是无法指定长度的问题
2019/10/09 PHP
jquery中的$(document).ready()与window.onload的区别
2009/11/18 Javascript
一行代码实现纯数据json对象的深度克隆实现思路
2013/01/09 Javascript
DIV+CSS+JS不间断横向滚动实现代码
2013/03/19 Javascript
jquery js 重置表单 reset()具体实现代码
2013/08/05 Javascript
Jquery EasyUI中弹出确认对话框以及加载效果示例代码
2014/02/13 Javascript
jquery实现上下左右滑动的方法
2015/02/09 Javascript
javascript解决小数的加减乘除精度丢失的方案
2016/05/31 Javascript
jquery自定义插件结合baiduTemplate.js实现异步刷新(附源码)
2016/12/22 Javascript
JS正则获取HTML元素的方法
2017/03/31 Javascript
React Native预设占位placeholder的使用
2017/09/28 Javascript
vue仿element实现分页器效果
2018/09/13 Javascript
Vue中的vue-resource示例详解
2018/11/02 Javascript
利用d3.js实现蜂巢图表带动画效果
2019/09/03 Javascript
[04:38]完美世界携手游戏风云打造 卡尔工作室饰品系统篇
2013/04/25 DOTA
python实现随机森林random forest的原理及方法
2017/12/21 Python
Python模拟脉冲星伪信号频率实例代码
2018/01/03 Python
python 利用for循环 保存多个图像或者文件的实例
2018/11/09 Python
Pandas时间序列重采样(resample)方法中closed、label的作用详解
2019/12/10 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
2020/02/15 Python
Python+PyQt5+MySQL实现天气管理系统
2020/06/16 Python
scrapy处理python爬虫调度详解
2020/11/23 Python
python不同版本的_new_不同点总结
2020/12/09 Python
加拿大时尚床上用品零售商:QE Home | Quilts Etc
2018/01/22 全球购物
FORZIERI福喜利中国官网:奢侈品购物梦工厂
2019/05/03 全球购物
儿科主治医生个人求职信
2013/09/23 职场文书
物流专业求职信
2014/06/30 职场文书
2014年惩防体系建设工作总结
2014/12/01 职场文书
2015年仓库管理员工作总结
2015/04/21 职场文书
Jupyter notebook 不自动弹出网页的解决方案
2021/05/21 Python