简介

  • FFmpeg框架的基本组成包含AVFormat, AVCodec, AVFilter, AVDevice, AVUtil等模块库。

  • FFmpeg的封装模块AVFormat
    • AVFormat中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,例如MP4,FLV,KV,TS等文件封装格式,RTMP,RTSP,MMS,HLS等网络协议封装格式。
    • FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库
  • FFmpeg的编解码模块AVCodec
    • AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,既支持编码,也支持解码。AVCodec除了支持MJPEG4,AAC,MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,例如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x265编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。
    • 如果希望增加自己的编码格式,或者硬件编码,则需要在AVCodec中增加相应的编解码模块。
  • FFmpeg的滤镜模块AVFilter
    • AVFilter库提供了一个通用的音频,视频,字幕等滤镜过滤框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。
    • 示例:
      • ./ffmpeg -i INPUT -vf “split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip];[main][flip] overlay=0:H/2” OUTPUT
    • 相同的Filter线性链之间用逗号分隔
    • 不同的Filter线性链之间用分号分隔
    • 在以上示例中,crop与vflip使用的时同一个滤镜处理的线性链,split滤镜和overlay滤镜使用的是另一个线性链,一个线性链与另一个线性链汇合时是通过方括号[]括起来的标签进行标示的。在这个例子中,两个流处理后是通过[main]与[flip]进行关联汇合的。
    • split滤镜将分割后的视频流的第二部分打上标签[tmp],通过crop滤镜对该部分流进行处理,然后进行纵坐标调换操作,打赏标签[flip],然后将[main]标签与[flip]标签进行合并,[flip]标签的视频流从视频的左边最中间的位置开始显示,这样就出现了镜像效果
  • FFmpeg的视频图像转换计算模块swscale
    • swscale模块提供了高级别的图像转换API,例如它允许图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p的缩放,或者将图像数据从YUV420p转换成YUYV,或者YUV转RGB等图像格式转换。
  • FFmpeg的音频转换计算模块swresample
    • swresample模块提供了高级别的音频重采样API。例如它允许操作音频采样,音频通道布局与布局调整

FFmpeg的编解码工具ffmpeg

  • ffmpeg是FFmpeg源代码编译后生成的一个可执行程序,其可以作为命令行工具使用。

  • ffmpeg的主要工作流程相对比较简单,具体如下:
    • 解封装(Demuxing)
    • 解码(Decoding)
    • 编码(Encoding)
    • 封装(Muxing)
  • 其中需要经过6个步骤,具体如下:
    • 读取输入源
    • 进行音视频的解封装
    • 解码每一帧音视频数据
    • 编码每一帧音视频数据
    • 进行音视频重新封装
    • 输出到目标
  • ffmpeg首先读取输入源;然后通过Demuxer将音视频包进行解封装,这个动作通过调用libavformat中的接口即可实现;
  • 接下来通过Decoder进行解码,将音视频通过Decoder解包成为YVU或者PCM这样的数据,Decoder通过libavcodec中的接口即可实现
  • 然后通过Encoder将对应的数据进行编码,编码可以通过libavcodec中的接口来实现
  • 接下来将编码后的音视频数据包通过Muxer进行封装,Muxer封装通过libavformat中的接口即可实现,输出成为输出流

FFmpeg的播放器ffplay

  • 使用FFmpeg的avformat与avcodec,可以播放各种媒体文件或者流。如果想要使用ffplay,那么系统首先需要有SDL来进行ffplay的基础支撑

  • ffplay是FFmpeg源代码编译后生成的另一个可执行程序,与ffmpeg在FFmpeg项目中充当的角色基本相同,可以作为测试工具进行使用,ffplay提供了音视频显示和播放相关的图像信息,音频的波形信息等。

FFmpeg的多媒体分析器ffprobe

  • ffprobe也是FFmpeg源码编译后生成的一个可执行程序。ffprobe是一个非常强大的多媒体分析工具,可以从媒体文件或者媒体流中获得想要了解的信息,例如音频的参数,视频的参数,媒体容器的参数信息等。
  • 使用ffprobe可以分析媒体文件中每个包的长度,包的类型,帧的信息等

FFmpeg编译

  • FFmpeg在官方网站中提供已经编译好的可执行文件。

FFmpeg之Windows平台编译

  • FFmpeg在Windows平台中的编译需要使用MinGW-w64,MinGW是Minimalist GNU for Windows的缩写,提供了一系列的工具链来辅助编译Windows的本地化程序

  • MinGW-w64单独使用起来会比较麻烦,但是其可以与MSYS环境配合使用,MSYS是Minimal SYStem的缩写,其主要完成的工作为UNIX on Windows的功能。显而易见,这是一个仿生UNIX环境的Windows工具集

FFmpeg编码支持与定制

  • FFmpeg本身支持一些音视频编码格式,文件封装格式与流媒体传输协议,但是支持的数量依然有限,FFmpeg所做的只是提供一套基础的框架,所有的编码格式,文件封装格式和流媒体协议均可以作为FFmpeg的一个模块挂在在FFmpeg框架中。这些模块以第三方的外部库的方式提供支持,可以通过FFmpeg源码的configure命令查看FFmpeg所支持的音视频编码格式,文件封装格式与 流媒体传输协议,对于FFmpeg不支持的格式,可以通过configure –help查看所需要的第三方外部库,然后通过增加对应的编译参数选项进行支持。

  • FFmpeg默认支持额音视频编码格式,文件封装格式和流媒体传输协议相对来说比较多,因此编译出来的FFmpeg体积比较大,在有些应用场景中,并不需要FFmpeg所支持的一些编码,封装或者协议。可以通过configure –help查看一些有用的裁剪操作

  • FFmpeg的编码器支持
    • FFmpeg源代码中可以包含的编码非常多,常见的和不常见的都可以在编译配置列表中见到,可以通过使用编译配置命令./configure –list-encoders参数来查看
  • FFmpeg的解码器支持
    • FFmpeg源代码本身包含了很多的解码支持,解码主要是在输入的时候进行解码,也可以理解为将压缩过的编码进行解压缩,关于解码的支持,可以通过./configure –list-decoders命令来查看
  • FFmpeg的封装支持
    • FFmpeg的封装(Muxing)是指将压缩后的编码封装到一个容器格式中,如果要查看FFmpeg源代码中都可以支持哪些容器格式,可以通过命令./configure –list-muxers来查看
  • FFmpeg的解封装支持
    • FFmpeg的解封装(Demuxing)是指将读入的容器格式拆解开,将里面的压缩的音频流,视频流,字幕流,数据流等提取出来,如果要查看FFmpeg的源代码中都可以支持哪些输入的容器格式,可以通过命令./configure –list-demuxers来查看
  • FFmpeg的通信协议支持
    • FFmpeg不仅仅支持本地的多媒体处理,而且还支持网络流媒体的处理,支持的网络流媒体协议相对来说也很全面,可以通过命令./configure –list-protocols查看

ffmpeg常用命令

  • ffmpeg在做音视频编解码时非常方便,所以在很多场景下转码使用的时ffmpeg,通过ffmpeg –help可以看到ffmpeg常见的命令大概分为6个部分,具体如下:
    • ffmpeg信息查询部分
    • 公共操作参数部分
    • 文件主要操作参数部分
    • 视频操作参数部分
    • 音频操作参数部分
    • 字幕操作参数部分

ffmpeg的封装转换

  • ffmpeg的封装转换(转封装)功能包含在AVFormat模块中,通过libavformat库进行Mux和Demux操作;多媒体文件的格式有很多种,这些格式中的很多参数在Mux与Demux的操作参数中是公用的。

ffmpeg的转码参数

  • ffmpeg编解码部分的功能主要是通过模块AVCodec来完成的,通过libavcodec库进行Encode和Decode操作。多媒体编码格式的种类有很多,但是还是有很多通用的基本操作参数设置

ffmpeg的基本转码原理

  • ffmpeg工具的主要用途为编码,解码,转码以及媒体格式转换,ffmpeg常用于进行转码操作。

ffprobe常用命令

  • ffprobe主要用来查看多媒体文件的信息。

  • 使用 ffprobe -show_packets input.flv 查看多媒体数据包信息;也可以通过 ffprobe -show_data -show_packets input.flv 组合参数来查看包中的具体数据。

  • 通过 ffprobe -show_format output.mp4 命令可以查看多媒体的封装格式,其使用FORMAT标签括起来显示

  • 通过 ffprobe -show_frames input.flv 命令可以查看视频文件中的帧信息,输出的帧信息将使用FRAME标签括起来

  • 通过 -show_streams 参数可以查看到多媒体文件中的流信息,流的信息将使用STREAM标签括起来

  • ffprobe使用前面的参数可以获得key-value格式的显示方式;如果要进行格式化的显示,这样就需要用到ffprobe -print_format或者ffprobe -of 参数来进行相应的格式输出,而-print_format 支持多种格式输出,包括XML,INI,JSON,CSV,FLAT等

ffplay常用命令

  • 在FFmpeg中通常使用ffplay作为播放器,其实ffplay同样也可以作为很多音视频数据的图形化分析工具,通过ffplay可以看到视频图像的运动方向,音视频数据的波形等

ffplay常用参数

  • ffplay不仅仅是播放器,同时也是测试ffmpeg的codec引擎,format引擎,以及filter引擎的工具,并且还可以进行可视化的媒体参数分析

ffplay的数据可视化分析应用

  • 使用ffplay除了可以播放视频流媒体文件之外,还可以作为可视化的视频流媒体分析工具,例如播放音频文件,如果不确定文件的声音是否正常,则可以直接使用ffplay播放音频文件,播放的时候其将会把解码后的音频数据以音频波形的形式显示出来

音视频文件转MP4格式

  • 在互联网常见的格式中,跨平台最好的应该是MP4文件,因为MP4文件既可以在PC平台的Flashplayer中播放,又可以在移动平台的Android,IOS等平台中进行播放,而且使用系统默认的播放器即可播放,因此我们说MP4格式是最常见的多媒体文件格式。

视频文件转FLV

  • 在网络的直播与点播场景中,FLV也是一种常见的格式,FLV是Adobe发布的一种可以作为直播也可以作为点播的封装格式,其封装格式非常简单,均以FLVTAG的形式存在,并且每一个TAG都是独立存在的。

视频文件转M3U8

  • M3U8是一种常见的流媒体格式,主要以文件列表的形式存在,即支持直播又支持点播,尤其在Android,IOS等平台最为常用

FFmpeg抽取音视频文件中的AAC音频流

  • FFmpeg除了转封装,转码之外,还可以提取音频流,例如需要将音频流提取出来然后合成之后插入到另一个封装中的情况。

  • FFmpeg提取MP4文件中的AAC音频流方法:

    • ./ffmpeg -i input.mp4 -vn -acodec copy output.aac

FFmpeg 硬编解码

  • 当使用FFmpeg进行软编码时,常见的基于CPU进行H.264或H.265编码其相对成本会比较高,CPU编码时的性能也很低,所以出于编码效率及成本考虑,很多时候都会考虑采用硬编码,常见的硬编码包含Nvidia GPU与Intel QSV两种,还有常见的嵌入式平台,例如树莓派,瑞芯微等。