
2.3 九阴真经:FFMpeg
《九阴真经》在金庸武学中的定位,是包罗万象的天下武学总纲,拿来对比音视频框架,能当得起的应该只有FFMpeg。
FFMpeg(见图2-10)是由传奇程序员Fabrice Bellard发起的一个开源项目,“FF”的含义是“Fast Forward”,后项目由Michael Niedermayer主持维护,项目主要使用C语言,其授权协议是LGPL,但其中部分代码的授权是GPL。由于数百名贡献者多年持续不断的努力,使当前FFMpeg项目拥有几乎全部常用的图像、视频、音频编解码和文件解析、封装库,以及流媒体协议支持。

图2-10 FFMpeg的Logo
与模块化、组件化设计的其他多媒体框架略有不同的是,FFMpeg更常见的使用方式是直接运行编译完全的命令行工具ffprobe、ffplay、ffmpeg、ffserver等,以及作为功能库整体,被包含到其他软件甚至多媒体框架中。
2.3.1 编译与安装
编译好的FFMpeg程序可从其官网进行下载安装,同时官方也提供源代码的github下载。对于开发者来说,不论是为了使用最新的代码。定制化功能还是选择特定的版本,自己编译源码再安装都是必由之路,而这也十分简单,只需如下3步即可。
1../configure,进行编译选项的设置,可以定义的内容包括安装前缀和希望使用的组件。
2.make,用GNU Make工具,编译生成各种程序和Library。
3.make install,安装所有编译好的程序和Library到预先设置的目录。
在默认情况下,许多库虽然有源代码,却是没有被选择编译的,需要在第一步设置的时候打开对应选项,例如,假设想使用x264来作H.264编码,则第一步是保证在系统内存有相应的Library,在configure时选择--enable-libx264。更进一步,很多情况下,你还需要这些Library的开发包,如果想打开--enable-libmp3lame,需要安装libmp3lame-dev。
安装完成的FFMpeg将包含/bin目录,存放编译好的程序(工具);/include目录,存放.h头文件,供其他程序引用;/lib目录,放置编译生成的Library;/share目录,用于独立系统的内容,例如文档和示范程序。
Library是指一系列程序的集合,与可执行程序的区别在于它不能独立运行。在现代软件开发中它又区分为静态链接和动态链接两种。静态链接库在链接时会将所有内容放到可执行程序里面,而动态链接库可以在可执行文件运行过程中再次载入内存,并且同一动态链接库可以被不同的运行程序同时使用,更多内容可于网上搜索elf或pm文件格式。
2.3.2 FFMpeg工具使用
FFMpeg提供了一系列强大的命令行工具,对许多常规任务调用命令行即可简单完成,能够单独使用,也可以嵌入商业需求的工作流中去,这一节里将简要介绍。
ffprobe是用于检测文件或视频流的信息,并用尽量可读的方式打印出来的工具,当用户只想了解音视频文件的信息而不想真正播放或转码时,ffprobe就可以发挥作用,其语法和示例如下。
·语法

·示例


ffmpeg是用于转码的工具,即将一种格式的文件转成另外一种格式(见图2-11),通过支持filter机制(和DirectShow的Filter概念颇有几分类似,但更多是一种虚拟概念)和搭建Filtergraph,不论使用命令行还是代码,都可以建立复杂的工作流,其语法示例如下。

图2-11 FFMpeg的转码流程(图片来自FFMpeg官网)
·语法

·示例1


·示例2

ffserver提供了简易的流媒体服务器功能,仅需将打算发布的视频文件准备好,在配置文件中进行几行设置,再行启动ffserver,就可以供人访问。通过ffmpeg创建的音视频流可以被ffserver监听并发布出去,在Linux系统中,默认config文件的位置是/etc/ffserver.conf。官网上给出了一些示范,其中发布一个本地的ASF文件所需的设置如下:

2.3.3 运用FFMpeg进行开发
编译完成的FFMpeg主要有以下几个库:libavutil、libavfilter、libavformat、libavcodec、libswscale、libswresample和libavdevice。其中libavformat提供了对文件及音视频流的格式解析与封装(multiplexing&demultiplexing),libavcodec提供了各种音频、视频、字幕等编码和解码功能,可谓FFMpeg框架的核心。
使用libavformat和libavcodec时,处理一个视频文件的步骤大致如下。
首先是引入头文件。

随后开始处理视频文件:

开发者既可以单独部署FFMpeg,让上层的软件或服务可以随时安排启动它进行编解码或文件格式转换等工作,也可以按上述流程所展示的,调用其提供的函数,对工作流程进行帧级或毫秒级别的细微控制。FFMpeg在PC上可以很好地完成工作,在嵌入式设备上也能一展身手,无论软件编解码,还是对Intel、Nvidia硬件的支持,都有全面的支持。除此以外,它还被裁剪编译,嵌入包括DirectShow、Helix以及后文将介绍的GStreamer、VideoLAN在内的其他多媒体框架,发挥巨大作用。但开发者需要注意的是,使用FFMpeg时,应避免违反其授权协议。
最后,无论ffprobe、ffmpeg,还是ffserver,又或是各类命令行参数、模块说明等,均可在官方文档中找到。