什么是ffmpeg
1.1 简介
FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。
FFmpeg提供了强大的命令行工具,非常方便用户使用以及二次开发。
官方网站:http://ffmpeg.org/
1.2 组件
FFmpeg项目由以下几部分组成:
1.FFmpeg视频文件转换命令行工具,也支持经过实时电视卡抓取和编码成视频文件;
2.ffserver基于HTTP、RTSP用于实时广播的多媒体服务器.也支持时间平移;
3.ffplay用 SDL和FFmpeg库开发的一个简单的媒体播放器;
4.libavcodec一个包含了所有FFmpeg音视频编解码器的库。为了保证最优性能和高可复用性,大多数编解码器从头开发的;
5.libavformat一个包含了所有的普通音视格式的解析器和产生器的库。
安装
下载免编译版本:xxxx-static.tar.gz 版本中包含static是免编译版本,
免编译版本下载地址:https://johnvansickle.com/ffmpeg/
安装步骤如下:
1 $ cd /home/john 2 $ wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-64bit-static.tar.xz 3 $ wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-64bit-static.tar.xz.md5 4 $ md5sum -c ffmpeg-git-64bit-static.tar.xz.md5 5 ffmpeg-git-64bit-static.tar.xz: OK 6 $ xz -d ffmpeg-git-64bit-static.tar.xz 7 $ tar -cvf ffmpeg-git-64bit-static.tar 8 $ ls ffmpeg-git-20180203-64bit-static 9 ffmpeg ffmpeg-10bit ffprobe GPLv3.txt manpages model qt-faststart readme.txt 10 $ pwd 11 /home/john 12 13 $ ./ffmpeg-git-20180203-64bit-static/ffmpeg 14 ffmpeg version N-89948-ge3d946b3f4-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2018 the FFmpeg developers 15 built with gcc 6.4.0 (Debian 6.4.0-11) 20171206 16 (snipped output to save space)
常用的集合选项
–y表示覆盖输出文件; –i表示输入文件; -t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持 -ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持
其他更加详细以及高级用法参考
https://wuyuans.com/2011/11/ffmpeg-syntax
剪切视频
./ffmpeg -ss 00:00:06 -t 00:00:12 -i input.mp4 -vcodec copy -acodec copy output.mp4
批量处理视频
由于视频很大,我想切割成一个一个小的视频文件保存起来
脚本如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/local/src/Python-2.7.15/python 2 import string 3 4 import os 5 import time 6 import re 7 import math 8 import sys 9 from optparse import OptionParser 10 11 print "Test by zzz start..." 12 parser = OptionParser() 13 parser.add_option("-i", "--input", dest="input",action="store_true",help="input x y for each file by user") 14 parser.add_option("-q", "--quality", dest="q",action="store",help="input xvid q arg",default="24") 15 parser.add_option("-v", "--vcodec", dest="vcodec",action="store",help="input video codec",default="x264") 16 parser.add_option("-n", "--noaudio", dest="an",action="store_true",help="no audio") 17 parser.add_option("-p", "--preset", dest="preset",action="store",help="",default="") 18 parser.add_option("-m", "--maxWidth", dest="maxWidth",action="store",help="input max width for output video",default="") 19 parser.add_option("-f", "--fileType", dest="fileType",action="store",help="",default="mp4") 20 parser.add_option("-o", "--ogg", dest="ogg",action="store_true",help="user ogg instead of aac",default="") 21 parser.add_option("-3", "--mp3", dest="mp3",action="store_true",help="user mp3 instead of aac",default="") 22 parser.add_option("-1", "--pad", dest="pad",action="store_true",help="pad to 16:9",default="") 23 parser.add_option("-s", "--src", dest="srcD",action="store",help="source dir",default="/usr/local/src/test/videoin") 24 parser.add_option("-t", "--target", dest="targetD",action="store",help="target dir",default="/usr/local/src/test/videoout") 25 parser.add_option("-w", "--workdir", dest="workdir",action="store",help="work dir",default="/usr/local/src/test/video") 26 parser.add_option("-e", "--split", dest="split",action="store_true",help="split to multiple file with size") 27 parser.add_option("-d", "--splitsize", dest="splitsize",action="store",help="split to multiple file with size",default="2")#Minutes 28 parser.add_option("-j", "--prefix", dest="prefix",action="store",help="target file name prefix",default="") 29 30 (options, args) = parser.parse_args() 31 32 if options.srcD==None or options.srcD[0:1]=='-': 33 print 'srcD Err, quit' 34 exit() 35 if options.targetD==None or options.targetD[0:1]=='-': 36 print 'targetD Err, quit' 37 exit() 38 if options.fileType==None or options.fileType[0:1]=='-': 39 print 'fileType Err, quit' 40 exit() 41 if options.workdir==None or options.workdir[0:1]=='-': 42 print 'workdir Err, quit' 43 exit() 44 45 #获取视频文件的名字 46 for root,dirs,files in os.walk(options.srcD): 47 for name in files: 48 name= name.replace('[','''[''')#??????[???? 49 newname =name[0: name.rindex('.')] 50 print "Test newname: " + newname 51 print "Test name: " + name 52 53 54 55 #?? 56 cmd ='cd '+options.workdir+';mkdir -p ffm; rm -f ffm/ffm.txt ; sh -c "(/usr/local/src/ffmpeg-git-20181015-64bit-static/ffmpeg -i '+options.srcD+'/' +name+ ' >& ffm/ffm.txt)"; grep Duration ffm/ffm.txt' 57 #ffmpeg -i xxx.mp4 能够得到视频文件的时间信息 58 print cmd 59 (si, so, se) = os.popen3(cmd) 60 t=so.readlines() ##[' Duration: 00:26:52.92, start: 0.000000, bitrate: 248 kb/s '] 61 print t 62 reg='''Duration:s(d+):(d+):([d.]+)''' 63 duration=0#second 64 for line in t: 65 result = re.compile(reg).findall(line)##result=[('00', '26', '52.92')] 66 for c in result: 67 print 'split file to',options.splitsize,'minutes, Duration:',c[0],c[1],c[2] 68 duration = int(c[0])*3600 + int(c[1])*60+float(c[2])##获取视频全部时间s 69 nameLength=int(math.log(int(duration / (int(options.splitsize)*60)) )/math.log(10)) + 1 70 print nameLength 71 for i in range(int(duration / (int(options.splitsize)*60)) + 1):##获取总计能够截取几份 72 print i 73 _t = '' 74 if duration>int(options.splitsize)*60*(i+1): ##当总时间数大于截取时间数时的取值 75 _t = str(int(options.splitsize)*60) 76 else: 77 _t = str(duration-int(options.splitsize)*60*i) 78 ##当总时间数小于截取时间数时的取值也就是最后一段视频 79 cmd ='sh -c "' + "cd "+options.workdir+";touch ffm/output.log;(/usr/local/src/ffmpeg-git-20181015-64bit-static/ffmpeg -y -i "+options.srcD+"/"+name+" -codec: copy -ss "+str(i*int(options.splitsize)*60)+" -t "+_t+" "+options.targetD+"/"+options.prefix+newname+'_'+string.replace(('%'+str(nameLength)+'s')%str(i),' ','0')+"."+options.fileType + ' >& ffm/output.log)"' 80 print cmd 81 (si, so, se) = os.popen3(cmd) 82 for line in se.readlines() :#???? 83 print line
最后截取视频如下,每个视频两分钟:
[root@localhost videoout]# ls -l total 47620 -rw-r--r--. 1 root root 6626325 Oct 27 16:11 02_xxx.ev4_00.mp4 -rw-r--r--. 1 root root 2551943 Oct 27 16:11 02_xxx.ev4_01.mp4 -rw-r--r--. 1 root root 3904819 Oct 27 16:11 02_xxx.ev4_02.mp4 -rw-r--r--. 1 root root 3380509 Oct 27 16:11 02_xxx.ev4_03.mp4 -rw-r--r--. 1 root root 3223771 Oct 27 16:11 02_xxx.ev4_04.mp4 -rw-r--r--. 1 root root 3004679 Oct 27 16:11 02_xxx.ev4_05.mp4 -rw-r--r--. 1 root root 3550070 Oct 27 16:11 02_xxx.ev4_06.mp4 -rw-r--r--. 1 root root 3362422 Oct 27 16:11 02_xxx.ev4_07.mp4 -rw-r--r--. 1 root root 3365144 Oct 27 16:11 02_xxx.ev4_08.mp4 -rw-r--r--. 1 root root 3301078 Oct 27 16:11 02_xxx.ev4_09.mp4 -rw-r--r--. 1 root root 3485420 Oct 27 16:11 02_xxx.ev4_10.mp4 -rw-r--r--. 1 root root 3468156 Oct 27 16:11 02_xxx.ev4_11.mp4 -rw-r--r--. 1 root root 3588643 Oct 27 16:11 02_xxx.ev4_12.mp4 -rw-r--r--. 1 root root 1922392 Oct 27 16:11 02_xxx.ev4_13.mp4
常见的一些问题:
-ss 放在-i前后的问题
https://wuyuans.com/2012/04/ffmpeg-split
一些其他用法:
参考:http://blog.51cto.com/yuanhuan/1246370
https://www.jianshu.com/p/2975f4efd808
补充,由于py2.7以及py3以上popen已经废弃,使用subprocess来替代,这里改写了下脚本
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #!/usr/local/src/Python-2.7.15/python 2 import string 3 4 import os 5 import time 6 import re 7 import math 8 import sys 9 from optparse import OptionParser 10 import subprocess 11 print "Test by gongjia start..." 12 13 14 parser = OptionParser() 15 parser.add_option("-i", "--input", dest="input",action="store_true",help="input x y for each file by user") 16 parser.add_option("-q", "--quality", dest="q",action="store",help="input xvid q arg",default="24") 17 parser.add_option("-v", "--vcodec", dest="vcodec",action="store",help="input video codec",default="x264") 18 parser.add_option("-n", "--noaudio", dest="an",action="store_true",help="no audio") 19 parser.add_option("-p", "--preset", dest="preset",action="store",help="",default="") 20 parser.add_option("-m", "--maxWidth", dest="maxWidth",action="store",help="input max width for output video",default="") 21 parser.add_option("-f", "--fileType", dest="fileType",action="store",help="",default="mp4") 22 parser.add_option("-o", "--ogg", dest="ogg",action="store_true",help="user ogg instead of aac",default="") 23 parser.add_option("-3", "--mp3", dest="mp3",action="store_true",help="user mp3 instead of aac",default="") 24 parser.add_option("-1", "--pad", dest="pad",action="store_true",help="pad to 16:9",default="") 25 parser.add_option("-s", "--src", dest="srcD",action="store",help="source dir",default="/usr/local/src/test/videoin") 26 parser.add_option("-t", "--target", dest="targetD",action="store",help="target dir",default="/usr/local/src/test/videoout") 27 parser.add_option("-w", "--workdir", dest="workdir",action="store",help="work dir",default="/usr/local/src/test/video") 28 parser.add_option("-e", "--split", dest="split",action="store_true",help="split to multiple file with size") 29 parser.add_option("-d", "--splitsize", dest="splitsize",action="store",help="split to multiple file with size",default="2")#Minutes 30 parser.add_option("-j", "--prefix", dest="prefix",action="store",help="target file name prefix",default="") 31 32 (options, args) = parser.parse_args() 33 34 if options.srcD==None or options.srcD[0:1]=='-': 35 print 'srcD Err, quit' 36 exit() 37 if options.targetD==None or options.targetD[0:1]=='-': 38 print 'targetD Err, quit' 39 exit() 40 if options.fileType==None or options.fileType[0:1]=='-': 41 print 'fileType Err, quit' 42 exit() 43 if options.workdir==None or options.workdir[0:1]=='-': 44 print 'workdir Err, quit' 45 exit() 46 47 #??videoin???? 48 for root,dirs,files in os.walk(options.srcD): 49 for name in files: 50 name= name.replace('[','''[''')#??????[???? 51 newname =name[0: name.rindex('.')] 52 print "Test newname: " + newname 53 print "Test name: " + name 54 os.chdir(options.workdir) 55 cmd ='mkdir -p ffm;rm -f ffm/ffm.txt;/usr/local/src/ffmpeg-git-20181015-64bit-static/ffmpeg -i '+options.srcD+'/' +name+ ' >& ffm/ffm.txt;pwd' 56 cmd1=['grep','Duration','ffm/ffm.txt'] 57 for i in cmd.split(';'): 58 print i 59 time.sleep(3) 60 t1=subprocess.Popen(i,shell=True) 61 obj=subprocess.Popen(cmd1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 62 (s1,s2)=obj.communicate() 63 print s1 64 reg='''Duration:s(d+):(d+):([d.]+)''' 65 result = re.compile(reg).findall(s1) 66 print result 67 for c in result: 68 print 'split file to',options.splitsize,'minutes, Duration:',c[0],c[1],c[2] 69 duration = int(c[0])*3600 + int(c[1])*60+float(c[2])##????????s 70 nameLength=int(math.log(int(duration / (int(options.splitsize)*60)) )/math.log(10)) + 1 71 print nameLength 72 for i in range(int(duration / (int(options.splitsize)*60)) + 1):##?????????? 73 print i 74 if duration>int(options.splitsize)*60*(i+1): 75 _t = str(int(options.splitsize)*60) 76 else: 77 _t = str(duration-int(options.splitsize)*60*i) 78 os.chdir(options.workdir) 79 cmd = "touch ffm/output.log;/usr/local/src/ffmpeg-git-20181015-64bit-static/ffmpeg -y -i "+options.srcD+"/"+name+" -codec: copy -ss "+str(i*int(options.splitsize)*60)+" -t "+_t+" "+options.targetD+"/"+options.prefix+newname+'_'+string.replace(('%'+str(nameLength)+'s')%str(i),' ','0')+"."+options.fileType + ' >& ffm/output.log' 80 for i in cmd.split(';'): 81 print i 82 time.sleep(2) 83 t1=subprocess.Popen(i,shell=True) 84 print t1 85 86 time.sleep(3)