FFmpeg的基本组成
FFmpeg框架的基本组成包含AVFormat、AVCodec、AVFilter、AVDevice、AVUtil等模块库。
(1)FFmpeg的封装模块AVFormat
AVFormat中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装与解封装,如MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库。根据实际需求,可进行媒体封装格式的拓展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。
(2)FFmpeg的编解码模块AVCodec
AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,既支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x265编码器;MP3(MP3lame)编码,需要使用libmp3lame编码器。如果希望增加自己的编码格式,或者硬件编码器,则需要在AVCodec中增加相应的编码模块。
(3)FFmpeg的滤镜模块AVFilter
AVFilter库提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。
FFmpeg转封装
- 音视频文件转MP4格式
在互联网常见的个格式中,跨平台最好的应该是MP4文件,因为MP4文件既可以在PC平台的Flashplayer中播放,又可以在移动平台的Android、IOS等平台中进行播放,而且使用系统默认的播放器即可播放,因此我们说MP4格式是最常见的多媒体文件格式。 - 视频文件转FLV
在网络的直播与点播场景中,FLV也是一种常见的格式,FLV是Adobe发布的一种可以作为直播也可以作为点播的封装格式,其封装格式非常简单,均已FLVTAG的形式存在,并且每一个TAG都是独立存在的。
FLV封装中可以支持的视频编码主要包含如下:
- Sorenson H.263
- Screen Video
- On2 VP6
- 带Alpha通道的On2 VP6
- Screen Video 2
- H.264(AVC)
而FLV封装中支持的音频主要包含如下:
- 限行PCM,大小端取决于平台
- ADPCM音频格式
- MP3
- 线性PCM,小端
- Nellymoser 16kHz Mono
- Nellymoser 8kHz Mono
- Nellymoser
- G.711 A-law
- G.711 mu-law
- 保留
- AAC
- Speex
- MP3 8kHZ
- 视频文件转M3U8
M3U8是一种常见的流媒体格式,主要以文件列表的形式存在,既可以支持直播又支持点播,尤其在Android、IOS等平台最为常用。
FFmpeg中自带HLS的封装参数,使用HLS格式即可进行HLS的封装,但是生成HLS的时候有各种参数进行参考,例如设置HLS列表中切片的前置路径、生成HLS的TS切片时设置TS的分片参数、生成HLS时设置M3U8列表中保存的TS个数等。 - 视频文件切片
视频文件切片与HLS基本类似,但是HLS切片在标准中只支持TS格式的切片,并且是直播与点播切片,既可以使用segment方式进行切片,也可以使用ss加上-t参数进行切片。
FFmpeg转码
软编码H.264与H.265
硬编解码Nvidia GPU硬编解码、Intel QSV硬编解码、树莓派硬编码、OS X系统硬编解码
ffmpeg的转码参数
ffmpeg编解码部分的功能主要是通过模块AVCodec来完成的,通过libavcodec库进行Encode与Decode操作。多媒体编码格式的种类有很多,但是还是有很多通用的基本操作参数设置。下面看一下通用参数。
通过命令ffmpeg --help full可以看到AVCodecContext参数列表信息,该选项下面的所有参数均为编解码可以使用的参数。
参数 | 类型 | 说明 |
---|---|---|
b | 整数 | 设置音频与视频码率,可以认为是音频加起来的码率,默认为200kbit/s,使用这个参数可以根据b:v设置视频码率,b:a设置音频码率 |
ab | 整数 | 设置音频的码率,默认是128kbit/s |
g | 整数 | 设置视频GOP(可以理解为关键帧间隔)大小,默认是12帧一个GOP |
ar | 整数 | 设置音频采样率,默认为0 |
ac | 整数 | 设置音频通道数,默认为0 |
bf | 整数 | 设置连续编码为B帧的个数,默认为0 |
maxrate | 整数 | 最大码率设置,与bufsize一同使用即可,默认为0 |
minrate | 整数 | 最小码率设置,配合maxrate与bufsize可以设置为CBR模式,平时很少使用,默认为0 |
bufsize | 整数 | 设置控制码率的buffer的大小,默认是0 |
keyint_min | 整数 | 设置关键帧最小间隔,默认是25 |
sc_threshold | 整数 | 设置场景切换支持,默认是0 |
me_threshold | 整数 | 设置运动估计阈值,默认是0 |
mb_threshold | 整数 | 设置宏块阈值,默认是0 |
profile | 整数 | 设置音视频的profile,默认是-99 |
level | 整数 | 设置音视频的level,默认是-99 |
timecode_frame_start | 整数 | 设置GOP帧的开始时间,需要在non-drop-frame默认情况下使用 |
channel_layout | 整数 | 设置音频通道的布局格式 |
threads | 整数 | 设置编解码工作的线程数 |
- FFmpeg输出MP3
平均码率编码参数ABR
ABR是VBR与CBR的混合产物,表示平均码率编码,使用ABR参数之后,编码速度将会比VBR高,但是质量会比VBR的编码稍逊一些,比CBR编码好一些,在FFmpeg中可使用参数-abr来控制MP3编码为ABR编码方式
-
FFmpeg输出AAC
在音视频流中,无论直播与点播,AAC都是目前最常用的一种音频 编码格式,例如RTMP直播、HLS直播、RTSP直播、FLV直播、FLV点播、MP4点播等文件中都是常见的AAC音视频。
与MP3相比,AAC是一种编码效率更高、编码音质更好的音频编码格式,常见的使用AAC编码后的文件存储格式为m4a,如在iPhone或者iPad中即为m4a。FFmpeg可以支持AAC的三种编码器具体如下。
- aac:FFmpeg本身的AAC编码实现
- libfaac:第三方的AAC编码器
- libfdk_aac:第三方的AAC编码器
后两种编码器为非GPL协议,所以使用起来需要注意,在预编译时需要主要采用nonfree的支持。
FDK AAC第三方的AAC编解码Codec库
FDK-AAC库是FFmpeg支持的第三方编码库中质量最高的AAC编码库,关于编码音质的好坏与使用方式有一定的关系。
- 恒定码率(CBR)模式
如果使用libfdk_aac设定一个恒定的码率,改变编码后的大小,并且可以兼容HE-AAC Profile,则可以根据音频设置的经验设置码率,例如如果一个声道使用64kbit/s,那么双声道为128kbit/s,环绕立体声为384kbit/s,这种通常为5.1环绕立体声。可以通过b:a参数进行设置。下面举例:
./ffmpeg -i input.wav -c:a libfdk_aac -b:a 128k output.m4a
根据这条命令可以看出,FFmpeg使用libfdk_aac将input.wav转为恒定码率为128kbit/s、编码为AAC的output.m4a音频文件。
./ffmpeg -i input.mp4 -c:v copy -c:a libfdk_aac -b:a 384k output.mp4
根据这条命令可以看出,FFmpeg将input.mp4的视频文件按照原有的编码方式进行输出封装,将音频以libfdk_aac进行编码,音频通道为环绕立体声,码率为384kbit/s,封装格式为output.mp4。
以上两个例子均为使用libfdk_aac进行AAC编码的案例,使用libfdk_aac可以编码AAC的恒定码率(CBR)。
- 动态码率(VBR)模式
使用VBR可以有更好的音频质量,使用libfdk_aac进行VBR模式的AAC编码时,可以设置5个级别。
VBR | 每声道码率/(kbit/s) | 编码信息 |
---|---|---|
1 | 20~32 | LC、HE、HEv2 |
2 | 32~40 | LC、HE、HEv2 |
3 | 48~56 | LC、HE、HEv2 |
4 | 64~72 | LC |
5 | 96~112 | LC |
第三列中有三种AAC编码信息,具体如下:
- LC: Low Complexity AAC,这种编码相对来说体积比较大,质量稍差
- HE:High-Efficiency AAC,这种编码相对来说体积稍小,质量较好
- HEv2:High-Efficiency AAC version 2,这种编码相对来说体积小,质量最优
- 平均码率(ABR)
H.264
H.264编码举例:
1.从编码器预设参数设置perset
- ultrafast:最快的编码方式
除了默认设置之外,还增加了如下参数设置:
–no-8x8dct --aq-mode 0 --bframes 0 --no-cabac --no-deblock --no-mbtree --me dia --no-mixed-refs --partitions none --rc-lookahead 0 --ref 1 --scenecut 0 --subme 0 --trellis 0 --no-weightb --weightp 0
- superfast:超级快速的编码方式
除了默认设置之外,还增加了如下参数设置:
–no-mbtree --me dia --no-mixed-refs --partitions i8x8,i4x4 --rc-lookahead 0 --ref 1 --subme 1 --trellis 0 --weightp 1 - veryfast:非常快速的编码方式
除了默认设置之外,还增加了如下参数设置:
–no-mixed-refs --rc-lookahead 10 --ref 1 --subme2 --trellis 0 --weightp 1 - faster:稍微快速的编码方式
除了默认设置之外,还增加了如下参数设置:
–no-mixed-refs --rc-lookahead 20 --ref 2 --subme 4 --weightp 1 - fast:快速的编码方式
除了默认设置之外,还增加了如下参数设置:
–rc-lookahead 30 --ref 2 --subme 6 --weightp 1 - medium:折中的编码方式
参数全部为默认设置 - slow:慢的编码方式
除了默认设置之外,还增加了如下参数设置:
–b-adapt 2 --direct auto --me umh --rc-lookahead 50 --ref 5 --subme 8 - slower:更慢的编码方式
除了默认设置之外,还增加了如下参数设置:
–b-adapt 2 --direct suto --me umh --partitions all --rc-lookahead 60 --ref 8 --subme 9 --trellis 2 - veryslow:非常慢的编码方式
除了默认设置之外,还增加了如下参数设置:
–b-dapt 2 --bframes 8 --direct auto --me umh --merange 24 --partitions all --ref 16 --subme 10 --trellis 2 --rc-lookahead 60 - placebo:最慢的编码方式
除了默认设置之外,还增加了如下参数设置:
–bframes 16 --b-adapt 2 --direct auto --slow-firstpass --no-fast-pskip --me tesa --merange 24 --partitions all --rc-lookahead 60 --ref 16 --subme 11 --trellis 2
[root@ip-172-31-32-39 bin]# ./ffmpeg -i /data/video/input_test.mp4 -vcodec libx264 -preset ultrafast -b:v 2000k output_20210907.mp4
ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 8 (GCC)
configuration: --enable-libx264 --enable-libfdk-aac --enable-gpl --enable-nonfree --prefix=/usr/local/ffmpeg
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/data/video/input_test.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.58.101
Duration: 00:00:46.44, start: 0.000000, bitrate: 525 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x368 [SAR 1:1 DAR 40:23], 476 kb/s, 24 fps, 24 tbr, 12288 tbn, 96 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 48 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 0x353c8c0] using SAR=1/1
[libx264 @ 0x353c8c0] using cpu capabilities: none!
[libx264 @ 0x353c8c0] profile Constrained Baseline, level 3.0, 4:2:0, 8-bit
[libx264 @ 0x353c8c0] 264 - core 157 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=1 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=24 scenecut=0 intra_refresh=0 rc=abr mbtree=0 bitrate=2000 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
Output #0, mp4, to 'output_20210907.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.45.100
Stream #0:0(und): Video: h264 (libx264) (avc1 / 0x31637661), yuv420p(progressive), 640x368 [SAR 1:1 DAR 40:23], q=-1--1, 2000 kb/s, 24 fps, 12288 tbn, 24 tbc (default)
Metadata:
handler_name : VideoHandler
encoder : Lavc58.91.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 0 vbv_delay: N/A
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
encoder : Lavc58.91.100 aac
frame= 1104 fps=103 q=19.0 Lsize= 11294kB time=00:00:46.41 bitrate=1993.3kbits/s speed=4.34x
video:10542kB audio:728kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.213971%
[libx264 @ 0x353c8c0] frame I:5 Avg QP:21.20 size: 32074
[libx264 @ 0x353c8c0] frame P:1099 Avg QP:23.48 size: 9676
[libx264 @ 0x353c8c0] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0x353c8c0] mb P I16..4: 11.0% 0.0% 0.0% P16..4: 54.5% 0.0% 0.0% 0.0% 0.0% skip:34.6%
[libx264 @ 0x353c8c0] final ratefactor: 21.91
[libx264 @ 0x353c8c0] coded y,uvDC,uvAC intra: 53.4% 45.6% 13.0% inter: 36.3% 19.2% 2.0%
[libx264 @ 0x353c8c0] i16 v,h,dc,p: 27% 36% 17% 19%
[libx264 @ 0x353c8c0] i8c dc,h,v,p: 42% 29% 18% 11%
[libx264 @ 0x353c8c0] kb/s:1877.29
[aac @ 0x354b180] Qavg: 978.074