基础概念

容器格式(Container Format)

容器格式又称封装格式,用于封装视频、音频、字幕、元数据(标题、章节信息等)等各种流媒体内容,容器决定了文件的扩展名。

常见的容器格式:

容器格式说明
mp4支持多种编解码器,广泛用于互联网和移动设备
mkv支持多轨音频、字幕,灵活性强,常用于高清电影和视频
avi支持功能有限,但兼容性强
mov苹果格式,主要用于QuickTime
flvFlash流媒体,现在使用较少
webm由Google提出,专为web视频流设计,轻量且开放
ogg免费、无专利限制、高质量的音频压缩格式

编码格式(Codec)

编码格式也称编解码器(Codec,Compressor/Decompressor),是对音视频数据进行压缩和解压缩的技术。编码器将原始多媒体数据压缩为更小的文件,以便于存储和传输,而解码器则负责将压缩的数据还原为可播放的音频或视频。

常见的视频编码格式:

编码格式说明
H.264 (AVC)最常用的压缩标准,广泛用于网络流媒体、蓝光等
H.265 (HEVC)H.264的升级版,压缩效率更高,适用于4K、8K视频
MPEG-4早期的压缩标准,主要用于流媒体和在线视频
VP9Google开发的开源编解码器,常用于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-gpllibx264采用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

标签: none

添加新评论