音视频开源库:多媒体框架的 FFmpeg,有哪些属性?
FFmpeg 简介
FFmpeg 是领先的多媒体框架,是一个强大的处理音视频的开源库,能够解码、编码、转码、混流、流媒体分离、滤镜和播放几乎所有格式的音视频内容;它既可以使用 API 对音视频进行处理,也可以使用 FFmpeg 命令编辑音视频文件
- 包含用于音频、视频和字幕流的多个解码器和编码器,以及多个位流过滤器
那么对于一个音视频文件,都有哪些属性呢?我们可以通过 ffmpeg-i 命令查看媒体文件的信息
» ffmpeg -i r1ori.mp4
ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers
built with Apple LLVM version 10.0.0 (clang-1000.10.44.4)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gpl --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-chromaprint --enable-frei0r --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfdk-aac --enable-libfontconfig --enable-libfreetype --enable-libgme --enable-libgsm --enable-libmodplug --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-librsvg --enable-librtmp --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtesseract --enable-libtwolame --enable-libvidstab --enable-libwavpack --enable-libwebp --enable-libzmq --enable-opencl --enable-openssl --enable-videotoolbox --enable-libopenjpeg --disable-decoder=jpeg2000 --extra-cflags=-I/usr/local/Cellar/openjpeg/2.3.0/include/openjpeg-2.3 --enable-nonfree
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Duration: 00:00:58.53, start: 0.000000, bitrate: 1870 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1732 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default)
Metadata:
handler_name : SoundHandler
除了视频的元信息,还包括了更多我们当初编译的配置,你可以选择 -hide_banner 参数来隐藏这些信息,完整的命令如下:
»ffmpeg -i r1ori.mp4 -hide_banner
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.20.100
Duration: 00:00:58.53, start: 0.000000, bitrate: 1870 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1732 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default)
Metadata:
handler_name : SoundHandler
At least one output file must be specified
我们主要看几个数据:
- Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4': # Input #0 表示我们通过 ffmpeg -i 参数输入的第一个文件,下标从0开始,也就是说我们可以输入多个文件,实际上 ffmpeg 还支持输出多个文件
- Metadata 表示视频元信息
- Duration 这行包含了视频的播放时长是58.53秒,开始播放时间是0,整个文件的比特率是1870kbit/s
- Stream #0:0(und): Video: h264,这行表示该文件的第一个流是视频流,编码格式是H264格式(封装格式为AVC1),每一帧的数据表示为yuv420p,分辨率为544x960,视频流的比特率是1732kbit/s,帧率为每秒钟29.83帧。
- Stream #0:1(und): Audio: aac,这行表示该文件的第二个流是音频流,编码格式为ACC(封装格式为MP4A),并且采用的Profile是LC规格,采样率是44.1KHz,声道是立体声(stereo),码率是129kbit/s
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 进行举例;假设已经交叉编译出了 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 调用的方式进行使用
FFmpeg 组成
构成 FFmpeg 主要有两个部分
1、工具软件
这一部分是编译好的程序,包括: ffmpeg.exe,ffplay.exe,ffserver.exe 和 ffprobe.exe
-
ffmpeg.exe: 音视频转码、转换器
ffplay.exe:简单的音视频播放器
ffserver.exe:流媒体服务器
ffprobe.exe:简单的多媒体码流分析器
2、库文件部分
这一部分是可以供开发者使用的 SDK,为各个不同平台编译完成的库;上面的四个工具软件都是完整成品形式,那么这些库就其组成部分,可以根据自己的需求使用这些库开发自己的应用程序;这些库有:
- libavcodec: 包含音视频编码器和解码器
- libavutil: 包含多媒体应用常用的简化编程的工具,如随机数生成器、数据结构、数学函数等功能
- libavformat: 包含多种多媒体容器格式的封装、解封装工具
- libavfilter: 包含多媒体处理常用的滤镜功能
- libavdevice: 用于音视频数据采集和渲染等功能的设备相关
- ibswscale: 用于图像缩放和色彩空间和像素格式转换功能
- libswresample: 用于音频重采样和格式转换等功能
总结
FFmpeg 是一个强大的专门音视频处理的库,很多播放器都是基于 FFmpeg 进行的开发;文章所提的功能只是罗列了 FFmpeg 可使用功能的一部分,更多 FFmpeg 相关的学习资料;可点击此处查看获取方式 或者简信发送"音视频进阶",即可获取一份高级音视频学习手册;希望这份手册能够给大家学习音视频带来一些帮助
好了,以上就是今天要分享的内容,大家觉得有用的话,可以点赞分享一下;如果文章中有什么问题欢迎大家指正;欢迎在评论区或后台讨论哈~