FFmpeg既是一款音视频编解码工具,同时也是一组音视频编解码开发套件,作为编解码开发套件,它为开发者提供了丰富的音视频处理的调用接口。
FFmpeg提供了多种媒体格式的封装和解封装,包括多种音视频编码、多种协议的流媒体、多种色彩格式转换、多种采样率转换、多种码率转换等;FFmpeg框架提供了多种丰富的插件模块,包含封装与解封装的插件、编码与解码的插件等。
FFmpeg中的“FF”指的是“FastForward”(快进),曾经有人写信给FFmpeg的项目负责人,询问“FF”是不是代表“FastFreec”或者“FastFourier”的意思。FFmpeg中的“mpeg则是人们通常理解的Moving Picture Experts Group(动态图像专家组),FFmpeg是一个很全面的图像处理套件。其实从2000年发展至今,FFmpeg中的“FF”已经可以用各种组合进行理解,因为FFmpeg的强大足以支撑这些意义。
AVFormat中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装
FFmpeg基本组成模块MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。
FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库。根据实际需求,可进行煤体封装格式的扩展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。
AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,既支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x265编码器:MP3(mp3lame)编码,需要使用libmp3lame编码器。如果
AVFilter库提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。
swscale模块提供了高级别的图像转换API,例如它允许进行图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p等的缩放,或者将图像数据从YUV420P转换成YUYV,或者YUV转RGB等图像格式转换。
swresample模块提供了高级别的音频重采样API。例如它允许操作音频采样、音频通道布局转换与布局调整。
fmpeg是FFmpeg源代码编译后生成的一个可执行程序,其可以作为命令行工具使用。
fmpeg的主要工作流程相对比较简单,具体如下。
1)解封装(Demuxing)。
2)解码(Decoding)。
3)编码(Encoding)。
4)封装(Muxing)。
其中需要经过6个步骤,具体如下。
1)读取输人源。
2)进行音视频的解封装。
3)解码每一帧音视频数据
4)编码每一帧音视频数据。
5)进行音视频的重新封装。
6)输出到目标。
FFmpeg不但可以提供转码、转封装等功能,同时还提供了播放器相关功能,使用FFmpeg的avformat与avcodec,可以播放各种媒体文件或者流。如果想要使用fplay,那么系统首先需要有SDL来进行fplay的基础支撑。
fplay是FFmpeg源代码编译后生成的另一个可执行程序,与fmpeg在FFmpeg项目中充当的角色基本相同,可以作为测试工具进行使用,fplay提供了音视频显示和播放相关的图像信息、音频的波形信息等。
注意:
有时通过源代码编译生成fplay不一定能够成功,因为mplay在旧版本时依赖于SDL-1.2,而fplay在新版本时依赖于SDL-2.0,需要安装对应的SDL才能生成flaya
ffprobe也是FFmpeg源码编译后生成的一个可执行程序。ffprobe是一个非常强大的多媒体分析工具,可以从媒体文件或者媒体流中获得你想要了解的媒体信息,比如音频的参数、视频的参数、媒体容器的参数信息等。
例如它可以帮助分析某个媒体容器中的音频是什么编码格式、视频是什么编码格式,同时还可以得到媒体文件中媒体的总时长、复合码率等信息。
使用fprobe可以分析媒体文件中每个包的长度、包的类型、顿的信息等
FFmpeg在官方网站中提供了已经编译好的可执行文件。因为FFmpeg是开源的,所以也可以根据自己的需要进行手动编译。FFmpeg官方建议用户自行编译使用FFmpeg的最新版本,因为对于一些操作系统,比如Linux系统(无论是Ubuntu还是RedHat),如果使用系统提供的软件库安装fimpeg时会发现其版本相对比较老旧,比如使用apt-getinstall fmpeg或者yuminstallfmpeg安装fmpeg,那么默认支持的版本都很老,有些新的功能并不支持,如一些新的封装格式或者通信协议。
FFmpeg本身支持一些音视频编码格式、文件封装格式与流媒体传输协议,但是支持的数量依然有限,FFmpeg所做的只是提供一套基础的框架,所有的编码格式、文件封装格式与流媒体协议均可以作为FFmpeg的一个模块挂载在FFmpeg框架中。这些模块以第三方的外部库的方式提供支持,可以通过FFmpeg源码的configure命令查看FFmpeg所支持的音视频编码格式、文件封装格式与流媒体传输协议,对于FFmpeg不支持的格式,可以通过configure--help查看所需要的第三方外部库,然后通过增加对应的编译参数选项进行支持。
configure--help
FFmpeg中常用的工具主要是fimpeg、fprobe、ffplay,它们分别用作多媒体的编解码工具、内容分析工具和播放器。
fmpeg在做音视频编解码时非常方便,所以在很多场景下转码使用的是fmpeg,通过ffmpeg--help可以看到fmpeg常见的命令大概分为6个部分,具体如下。
通过ffmpeg--help查看到的help信息是fmpeg命令的基础信息,如果想获得高级参数部分,那么可以通过使用ffmpeg --help long参数来查看,如果希望获得全部的帮助信息,那么可以通过使用ffmpegg --help full参数来获得。
看fmpeg的版本,包括子模块的详细版本信息,如libavformat、libavcodec、libavutil、libavfilter、libswscale、libswresample的版本。
- ffmpeg --help long
- ffmpegg --help ful
在FFmpeg套件中,除了fmpeg作为多媒体处理工具之外,还有ffprobe多媒体信息查看工具,ffprobe主要用来查看多媒体文件的信息.
fprobe常用的参数比较多,可以通过fprobe--help来查看详细的帮助信息。
fprobe--help
使用fprobe-showpacketsinput.flv查看多媒体数据包信息:
通过showpackets查看的多媒体数据包信息使用PACKET标签括起来,其中包含的信息主要如表
字段 | 说明 |
.codec_type | 多媒体类型,如视频包、音频包等 |
Stream index | 多媒体的stream索引 |
PIS | 多媒体的显示时间值 |
pIs_time | 根据不同格式计算过后的多媒体的显示时间 |
dts | 多媒体解码时间值 |
dts time | 根据不同格式计算过后的多媒体解码时间 |
duration | 多媒体包占用的时间值 |
duration timc | 根据不同格式计算过后的多媒体包所占用的时间值 |
size | 多媒体包的大小 |
pos | 多媒体包所在的文件偏移位置 |
flags | 多媒体包标记,如关键包与非关键包的标记 |
除了packets与data之外,ffprobe还可以分析多媒体的封装格式,通过ffprobe-show_formatoutput.mp4命令可以查看多媒体的封装格式,其使用FORMAT标签括起来显示:
下面对输出信息关键字段进行说明,具体见表
字段 | 说明 |
filename | 文件名 |
nb streams | 媒体中包含的流的个数 |
nbprograms | 节目数(相关的概念在2.3节中会有详细的介绍) |
format name | 使用的封装模块的名称 |
format long name | 封装的完整名称 |
start time | 媒体文件的起始时间 |
duration | 媒体文件的总时间长度 |
size | 媒体文件的大小 |
bit rate | 媒体文件的码率 |
通过ffprobe-show_framesinput.dv命令可以查看视频文件中的赖信息,输出的顺信息将使用FRAME标签括起来
- [FRAME]
- media_type=video
- stream index=0
- key_frame=l
- pkt pts=80
- pkt_pts_time=0.080000
- pkt dts=80
- pkt dts_time=0.080000
- begt effort timegtamp=80
- best effort timestamp_time=0.080000
- pkt_duration=N/A
- pkt duration time=N/A
- pkt_pog=344
- pkt_size=8341
- width=1280
- height=714
- pix fmt=yuv420p
- 6ample_aspect_ratio=1:1
- pict_type=T
- coded picture number=0
- display picture number=0
- interlaced frame=0
- top_field first=o
- repeat pict=0
- [/FRAME]
通过-show_frames参数可以查看每一帧的信息,下面就来介绍一下其中重要的信息,具体见表
属性 | 说明 | 值 |
media type | 的类型(视频、音频,字幕等) | video |
stream index | 帧所在的索引区域 | 0 |
key_frame | 是否为关键顿 | 1 |
pktpts | Frame包的pts | 0 |
pkt pis time | Frame包的ps的时间显示 | 0.08 |
pkt dts | Frame包的dts | 80 |
pkt dis time | Frame包的dts的时间显示 | 0.08 |
pkt duration | Frame包的时长 | NIA |
pkt duration time | Frame包的时长时间显示 | NIA |
pkt pos | Frame包所在文件的偏移位置 | 344 |
width | 显示的宽度 | 1280 |
height | 显示的高度 | 714 |
pix fimt | 倾的图像色彩格式 | yuv420p |
piet type | 侦类型 | I |
通过-show streams参数可以查看到多媒体文件中的流信息,流的信息将使用STREAM标签括起来:
1eve1=31如以上输出内容所示,从中可以看到流的信息,具体属性及说明见表
属性 | 说明 | 值 |
index | 流所在的索引区域 | 0 |
codecnamc | 编码名 | h264 |
codee long name | 编码全名 | MPEG-4 part 10 |
profile | 编码的profile | High |
属性 | 说明 | 值 |
level | 编码的level | 31 |
has b frames | 包含B赖信息 | 2 |
codec type | 编码类型 | video |
codec timebase | 编码的时间截计算基础单位 | 1750 |
pix fmt | 图像显示的色彩格式 | yuv420p |
codedwidth | 图像的宽度 | 1280 |
coded height | 图像的高度 | 714 |
codec tag string | 编码的标签数据 | [0][0][0][0] |
Tframe rateavg frame rate | 实际硕率平均帧率 | 25/125/ |
time base | 时间基数(用来进行timestamp计算) | 1/1000 |
bit rate | 码率 | 200000 |
xbit ratemax | 最大码率 | N/A |
nb_frames | 帧数 | N/A |
在编译旧版本FFmpeg源代码时,如果系统中包含了SDL-1.2版本,就会默认将ffplay编译生成出来,如果不包含SDL-1.2或者版本不是SDL-l.2时,将无法生成ffplay文件,所以,如果想使用flay进行流媒体播放测试,则需要安装SDL-1.2.而在新版本的FFmpeg源代码中,需要SDL-2.0之后的版本才能有效生成ffplay.。
在FFmpeg中通常使用ffplay作为播放器,其实ffplay同样也可以作为很多音视频数据的图形化分析工具,通过ffplay可以看到视频图像的运动估计方向、音频数据的波形等.
下表是ffplay的基础参数
参数 | 说明 |
x | 强制设置视频显示窗口的宽度 |
y | 强制设置视频显示窗口的高度 |
s | 设置视频显示的宽高 |
fs | 强制全屏显示 |
an | 屏蔽音频 |
vn | 屏蔽视频 |
sn | 屏蔽字幕 |
ss | 根据设置的秒进行定位拖动 |
t | 设置播放视频/音频的长度 |
bytes | 设置定位拖动的策略,0为不可拖动,1为可拖动,-1为自动 |
nodisp | 关闭图形化显示窗口 |
f | 强制使用设置的格式进行解析 |
window title | 设置显示窗口的标题 |
af | 设置音频的滤镜 |
codec | 强制使用设置的codec进行解码 |
autorotate | 自动旋转视频 |
下面这个表是ffplay高级参数
参数 | 说明 |
ast | 设置将要播放的音额流 |
vst | 设置将要播放的视频流 |
sst | 设置将要播放的字幕流 |
stats | 输出多媒体播放状态 |
fast | 非标准化规范的多媒体兼容优化 |
sync | 音视频同步设置可根据音频时间、视频时间或者外部扩展时间进行参考 |
autoexit | 多媒体播放完毕之后自动退出fplay,fplay默认播放完毕之后不退出播放器 |
cxitonkeydown | 当有按键按下事件产生时退出ffplay |
exitonmousedown | 当有鼠标按键事件产生时退出fplay |
loop | 设置多媒体文件循环播放的次数 |
framedrop | 当CPU资源占用过高时,自动丢顿 |
infbuf | 设置无极限的播放器buffer,这个选项常见于实时流媒体播放场景 |
vf | 视频滤镜设置 |
acodec | 强制使用设置的音频解码器 |
vcodec | 强制使用设置的视频解码器 |
scodec | 强制使用设置的字幕解码器 |
(累了orz,下次更,有人看可以关注回复我下,更有动力)
3.1.1MP4格式标准介绍
MP4格式标准为IS0-14496Part12、IS0-14496Part14,标准内容并不是特别多,下面就来着重介绍一些重要的信息。
如果要了解MP4的格式信息,首先要清楚几个概念,具体如下。
Box MP4文件中Box的组成可以用表3-1所示的列表进行排列,表3-1中标记“V”的Box为必要Box,否则为可选Box。
3.H.264的proffle与level设置
这里的profile(档次)与level(等级)的设置与H.264标准文档ISO-14496-Part10中描述的profile、level的信息基本相同,×264编码器支持Baseline、Extented、Main、High、High10、High422、High444共7种profile参数设置,根据profile的不同,编码出来的视频的很多参数也有所不同,具体的情况可以参考表。
ExtentedMainBaseline | High | High10 | High4:2:2 | High4:4:4(Predictive) | |||
1与P分片 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
B分片 | 不支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
SI和SP分片 | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 |
多参考幢 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
环路去块滤波 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
CAVLC愉编码 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
CABAC编码 | 不支持 | 不支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
FMO | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 |
ASO | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 |
RS | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 |
数据分区 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | |
场编码PAFF/MBAFF | 不支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
42:0色度格式 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
4:0:0色度格式 | 不支持 | 不支持 | 不支持 | 支持 | 支持 | 支持 | 支持 |
42:2色度格式 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 支持 | 支持 |
44:4色度格式 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 支持 |
8位采样深度 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
9和10位采样深度 | 不支持 | 不支持 | 不支持 | 不支持 | 支持 | 支持 | 支持 |
11至14位采样深度 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 支持 |
8×8与4×4转换适配 | 不支持 | 不支持 | 不支持 | 支持 | 支持 | 支持 | 支持 |
量化计算矩阵 | 不支持 | 不支持 | 不支持 | 支持 | 支持 | 支持 | 支持 |
分离Cb和Cr量化参数控制 | 不支持 | 不支持 | 不支持 | 支持 | 支持 | 支持 | 支持 |
分离色彩平面编码 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 支持 |
分离无损编码 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | 支持 |
在音视频流中,无论直播与点播,AAC都是目前最常用的一种音频编码格式,例如RTMP直播、HLS直播、RTSP直播、FLV直播、FLV点播、MP4点播等文件中都是常见的AAC音视频。
与MP3相比,AAC是一种编码效率更高、编码音质更好的音频编码格式,常见的使用AAC编码后的文件存储格式为m4a,如在iPhone或者iPad中即为m4a.FFmpeg可以支持AAC的三种编码器具体如下。
后两种编码器为非GPL协议,所以使用起来需要注意,在预编译时需要注意采用nonfree的支持。
AAC-LC的音频编码可以采用libfaac、libfdk aac、FFmpeg内置AAC三种,其质量顺序排列如下。
AAC-LC的音频编码可以采用libfaac、libfdk_aac、FFmpeg内置AAC三种,其质量顺序排列如下
libfdkaac音频编码质量最优
FFmpeg内置AAC编码次于libfdkaac但优于libfaac
libfaac在FFmpeg内置AAC编码为实验品时是除了Iibfdkaac之外的唯一选择。
随着互联网、移动互联网的发展,人们获取信息的方式开始从纸质媒体转向互联网文字媒体,又从文字媒体转向音视频流媒体。音视频流媒体又称为“流媒体”,而用于处理流媒体的压缩、录制、编辑操作,开源并强大的工具屈指可数,FFmpeg就是常见的流媒体处理工具。
3.解析trak子容器
trak容器中定义了媒体文件中的一个track的信息,一个媒体文件中可以包含多个trak,每个trak都是独立的,具有自己的时间和空间占用的信息,每个trak容器都有与它关联的media容器描述信息。trak容器的主要使用目的具体如下。
hint track和modifier track必须保证完整性,同时要与至少一个media track一起存在。
一个trak容器中要求必须要有一个Track Header Atom(tkhd)、一个Media Atom(mdia),其他的Atom都是可选的,例如如下的atom选项。