大家好,欢迎来到停止重构的频道。
本期我们讨论FFmpeg。
这里先提一个问题,FFmpeg命令行功能如此强大,为什么还需要舍近求远地调用库函数呢 ?
我们按这样的顺序讨论 :
1、 FFmpeg命令行说明
2、 FFmpeg代码结构
3、 FFmpeg编译安装
FFmpeg命令行说明
FFmpeg命令行可快速实现音视频处理,几乎囊括所有音视频处理的功能。
常用的FFmpeg命令行如图所示,包括查看支持的编解码器、转封装、转码、文件直播推流等。
另外,FFmpeg也提供FFprobe工具,用于查看文件、轨道信息、打印每帧信息等。
FFmpeg命令行大致上与音视频处理过程对应。
大概分为5部分:前置参数、输入文件及参数、原始帧filter处理设置、编码设置、输出文件及参数。
官网有相关参数的详细说明和例子,一般对音视频处理过程了解的话,则相关参数是比较好查找的,例如需要画中画合并多个视频,则在video filter中可找到layout设置。
如果是新手,由于FFmpeg功能过于庞杂,从头开始看说明并不现实。
更推荐先在网上搜索答案,然后再查看官方对应说明,久而久之就会对很多设置有印象。
FFmpeg代码结构
在讨论FFmpeg代码结构之前,我们需要说明开篇的问题。
为什么FFmpeg命令行功能这么强大,还需要调用它的库函数,舍近求远地重新实现功能呢?
这是因为FFmpeg的命令行虽然强大,但是对于一些异常处理,如直播拉流中断重试就无法实现。
另外,一些复杂功能,如直播中断补充默认帧、地图画面接入等场景,命令行也是无法实现的。
所以如果希望做一个稳定或功能较复杂的音视频处理软件,更推荐调用FFmpeg的库函数,而非直接使用FFmpeg命令行。
FFmpeg的代码结构基本是对应音视频处理过程的,音视频处理过程可参考往期《视频转码》 。
如图所示,封装处理,对应库函数基本都在libavformat中;编解码处理,对应库函数基本都在libavcodec中;原始帧filter处理,对应库函数基本都在libavfilter 中。
官网、源码中都有每个库函数的说明,但是,通读FFmpeg的代码并不现实,且有很多说明第一次看是非常模糊的。
在刚开始的时候,最好参考对应的sample代码,然后再看对应库函数说明。
深入后,可以参考FFmpeg命令行,在对应函数中设置相关参数。
另外,ffmpeg命令行、ffprobe、ffplay的代码也在源码中,必要时可以参考。
当然,网上也有很,FFmpeg代码分析,但由于版本差异,可能没有什么参考价值,所以最好还是看官方sample代码,必要时再追查源码。
FFmpeg编译安装
网上有很多详细的教程,且不同版本的FFmpeg编译及相关设置有所区别,所以这里仅做概括性的说明。
如果仅仅是使用FFmpeg常规命令行,可以从官网下载对应平台编译好的包。
如果是需要自定义裁剪FFmpeg ,增加编解码器、开启动态库、开启硬件编解码等,则需要下载源码进行编译安装。
以Ubuntu22.04为例,编译过程一般分为三步:安装基础依赖、配置和编译安装、设置环境变量。
第一步,安装基础依赖,最基础的依赖只有3个,但是如果需要其他功能,如h265编解码,则需要安装对应的软件。
第二步,配置和编译安装,如果没有特殊要求,最好用最新的版本。
通过configure可进行编译设置,如果需要支持额外的功能,这里需要一一配置,通过./configure --help,可以查看可设置的项。
配置完后通过编译命令编译安装即可。
第三步,设置环境变量,如果是docker运行,需要在启动命令加上环境变量设置。
安装完毕后 ffmpeg、ffprobe等工具即可使用,相关动态库的函数也可以被调用。
顺便一提,追加编解码器等功能是常有的事情,但是每次都需要重新编译安装FFmpeg。
因此更推荐使用动态库,而非把静态库编译进自己的程序,这样FFmpeg重新编译并不影响自己的程序。
总结
最后,本期内容只对FFmpeg做了浅显的介绍,很多人会抱怨FFmpeg过于复杂,库函数说明也不那么清晰,很多时候都得翻看源码,
可能原因在于音视频本身比较复杂,且处理过程也会有很多细节问题。不过,随着我们后续内容的深入,很多问题都会明了的。