1.1FFmpeg的定义
FFmpeg既是一款音视频编解码工具,同时也是一组音视频编解码开发套件,作为编解码开发套件,它为开发者提供了丰富的音视频处理的调用接口。FFmpeg中的"FF"指的是"Fast Forward",FFmpeg中的 "mpeg"
则是人们通常理解的Moving Picture Experts Group(动态图像专家组), FFmpeg是一个很全面的图像处理套件。
git:// source. ffmpeg.org/ffmpeg.git
http: //git.videolan.org/?p=ffmpeg.git
https://github.corn/FFmpeg/FFmpeg
视频库
https://file-examples.com/index.php/sample-video-files/sample-mp4-files/?utm_source=chatgpt.com
1.2FFmpeg的基本组成
FFmpeg框架的基本组成包含AVFormat、AV Codec、AVFilter、AVDevice、AVUtil 等模块库。
1. FFmpeg 的封装模块AVFormat
AVFormat中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,如MP4、FLY、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(mp3 lame)编码,需要使用libmp3lame 编码器。如果希望增加自己的编码格式,或者硬件编解码,则需要在AVCodec中增加相应的编解码模块。
3. FFmpeg 的滤镜模块AVFilter
AVFilter库提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。我们参考下面这个滤镜处理的例子,如图1-2所示。

图1-2所示样例中的滤镜处理将输入的视频切割成了两部分流,一部分流抛给crop滤镜与vflip滤镜处理模块进行操作,另一部分保持原样,当crop滤镜与vflip滤镜处理操作完成之后,将流合并到原有的overlay图层中,并显示在最上面一层,输出新的视频。对应的命令行如下:
cpp
ffmpeg -i input.mp4 -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" output.mp4

以上内容输出完成,该命令将自动退出,生成的视频结果是保留视频的上半部分,同时上半部分会镜像到视频的下半部分,二者合成之后作为输出视。
下面详细说明一下规则,具体如下:
相同的Filter线性链之间用逗号分隔
不同的Filter线性链之间用分号分隔
在以上示例中,crop与vflip使用的是同一个滤镜处理的线性链,split滤镜和overlay滤镜使用的是另外一个线性链,一个线性链与另一个线性链汇合时是通过方括号"[]"括起来的标签进行标示的。在这个例子中,两个流处理后是通过[main]与[flip]进行关联汇合的。
split滤镜将分割后的视频流的第二部分打上标签[tmp],通过crop滤镜对该部分流进行处理,然后进行纵坐标调换操作,打上标签[flip],然后将[main]标签与[flip]标签进行合井,[flip]标签的视频流从视频的左边最中间的位置开始显示,这样就出现了镜像效果。
4. FFmpeg的视频图像转换计算模块swscale
swscale模块提供了高级别的图像转换API,例如它允许进行图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p等的缩放,或者将图像数据从YUV420P 转换成YUYV ,或者YUV 转RGB等图像格式转换。
5. FFmpeg 的音频转换计算模块swresample
swresample模块提供了高级别的音频重采样API 。例如它允许操作音频采样、音频通道布局转换与布局调整。
1.3 FFmpeg的编解码工具ffmpeg
ffmpeg是FFmpeg源代码编译后生成的一个可执行程序,其可以作为命令行工具使用。
cpp
ffmpeg -i input.mp4 output.avi
这是一条简单的ffmpeg命令,可以看到,ffmpeg通过 -i 参数将input.mp4作为输入源输入,然后进行转码与转封装操作,输出到output.avi中,这条命令主要做了如下工作:
获取输入源input.mp4
转码
输出文件output.avi
看似简单的两步主要的工作,其实远远不止是从后缀名为MP4的文件输出成后缀名为AVI的文件,因为在ffmpeg中, MP4与AVI是两种文件封装格式,并不是后缀名就可以决定的,例如上面的命令行同样可以写成这样:
cpp
ffmpeg -i input.mp4 -f avi output.dat
这条ffmpeg命令相对于前面的那条命令做了一些改变,加了一个"-f"进行约束,"-f"参数的工作非常重要,它制定了输出文件的容器格式,所以可以看到输出的文件为output.dat,文件后缀名为.dat ,但是其主要工作依然与之前的指令相同。
ffmpeg的主要工作流程相对比较简单,具体如下:
解封装(Demuxing)
解码(Decoding)
编码(Encoding)
封装(Muxing)
其中需要经过6 个步骤,具体如下:
读取输入源
进行音视频的解封装
解码每一帧音视频数据
编码每一帧音视频数据
进行音视频的重新封装
输出到目标

从图1-4所示的工作流程可以看出,ffmpeg首先读取输入源;然后通过Demuxer将音视频包进行解封装,这个动作通过调用libavformat中的接口即可实现;接下来通过Decoder进行解码,将音视频通过Decoder解包成为YVU或者PCM这样的数据,Decoder通过libavcodec中的接口即可实现;然后通过Encoder将对应的数据进行编码,编码可以通过libavcodec中的接口来实现;接下来将编码后的音视频数据包通过Muxer进行封装,Muxer封装通过libavformat中的接口即可实现,输出成为输出流。
1.4 FFmpeg 的播放器ffplay
ffplay是FFmpeg源代码编译后生成的另一个可执行程序,与ffmpeg在FFmpeg项目中充当的角色基本相同,可以作为测试工具进行使用,ffplay提供了音视频显示和播放相关的图像信息、音频的波形信息等。
1.5 FFmpeg的多媒体分析器ffprobe
ffprobe也是FFmpeg源码编译后生成的一个可执行程序。ffprobe是一个非常强大的多媒体分析工具,可以从媒体文件或者媒体流中获得你想要了解的媒体信息,比如音频的参数、视频的参数、媒体容器的参数信息等。
例如它可以帮助分析某个媒体容器中的音频是什么编码格式、视频是什么编码格式,同时还可以得到媒体文件中媒体的总时长、复合码率等信息。
使用ffprobe可以分析媒体文件中每个包的长度、包的类型、帧的信息等。
cpp
ffprobe -show_stream output.mp4
根据输出内容可以看到,使用ffprobe能够查看MP4文件容器中的流的信息,其包含了一个视频流,由于该文件中只有视频流,流相关的信息是通过[STREAM][/STREAM]的方式展现出来的,在[STREAM]与[/STREAM]之间的信息即为该MP4文件的视频流信息。当视频文件容器中包含音频流与视频流或者更多路流时,会通过[STREAM]与[/STREAM]进行多个流的分隔,分隔后采用index来进行流的索引信息的区分。