基础概念
容器格式(Container Format)
容器格式又称封装格式,用于封装视频、音频、字幕、元数据(标题、章节信息等)等各种流媒体内容,容器决定了文件的扩展名。
常见的容器格式:
| 容器格式 | 说明 |
|---|
| mp4 | 支持多种编解码器,广泛用于互联网和移动设备 |
| mkv | 支持多轨音频、字幕,灵活性强,常用于高清电影和视频 |
| avi | 支持功能有限,但兼容性强 |
| mov | 苹果格式,主要用于QuickTime |
| flv | Flash流媒体,现在使用较少 |
| webm | 由Google提出,专为web视频流设计,轻量且开放 |
| ogg | 免费、无专利限制、高质量的音频压缩格式 |
编码格式(Codec)
编码格式也称编解码器(Codec,Compressor/Decompressor),是对音视频数据进行压缩和解压缩的技术。编码器将原始多媒体数据压缩为更小的文件,以便于存储和传输,而解码器则负责将压缩的数据还原为可播放的音频或视频。
常见的视频编码格式:
| 编码格式 | 说明 |
|---|
| H.264 (AVC) | 最常用的压缩标准,广泛用于网络流媒体、蓝光等 |
| H.265 (HEVC) | H.264的升级版,压缩效率更高,适用于4K、8K视频 |
| MPEG-4 | 早期的压缩标准,主要用于流媒体和在线视频 |
| VP9 | Google开发的开源编解码器,常用于YouTube视频 |
| AV1 | 更先进的开源编解码器,旨在取代H.265和VP9 |
容器格式和编码格式密切相关,但职责不同。容器负责封装和管理音视频、字幕等数据,编码格式负责压缩和解压实际的音视频数据。
同一容器可以支持多种编码格式。例如mp4容器可以使用H.264、H.265等不同的编解码器,mkv容器支持H.264、VP9等多种音视频编码。
安装编译环境
nasm/yasm
nasm/yasm都是汇编编译器,yasm是从nasm的基础上开发出来的,属于同宗,使用了相同的语法,所以nasm的代码可以用yasm编译。yasm对nasm一些不合理的地方进行了改良。但yasm更新较慢,而nasm更新较快,能支持更新的指令集,而且还支持Gas语法和AMD64(EM64T)架构,跨平台,支持多种目标文件格式。在Window平台上,fasm支持最好。
必须安装nasm/yasm,否则会报错:nasm/yasm not found or too old. Use --disable-x86asm for a crippled build.。
nasm下载地址:https://www.nasm.us/pub/nasm/releasebuilds/
[root@ecs ~]# yum install -y gcc
[root@ecs ~]# tar -xvf nasm-2.15.05.tar.gz && cd nasm-2.15.05
[root@ecs nasm-2.15.05]# ./configure && make && make install
nasm和yasm二者安装其一即可,但由于x265 2.6版之后,只能使用nasm 2.13或更高版本编译,因此如果要安装x265 2.6之后的版本就只能选择nasm。
安装媒体开发库
SDL
SDL是一套开源的跨平台多媒体开发库,专注于提供图形、音频和输入设备的访问。SDL主要用于:
- 图形显示:提供对窗口、渲染器和纹理的控制,用于显示图像或视频;
- 音频输出:处理和播放音频数据;
- 输入处理:管理键盘、鼠标等输入设备。
SDL通常和ffmpeg搭配使用,可以实现功能上的互补。ffmpeg主要负责音视频解码,再由SDL负责将视频原始帧数据显示到屏幕,将解码后的音频数据输出到扬声器。在需要实时处理和播放的音视频应用中,ffmpeg解码后的数据通过SDL进行渲染和播放。
编译ffmpeg的时候加上参数--enable-ffplay即可生成ffplay。
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar -zxvf SDL2-2.0.20.tar.gz && cd SDL2-2.0.20
[root@ecs SDL2-2.0.20]# ./configure && make -j 16 && make install
注:SDL只有在生成ffplay时才是必须的,如果不需要编译ffplay则忽略SDL。
安装依赖库
libmp3lame
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar xzvf lame-3.100.tar.gz && cd lame-3.100
[root@ecs src]# ./configure --enable-nasm && make && make install
ffmpeg不支持mp3编码,因此需要依赖libmp3lame实现编码功能,但ffmpeg支持mp3解码,因此无需安装libMAD。
xvid
xvid是一个开放源代码的MPEG-4(Moving Picture Experts Group-4 Part 2)视频编解码器。与x264相比,相同质量下,x264压缩的视频体积更小。
下载地址:https://downloads.xvid.org/downloads/xvidcore-1.3.7.tar.gz
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar -zxvf xvidcore-1.3.7.tar.gz && cd xvidcore/build/generic
[root@ecs src]# ./configure && make && make install
libx264
H.264(AVC),全称MPEG-4 Part 10或Advanced Video Coding(AVC),是由ITU-T的视频编码专家组(VCEG)和ISO/IEC的动态图像专家组(MPEG)联合制定的视频编码标准。ITU-T称为H.264,ISO/IEC则归纳与MPEG系列,称为MPEG-4 Part 10,另一个代称是MPEG-4 AVC。
x264是一个开源的H.264/MPEG-4 AVC视频编码库,是最好的有损视频编码器之一。
下载地址:https://www.videolan.org/developers/x264.html
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar -zxvf x264-master.tar.gz && cd x264-master
[root@ecs src]#./configure --enable-shared --enable-static --disable-asm
[root@ecs src]#make && make install
libx265
H.265又称High Efficiency Video Coding(HEVC),是H.264的升级版。
x265是一个开源的H.265视频编码库。
下载地址:https://www.videolan.org/developers/x265.html
x265需要CMake 2.8.8或更高版本,yum的cmake版本为2.8.12,因此直接yum安装即可。
[root@ecs ~]# yum install -y gcc-c++ cmake numactl-devel
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar -zxvf x265_4.0.tar.gz
[root@ecs src]# cd x265_4.0/build/linux
[root@ecs linux]# sed -i 's/string(SUBSTRING "\${X265_REVISION_ID}" 0 12 X265_REVISION_ID)/set(X265_LATEST_TAG "4.0")\n set(X265_TAG_DISTANCE "23")\n set(X265_REVISION_ID "487105d")\n string(SUBSTRING "\${X265_REVISION_ID}" 0 7 X265_REVISION_ID)/g' /usr/local/src/x265_4.0/source/cmake/Version.cmake
[root@ecs linux]# cmake -G "Unix Makefiles" ../../source
[root@ecs linux]# make -j$(nproc) && make install
常见报错:
- 报错:CMake Error: your CXX compiler: "CMAKE_CXX_COMPILER-NOTFOUND" was not found.,解决方法:安装
gcc-c++。 - 报错:Could NOT find nasm,解决方法:安装
nasm。 - 报错:Could NOT find NUMA (missing: NUMA_ROOT_DIR NUMA_INCLUDE_DIR NUMA_LIBRARY),解决方法:安装
numactl-devel。
注:ffmpeg自身支持H.264和H.265的解码,因此无需安装其它解码器。
libvpx
VP8是google定义并开源的视频编解码标准和编解码库实现。
MPEG系列格式商用需要缴纳授权费用,因此Google和On2 Technologies制定了VP8,并在收购On2 Technologies之后将VP8开源(BSD授权),使其成为可免费授权使用的高品质视频编码格式。
VP8号称比H.264编码性能更好,实际上没那么夸张,差不多相当于ffmpeg内置默认的openh264编解码库。VP8的压缩实现与H.264有点区别就是VP8没有B帧,而H.264有B帧。
VP8的优点是开源,没有H.264/H.265的专利版权风险,除了IE9以下版本的浏览器外,现代浏览器都支持VP8视频编码,即webm视频格式。
VP9也是google开源的,用于比拼H.265(HEVC)的编解码器。兼容性方面,除了IE9以下版本的浏览器外,现代浏览器都支持VP9视频编码。
libvpx是WebM项目的子库,可以同时支持VP8和VP9视频编码。
下载地址:https://github.com/webmproject/libvpx/archive/v1.11.0/libvpx-1.11.0.tar.gz
[root@ecs ~]# yum install -y perl
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar -zvxf libvpx-1.11.0.tar.gz && cd libvpx-1.11.0
[root@ecs src]# ./configure --enable-shared && make && make install
aac
AAC全称Advanced Audio Coding,高级音频编码。是目前最常用的一种音频编码格式,与MP3相比,AAC是一种编码效果更好,编码音质更高的音频编码格式,常见的使用AAC编码后的文件存储格式为m4a。
ffmpeg可以调用的AAC编码器主要有:
- aac:ffmpeg自带的aac编码器;
- libfaac:第三方aac编码器,faac是aac音频编码库,可将pcm音频编码为aac格式。faad是aac音频解码库,可将aac格式数据解码为pcm数据;
- libfdk_aac:第三方aac编解码器。
libfaac和libfdk_aac为非GPL协议,所以在预编译时需采用nonfree支持。
性能对比:libfdk_aac > aac > libfaac,新版ffmpeg已经弃用了--enable-libfaac,因此只能选择libfdk_aac。
fdk-aac下载地址:https://downloads.sourceforge.net/opencore-amr/fdk-aac-2.0.1.tar.gz
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar xzvf fdk-aac-2.0.1.tar.gz && cd fdk-aac-2.0.1
[root@ecs src]# ./configure && make && make install
ogg
Ogg是一种流式容器格式,提供对流式数据进行分割、存储、排序、按时间顺序查找以及检查数据丢失的框架。Ogg格式主要采用Vorbis/Opus编码格式。
Vorbis是Xiph.Org基金会为了对抗MP3收费音频格式而推出的一种有损压缩音频编码格式,支持多通道。它完全免费、开放且没有专利限制。
libvorbis是Vorbis的编解码库,下载地址:https://www.xiph.org/downloads/。
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar -xzvf libogg-1.3.5.tar.gz && cd libogg-1.3.5
[root@ecs libogg-1.3.5]# ./configure && make && make install
[root@ecs libogg-1.3.5]# echo /usr/local/lib >> /etc/ld.so.conf; ldconfig
[root@ecs libogg-1.3.5]# cd /usr/local/src
[root@ecs src]# tar -zxvf libvorbis-1.3.7.tar.gz && cd libvorbis-1.3.7
[root@ecs libvorbis-1.3.7]# ./configure && make && make install
[root@ecs libvorbis-1.3.7]# echo export PKG_CONFIG_PATH="\$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" >> /etc/profile
[root@ecs libvorbis-1.3.7]# source /etc/profile
libvorbis依赖于libogg,安装完libogg后,需要配置ld.so.conf,否则会报错:configure: error: must have Ogg installed!。
安装好libvorbis后,还需要配置PKG_CONFIG_PATH,否则编译ffmpeg时会报错:ERROR: vorbis not found using pkg-config。
或者直接安装libvorbis-devel(自动安装libogg-devel)。
Vorbis在中高码率时优势明显,低码率时效果不佳。Xiph.Org随后开发了Speex有损压缩音频格式,专攻低码率语音,适用于视频通话、游戏聊天、有声读物等。
后来Xiph研发CELT技术(继承自Vorbis的MDCT)以改进Speex,互联网工程任务组(IETF)将CELT和Skype公司的SILK(LP线性预测)这两个技术集成为Opus。Opus是一个完全开源、免费、通用性高的音频编解码器,由Xiph和Skype合作开发,8kHz以下(语音)用LP,8~20kHz用MDCT,强强联手,无缝切换,不仅音质极佳,而且适用范围广。
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# tar -zxvf opus-1.3.1.tar.gz && cd opus-1.3.1
[root@ecs opus-1.3.1]# ./configure --disable-static && make && make install
或者直接安装opusfile-devel(自动安装libogg-devel和opus-devel)。
flac
FLAC既是一个容器格式,也是一个编码格式。是目前最快、支持最广泛的无损音频格式,也是唯一一个开源无专利的无损音频格式。FLAC原为Josh Coalson发起的项目,后并入Xiph.Org基金会。ffmpeg支持flac的编解码,无需安装编解码库。
安装FFmpeg
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# yum install -y bzip2
[root@ecs src]# tar -jvxf ffmpeg-7.0.2.tar.bz2 && cd ffmpeg-7.0.2
[root@ecs ffmpeg-7.0.2]# ./configure --prefix=/usr/local/ffmpeg \
--enable-ffplay --enable-libmp3lame \
--enable-libfdk-aac --enable-nonfree \
--disable-static --enable-shared \
--enable-libx264 --enable-libx265 --enable-gpl --enable-version3 \
--enable-libvpx --enable-libxvid
[root@ecs ffmpeg-7.0.2]# make -j$(nproc) && make install
[root@ecs ffmpeg-7.0.2]# cat >> /etc/profile << EOF
export PATH=\$PATH:/usr/local/ffmpeg/bin
LD_LIBRARY_PATH=/usr/local/ffmpeg/lib:/usr/local/lib:\$LD_LIBRARY_PATH
EOF
[root@ecs ffmpeg-7.0.2]# source /etc/profile
编译参数说明:
| 参数 | 说明 |
|---|
| --prefix | 安装目录 |
| --enable-debug | 打开debug模式 |
| --disable-static --enable-shared | 编译成动态库,默认编译成静态库 --disable-static:禁止编译静态链接库(.a或.lib) --enable-shared:编译动态链接库(.so、.dll或.dylib) |
| --enable-ffplay | 生成ffplay(默认编译不带ffplay),必须先安装SDL,否则即使--enable-ffplay也无法生成ffplay |
| --enable-libx264 --enable-gpl | libx264采用GPL协议,所以用到libx264的ffmpeg必须gpl |
| --enable-version3 | 启用LGPLv3(GNU Lesser General Public License version 3)许可,必须先--enable-gpl |
| --enable-filter=delogo | 启用去水印滤镜 |
| --enable-libfdk-aac --enable-nonfree | 使用libfdk-aac库进行aac编解码 fdk-aac使用非自由许可证,与GPL不兼容,必须添加--enable-nonfree,生成的FFmpeg(库或二进制文件)不可公开分发 |
必须将/usr/local/ffmpeg/lib目录加入环境变量LD_LIBRARY_PATH中,否则在使用ffmpeg的过程中就会出现类似cannot open shared object file: No such file or directory这样的报错。
如果需要避免运行时依赖,须要同时设置:--enable-static --disable-shared。
注:只设置--enable-static而不设置--disable-shared,ffmpeg会同时生成.a和.so,默认情况下gcc链接时优先使用.so,导致ffmpeg仍是动态链接的。
常见报错
ffmpeg: error while loading shared libraries: libavdevice.so.61: cannot open shared object file: No such file or directory。
此类报错一般会出现在--enable-shared方式编译的情况下。
查看ffmpeg依赖
[root@ecs ~]# ldd /usr/local/ffmpeg/bin/ffmpeg
linux-vdso.so.1 => (0x00007ffcd1fbb000)
libavdevice.so.61 => not found
libavfilter.so.10 => not found
libavformat.so.61 => not found
libavcodec.so.61 => not found
libpostproc.so.58 => not found
libswresample.so.5 => not found
libswscale.so.8 => not found
libavutil.so.59 => not found
libm.so.6 => /lib64/libm.so.6 (0x00007fb088914000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb0886f8000)
libc.so.6 => /lib64/libc.so.6 (0x00007fb08832a000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb088c16000)
发现很多都是not found,查找libavdevice.so.59共享库:
[root@ecs ~]# find / -name libavdevice.so
/usr/local/ffmpeg/lib/libavdevice.so
/usr/local/ffmpeg/lib/存在libavdevice.so,但为什么还提示not found呢?
ffmpeg在调用动态链接库时,会到系统默认的动态链接库路径下查找,查看系统默认的动态链接库路径:
[root@ecs ~]# ld --verbose | grep SEARCH
SEARCH_DIR("=/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
返回的路径中并没有/usr/local/ffmpeg/lib/,因此就无法找到libavdevice.so了。解决方法只需将/usr/local/ffmpeg/lib/添加到动态链接库路径即可。
[root@ecs ~]# echo export LD_LIBRARY_PATH="/usr/local/ffmpeg/lib:/usr/local/lib:\$LD_LIBRARY_PATH" >> /etc/profile
[root@ecs ~]# source /etc/profile
或者:
[root@ecs ~]# echo "/usr/local/ffmpeg/lib" >> /etc/ld.so.conf; ldconfig