FFmpeg命令行工具ffmpeg
简介####
FFmpeg是处理音视频的一个强大、跨平台的自由软件(可以理解为开源软件的一种,关于自由软件的定义,可以参考维基百科),很多音视频软件是基于它开发的,例如射手播放器,暴风影音,QQ影音,格式工厂等。
在FFmpeg的官网上,可以看到FFmpeg内部的库包含以下这些
其中libavcodec和libavformat是很重要的两个库,涉及到音视频的编码解码、从容器中读取和写入多媒体流等,涉及的一些概念可参考下面的基本概念部分
在FFmpeg的官网上,还可以看到FFmpeg的tools分为以下部分
屏幕快照 2017-06-16 下午4.50.48.png
本篇文章用到第一个工具,围绕命令行使用FFmpeg展开
安装####
最简单的方式
1.如果你的mac上安装Homebrew了,请直接跳到下一步;如果没有,可以在终端使用ruby安装Homebrew:
$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
2.使用Homebrew安装ffmpeg:在终端键入brew install ffmpeg,安装完成后键入ffmpeg -version查看是否安装成功,如果安装成功会有ffmpeg的版本信息
基本概念####
ffmpeg的流程如下所示
屏幕快照 2017-06-16 下午4.27.30.png
其中可能还涉及filter的处理,filter的处理处于decoded frames 到
encoded data packets之间,如果只是做stream copy处理,decode和encode的步骤不被需要
官网上对这一系列的流程作如下解释:
ffmpeg calls the libavformat library (containing demuxers) to read input files and get packets containing encoded data from them. When there are multiple input files, ffmpeg tries to keep them synchronized by tracking lowest timestamp on any active input stream.Encoded packets are then passed to the decoder (unless streamcopy is selected for the stream, see further for a description). The decoder produces uncompressed frames (raw video/PCM audio/...) which can be processed further by filtering (see next section). After filtering, the frames are passed to the encoder, which encodes them and outputs encoded packets. Finally those are passed to the muxer, which writes the encoded packets to the output file.
简单来讲,先用demuxer从容器读取多媒体流,读到的这些数据是编码压缩过的,所以需要用decoder去解压得到未压缩的数据,然后可能会用filters进行效果加工处理(也可能不需要)接着将处理好的数据用encoder编码压缩,最后用muxer写入容器中。如果只是copy处理,那么应该保留第一个步骤和最后一个步骤。
以上涉及几个概念:
1.encoder和decoder
编码器和解码器,都是codec,而所谓的编码(encode)解码(decode)就是压缩和解压缩,不同的编码标准的压缩率和压缩后的质量不同,光是视频的编码标准就有很多,维基百科上列出以下几种:
2.muxer和demuxer
muxer allows writing multimedia streams to a particular type of file;demuxer can read the multimedia streams from a particular type of file.简单来说就是从容器中读取多媒体流和将多媒体流写入容器中
3.filter
即过滤器,用于在被编码到输出文件之前修改输入文件内容,如:视频翻转,旋转,缩放等。
除此以外还有一些重要的概念:
4.container(容器)
容器对应多媒体的封装格式,不同的文件格式扩展名(后缀)不同,例如.flv,.avi等,容器的作用就是将不同的多媒体数据流(多条音频流、视频流、字幕流)联合起来加载到同一个文件中,使这些流同步
5.流式技术:实现整个文件被传输完成前显示多媒体数据,例如视频流可以实现边传输边播放
命令####
1.命令格式#####
ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...
2.全局命令(辅助信息)#####
列出demuxer aa的具体信息:ffmpeg -h demuxer=aa
列出可用的demuxers:ffmpeg -demuxers
也使用-muxers、-filters、-encoders等等
3.音视频处理的常用命令#####
ffmpeg -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:137 libvorbis OUTPUT
其中-i标识后面是输入文件(有多少个输入文件就有多少个-i),-c表示encode或者decode,如果用在输入文件前面就是decode,用在输入文件后面且在输出文件前面就是encode,-c copy表示所有的流(包括音频流、视频流、字幕流等等)都从输入文件复制到输出文件,后面的 -c:v:1 libx264表示视频流类别的第二个流用libx264(encoder的一种)进行编码压缩,-c:a:137 libvorbis表示音频流类别的第138个流用libvorbis(encoder的一种)进行编码压缩,-map用于指定输出文件的流的映射关系,-map 0表示将第一个输入文件的流写入输出文件(-map 1:0 表示将第二个输入文件的第一个流写入输出文件,如果文件index之前加“-”表示不选,例如ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT表示除第一个文件的第二个音频流以外所有的流都进OUPUT)
可以指定输出文件的大小
ffmpeg -i INPUT -c copy -fs 10000000 OUTPUT
上面指定输出文件为10,000,000bytes,实际上的输出文件大小会比10,000,000bytes多一点点
可以指定输出文件的FPS(帧率)和分辨率(指视频的横纵比)
ffmpeg -i INPUT -r 15 OUTPUT
ffmpeg -i INPUT -aspect 4:3 OUTPUT
可以指定音频的声道数目
ffmpeg -i INPUT -ac 1 OUTPUT(指定输出文件为单声道)
可以将视频截为一张张图片
ffmpeg -i INPUT -r 1 -s WxH -f image2 FILE-%03d.jpeg
-f表示格式,-r 1表示每一秒截1帧,-s WxH表示帧的大小为WxH(单位是像素),FILE-%03d.jpeg表示存储的图片命令为FILE-0001.jpeg、FILE-0002.jpeg、FILE-0003.jpeg等
也可以将一系列图片转为一个视频
ffmpeg -f image2 -framerate 12 -i foo-%03d.jpeg -s WxH foo.avi
-f表示格式,-framerate 12与-r 12类似,表示视频的帧率为12,foo-%03d.jpeg见上条命令解释,-s WxH指定视频的大小,如1280720
也可以将输入的图片集指定为通配符形式,不过要添加-pattern_type glob ,例如
ffmpeg -f image2 -pattern_type glob -framerate 12 -i 'foo-.jpeg' -s WxH foo.avi
4.ffmpeg的简写#####
表示video size时######
hd720表示视频屏幕分辨率为1280x720
hd1080表示视频屏幕分辨率为1920x1080
ntsc表示视频屏幕分辨率为720x480
表示video rate时######
pal表示帧率25/1
ntsc表示帧率30000/1001
film表示帧率24/1
表示color时######
Silver :0xC0C0C0
Tomato:0xFF6347
channel layout######
声道布局是指在多声道的音频流中声道的空间布局
单独的声道:
‘FL’
front left
‘FR’
front right
‘FC’
front center
标准的声道布局组合:
‘mono’
FC
‘stereo’
FL+FR
5.codec的选项#####
这部分在上面的命令中或多或少用到
b integer (encoding,audio,video)
Set bitrate in bits/s. Default value is 200K.
ab integer (encoding,audio)
Set audio bitrate (in bits/s). Default value is 128K.
g integer (encoding,video)
Set the group of picture (GOP) size. Default value is 12.
ar integer (decoding/encoding,audio)
Set audio sampling rate (in Hz).
ac integer (decoding/encoding,audio)
Set number of audio channels.
aspect rational number (encoding,video)
Set sample aspect ratio.
6.filter#####
过滤器用于对未压缩的音视频进行处理,例如翻转、缩放视频等
filter可以组成filterchain,再由filterchain组成filtergraph,一条filterchain中的filters用逗号分离,而filterchains之间用分号分离
一个简单的filter一般有一个输入和流类型相同的输出(复杂的filter可有多个输入或者输出,类型也没有要求一致),如果一个filter没有输入端则称为source,没有filter则称为sink
再来看看filter的语法:
[in_link_1]...[in_link_N]filter_name@id=arguments[out_link_1]...[out_link_M]
in_link或者out_link或者@id或者=arguments都是可选的
filter_name是过滤器类的名字,声明的过滤器正是这个类的实例,而且
这个过滤器类是在程序(@id标识)中注册的所有过滤器类中的一个。
后面的arguments包含用于初始化这个过滤器实例的一些参数,它有两种形式
第一种:key = value对的':'分隔列表。
第二种:一个':'分隔的值列表。在这种情况下,按照它们被声明的顺序,键被认为是选项名称。例如,fade过滤器以此顺序声明三个选项 -类型, start_frame 和 nb_frames。然后参数列表中:0:30表示该值 在分配给选择类型,0到 start_frame和30到nb_frames。
当然也可是是前两种的混合。这种情况下第二种(也称为direct value)必须位于第一种(也称为键值对)之前
fiter_name前面的一系列可选项是对应的输入端,后面一系列可选项(arguments之后)是对应的输出端
看下面这个例子:
nullsrc, split[L1], [L2]overlay, nullsink
其中split有两个输出端,overlay有两个输入端,split的第一个输出端是L1([]扩住标识符),第二个没有标识,而overlay中的第一个输入端是L2,而第二个输入端没有标识,使用filter有一条原则,如果一个fiter没有标识输出端,那么这个输出端对应下一个fiter的第一个未标识的输入端。如果第一个fiter没有标识输入端,则默认用“in"标识,如果最后一个fiter没有标识输出端,则默认用"out"标识