本文章是阅读《音视频开发进阶指南基于android与ios平台的实践》一书的学习笔记。
目录:
- FFmpeg 的介绍
- FFmpeg Android 编译库
- FFmpeg 的结构
- FFmpeg 命令行工具的使用
1. FFmpeg 的介绍
http://ffmpeg.org
若要讲解音视频的开发,首先不得不提开源框架 FFmpeg。该开源框架为音视频开发者们提供了非常大的帮助,其也是全世界的音视频开发工程师都应该掌握的工具。
FFmpeg 是一套可以用来记录、处理数字音频、视频,并将其转换为流的开源框架,提供了录制、转换以及流化音视频的完整解决方案。
它的可移植性或者说跨平台特性非常强大,可以用在 Linux 服务器、PC (包括 Windows、Mac OS X 等)、移动端设备 (Android、iOS 等移动设备) 等平台。
名称中的 mpeg 来自视频编码标准 MPEG,而前缀 FF 是 Fast Forward 的首字母缩写。本章会从编译开始讲解,然后介绍命令行工具的使用,接着会介绍 FFmpeg 在代码层面提供给开发者的 API,最后会从源码的角度分析一下整个 FFmpeg 框架。
2. FFmpeg Android 编译库
FFmpeg github 上已经有现成编译好的 android 库:https://github.com/xufuji456/FFmpegAndroid,简介如下:
android 端基于 FFmpeg 库的使用,添加编译 ffmpeg、shine、mp3lame、x264 源码的参考脚本,目前音视频相关处理:
- 音频剪切、拼接
- 音频混音
- 音频转码
- 音视频合成
- 音频抽取
- 音频解码播放
- 音频编码
- 视频抽取
- 视频剪切
- 视频转码
- 视频截图
- 视频降噪
- 视频抽帧
- 视频转 GIF 动图
- 视频添加水印
- 视频画面拼接
- 视频反序倒播
- 视频画中画
- 图片合成视频
- 视频解码播放
- 本地直播推流
- 实时直播推流
- 音视频解码播放
- FFmpeg 的 AVFilter 滤镜
- 使用 mp3lame 库进行 mp3 转码
- 视频拖动实时预览
- moov 往前移动
- ffprobe 检测多媒体格式
- IjkPlayer 的 RTSP 超低延时直播
3. FFmpeg 的结构
默认的编译会生成 4 个可执行文件和 8 个静态库。可执行文件包括用于转码、推流、Dump 媒体文件的 ffmpeg、用于播放媒体文件的ffplay、用于获取媒体文件信息的 ffprobe,以及作为简单流媒体服务器的 ffserver。8 个静态库其实就是 FFmpeg 的 8 个模块,具体包括如下内容:
- AVUtil:核心工具库,该模块是最基础的模块之一,下面的许多其他模块都会依赖该库做一些基本的音视频处理操作。
- AVFormat:文件格式和协议库,该模块是最重要的模块之一,封装了 Protocol 层和 Demuxer、Muxer 层,使得协议和格式对于开发者来说是透明的。
- AVCodec:编解码库,该模块也是最重要的模块之一,封装了 Codec 层,但是有一些 Codec 是具备自己的 License 的,FFmpeg 是不会默认添加像 libx264、FDK-AAC、lame 等库的,但是 FFmpeg 就像一个平台一样,可以将其他的第三方的 Codec 以插件的方式添加进来,然后为开发者提供统一的接口。
- AVFilter:音视频滤镜库,该模块提供了包括音频特效和视频特效的处理,在使用 FFmpeg 的 API 进行编解码的过程中,直接使用该模块为音视频数据做特效处理是非常方便同时也非常高效的一种方式。
- AVDevice:输入输出设备库,比如,需要编译出播放声音或者视频的工具 ffplay,就需要确保该模块是打开的,同时也需要 libSDL的预先编译,因为该设备模块播放声音与播放视频使用的都是 libSDL 库。
- SwrRessample:该模块可用于音频重采样,可以对数字音频进行声道数、数据格式、采样率等多种基本信息的转换。
- SWScale:该模块是将图像进行格式转换的模块,比如,可以将 YUV 的数据转换为 RGB 的数据。
- PostProc:该模块可用于进行后期处理,当我们使用 AVFilter 的时候需要打开该模块的开关,因为 Filter中 会使用到该模块的一些基础函数。
如何为 FFmpeg 平台引入第三方编解码库呢?下面就以最常用的 LAME、X264、FDK-AAC 进行举例。前面的章节中已经介绍了这三个库在 Android 和 iOS 平台上的交叉编译,现在就假设已经交叉编译出了 LAME、X264、FDK-AAC 的静态库与头文件,并且在 FFmpeg 的源码目录下建立了 external-libs 目录,还在其中建立了 LAME、X264、FDK-AAC 三个目录,每个目录中的结构都包含了 include 和 lib两个目录,并且将编译出来的头文件和静态库文件分别都放到了这两个目录下面。
现在修改编译脚本如下:
新增 X264 编码器需要新增以下脚本:
--enable-muxer=h264 \
--enable-encoder=libx264 \
--enable-libx264 \
--extra-cflags=”-Iexternal-libs/x264/include” \
--extra-ldflags=”-Lexternal-libs/x264/lib” \
新增 LAME 编码器需要新增以下脚本:
--enable-muxer=mp3 \
--enable-encoder=libmp3lame \
--enable-libmp3lame \
--extra-cflags=”-Iexternal-libs/lame/include” \
--extra-ldflags=”-Lexternal-libs/lame/lib” \
新增FDK-AAC编码器需要新增以下脚本:
--enable-encoder=libfdk_aac \
--enable-libfdk_aac \
--extra-cflags=”-Iexternal-libs/fdk-aac/include” \
--extra-ldflags=”-Lexternal-libs/fdk-aac/lib” \
可以按照自己的应用场景,把需要编译进来的第三方库以修改脚本文件的方式进行编译,然后以命令行模式或者以API调用的方式进行使用。
4. FFmpeg 命令行工具的使用
FFmpeg 中有 ffmpeg、ffprobe、ffplay以及 ffserver 等命令行工具,这边将重点介绍 ffmpeg、ffprobe 与 ffplay 这三个命令行工具,而ffserver 则是作为简单的流媒体服务器存在的,与客户端开发关系不大。
- ffmpeg 是进行媒体文件转码的命令行工具;
- ffprobe 是用于查看媒体文件头信息的工具;
- ffplay 则是用于播放媒体文件的工具。
4.1 ffprobe