给FFmpeg编译AV1编码支持这事听起来就是跑几条命令的事实际动手才发现坑不少。前阵子给一个跨平台系统的视频处理模块加AV1编解码能力核心就是要让FFmpeg在configure阶段识别并启用libaom-av1编解码器。网上能找到的教程多半是让你直接下个现成的静态build版本和依赖不完全可控换个环境就没法复现。我从源码把libaom和FFmpeg都编译了一遍把完整流程、关键参数和踩过的坑整理出来覆盖从环境准备到AV1参数调优的整个链路给需要定制编译FFmpeg的开发者做个实际操作参考。你要做的其实不复杂先编译libaom再让FFmpeg找到它并开启对应开关。整个过程不要求你是编译老手会开终端、能按命令执行就能跟着走。如果你有现成包能用这篇仍值得看完——里面对参数和报错的解释能帮你少走不少弯路。1. 为什么自己编译而不是用一份现成的FFmpeg1.1 现成构建里往往没有libaom-av1大多数Linux发行版自带的FFmpeg默认编解码器列表是严格筛选过的x264、x265这类常见编码器基本都有但libaom经常不在里面。这不是发行版偷懒而是libaom本身体积不小、编译时间长维护者更倾向把这类非默认组件排除在主包外。即便有的发行版后续把libaom加进去了版本也可能滞后。AV1编码器的质量随版本迭代差异很大落后几个版本同样参数下出来的画质和压缩率可能就有明显区别。另外很多团队做视频转码服务时对FFmpeg有额外需求需要自己patch某些滤镜、需要把库装到独立目录、需要同时保留多个版本来回切换、需要针对特定CPU指令集做编译优化。这些需求现成二进制都很难满足。我自己就是因为要在一套离线环境里部署同时还要保证后续能随时升级libaom版本最终只能走源码编译这条最笨也最稳的路。1.2 AV1编码器三选一为什么先碰libaom-av1AV1编码器不止libaom一个SVT-AV1和rav1e也是社区常用的选择三者的定位差异很大。我在确定方案前做过一轮对比简单整理成下面的表编码器定位FFmpeg集成开关典型使用场景libaom-av1AV1参考实现参数语义清晰画质上限高--enable-libaom离线转码、画质优先、兼容性验证SVT-AV1并行化做得很好速度调优空间大--enable-libsvtav1批量生产管线、速度敏感任务rav1e偏研究与实验特性Rust实现--enable-librav1e特性实验、质量对比研究选择libaom-av1并不代表它是唯一解而是因为它作为参考实现参数行为和输出质量最“标准”。出问题时更容易定位到底是用法不对还是编码器自身的问题。一旦这套流程跑通再叠加SVT-AV1做提速也比较自然configure里多一个开关而已。AV1系列编码器普遍比H.264慢这是代价但AV1在同等画质下的码率优势确实明显低码率场景值得投入。2. 编译前的环境准备工具链选型决定成败2.1 四件套编译器、CMake、NASM、pkg-config编译libaom和FFmpeg之前需要确认几个基础工具。GCC/G这套编译器不用多说重点提醒的是CMake版本。libaom的构建脚本对CMake版本有最低要求偏旧的发行版自带CMake可能直接报版本不满足。解决办法是到CMake官网下载新版源码自己装装上以后用cmake --version确认一下避免构建到一半才发现版本问题。NASM是另一个关键依赖。libaom包含大量汇编优化这些汇编代码必须通过NASM编译成机器码。如果系统没装NASM或者版本太老CMake配置阶段会出错或者要等到make阶段才报错。建议装新版本省得后面反复折腾。FFmpeg编译时也需要NASM缺了它configure会静默禁用部分汇编优化编码性能会打折扣这个问题后面章节详细说。pkg-config则是FFmpeg configure阶段查找libaom的关键中介。FFmpeg本身并不会直接扫描所有目录它是靠pkg-config提供aom的编译和链接参数。这个工具通常系统自带但后面需要手动配置PKG_CONFIG_PATH这一步很多人忽略也是绝大多数“明明装了却找不到”问题的根源。2.2 依赖安装与目录规划以Ubuntu类系统为例一键装齐基础工具sudo apt update sudo apt install -y build-essential cmake nasm pkg-config git注意如果发行版自带CMake版本不达标装完这个之后再单独升级CMake。如果你是在内网或离线环境建议提前把所有源码包和依赖的离线包备好编译过程不要边编边联网。再提一下目录规划。我的建议是不要直接装到系统默认目录而是用独立前缀例如libaom装到/opt/aomFFmpeg装到/opt/ffmpeg。这样以后升级、删除、并行维护版本都很方便也不用担心污染系统库。这个习惯在多次编译之后会越来越值钱尤其是当系统里同时存在多个依赖版本时独立前缀能省掉大量冲突问题。3. 编译libaom从源码到动态库3.1 获取源码并固定版本先去AOM官方仓库克隆源码。我习惯把源码目录和构建目录分开例如git clone ${AOM_REPO_URL} aom-src cd aom-src git tag git checkout ${AOM_RELEASE_TAG}${AOM_REPO_URL}换成你的仓库地址${AOM_RELEASE_TAG}选一个最新稳定tag。固定版本很重要。直接跑主线分支看起来是在用最新功能但主线上时不时会有构建配置或汇编层面的临时代码问题稍不留神就卡住。选一个已经过验证的release tag编译成功率会高很多。实际踩坑时我就碰到过主线提交导致CMake配置失败的情况换回release分支立刻正常。3.2 CMake配置参数怎么选在源码目录外新建并行构建目录避免在源码树里混入构建缓存mkdir -p aom-build cd aom-build cmake ../aom-src \ -DCMAKE_INSTALL_PREFIX/opt/aom \ -DCMAKE_BUILD_TYPERelease \ -DENABLE_TESTS0 \ -DBUILD_SHARED_LIBS1这四个参数很重要逐个展开CMAKE_INSTALL_PREFIX决定头文件和库文件装到哪。用/opt/aom是刻意隔离系统目录的做法后面卸载只要删这个目录就干净了。CMAKE_BUILD_TYPERelease启用优化选项。同样的源码Debug和Release编译出来的编码速度差距明显。第一次我图省事没加这个后面压片时速度慢得离谱排查一圈才发现是编译类型的问题。转码场景必须用Release。ENABLE_TESTS0测试代码会显著拖长编译时间。不跑测试就关掉能省不少等待时间。BUILD_SHARED_LIBS1产出共享库。FFmpeg编译时链接动态库之后替换libaom版本无需重新编译FFmpeg。如果做静态部署也可以改成0但动态库更灵活我推荐保持1。配置成功后CMake会输出很多检测信息最后没有报错就进入编译阶段。3.3 编译安装与pkg-config验证make -j$(nproc) sudo make install如果机器核心很多-j$(nproc)能充分利用CPU但要注意内存。make并行度不是越高越好编译进程多到一定程度内存会吃紧出现OOM反而更慢。我一般在内存有限的机器上用make -j4或make -j6。libaom编译一次大概几分钟到十几分钟看机器性能。安装完成后最关键的一步是验证export PKG_CONFIG_PATH/opt/aom/lib/pkgconfig:$PKG_CONFIG_PATH pkg-config --modversion aom能输出版本号说明libaom已被pkg-config正确发现。如果提示找不到先检查/opt/aom/lib/pkgconfig/里是否有aom.pc文件有的话就看PKG_CONFIG_PATH是否拼对没有的话说明你的CMAKE_INSTALL_PREFIX设置和实际路径不一致。还要留意一个细节有些版本的CMake会把pkgconfig文件装到/opt/aom/lib/pkgconfig有些则是lib64/pkgconfig。核对路径时两边都看一下。4. 编译FFmpeg并启用libaom-av1开关4.1 configure前的环境变量设置libaom就绪之后编译FFmpeg前必须让configure阶段能找到它。先设置export PKG_CONFIG_PATH/opt/aom/lib/pkgconfig:$PKG_CONFIG_PATH同时确认NASM在PATH里。FFmpeg的configure会调用nasm来启用x86汇编优化找不到nasm时它会自动禁用相关优化结果也能编译但性能会打折而且没有直接报错很容易被忽略。我建议在configure之前先执行which nasm确认一下。然后获取FFmpeg源码git clone ${FFMPEG_REPO_URL} ffmpeg-src cd ffmpeg-srcFFmpeg版本我建议选最新的release分支避免旧版本对libaom新特性支持不全。4.2 configure参数组合与关键确认针对libaom-av1核心参数是./configure \ --prefix/opt/ffmpeg \ --enable-shared \ --disable-static \ --enable-libaom \ --enable-gpl逐项说明--enable-libaom让FFmpeg的configure自动探测libaom是启用AV1编码器的核心开关。--enable-gpl如果不加FFmpeg里的GPL组件会被排除很多滤镜和编码器直接消失。--prefix/opt/ffmpeg所有二进制和库装到自定义目录避免与系统FFmpeg冲突。--enable-shared推荐用共享库方式对后续排查和更新都友好。如果你还需要x264、x265、fdk-aac等把对应enable参数一并加上。注意不要乱加--enable-nonfree绝大多数AV1场景用不到这个开关加了反而引入额外的许可顾虑。configure执行结束后输出日志里会自动列出检测到的外部库其中应该有一行类似libaom ... yes。这一步一定要亲眼确认是yes再继续make。我就有过一次没注意日志里libaom是no结果make完才发现编码器没编进去回头重跑来浪费了快半小时。用下面命令快速搜索./configure --prefix/opt/ffmpeg --enable-shared --enable-libaom --enable-gpl 21 | grep -i aom4.3 编译安装与编码器验证make -j$(nproc) make install编译FFmpeg的时间会比libaom长一些耐心等。装完后立刻验证编码器是否真的被编进去/opt/ffmpeg/bin/ffmpeg -version /opt/ffmpeg/bin/ffmpeg -encoders 2/dev/null | grep av1 /opt/ffmpeg/bin/ffmpeg -codecs 2/dev/null | grep av1第二种命令应显示libaom-av1编码器第三种命令应显示AV1解码条目。如果什么都没搜到回到configure输出看libaom那行是yes还是no这个排查路径比我见过的大多数网上问题帖子都有效。另外如果系统里已经存在/usr/bin/ffmpeg自编译版本放在/opt/ffmpeg/bin不会覆盖它。我建议在所有用到FFmpeg的脚本里统一使用全路径或者把这个目录放在PATH最前避免哪天调错版本。4.4 运行库路径问题自编译FFmpeg运行时依赖的libaom动态库在/opt/aom/lib这一路径默认不在系统加载器的搜索范围内。直接执行编码命令可能会报ffmpeg: error while loading shared libraries: libaom.so...两个解决方案每次执行前export LD_LIBRARY_PATH/opt/aom/lib:$LD_LIBRARY_PATH或者把/opt/aom/lib写入/etc/ld.so.conf.d/aom.conf后执行sudo ldconfig一劳永逸。我建议选第二种写服务、做部署的时候不依赖临时环境变量出问题概率低很多。首次配好之后后面所有自编译二进制都能直接跑到。5. AV1编码实战libaom-av1参数使用心得5.1 一条能直接用的编码命令编译完成只是第一步AV1编码的参数体系和H.264差别不小。先用一条最稳妥的命令/opt/ffmpeg/bin/ffmpeg -i input.mp4 \ -c:v libaom-av1 -b:v 0 -crf 30 \ -cpu-used 4 -row-mt 1 \ -c:a copy \ output.mkv这条命令里最容易犯的错是漏掉-b:v 0。libaom-av1在FFmpeg里不是默认CRF模式如果不主动把码率设成0它可能按固定VBR方式跑画质表现完全不对。-crf 30表示质量目标数值范围0-63越小质量越高。正常内容用28-34之间都不算离谱动画或者计算机生成图像可以适当放低一些。-cpu-used 4是速度与压缩率的平衡点值越大速度越快但压缩率会下降默认大约是1但那个速度做1080p会等到怀疑人生。离线转码我从4起步快编用6-8。初次测试建议先用一小段素材跑找到能接受的画质和速度组合再铺到全量数据。5.2 并行与分片参数row-mt和tile-columnsAV1的并行编码模型和H.264不太一样需要显式开启两个核心选项-row-mt 1行级多线程。不开启时大部分线程根本用不满编码速度上不去。-tile-columns 2把画面横向切成4块2的2次方并行处理切分更多并行度更高但画质会轻微下降。-tile-rows 2纵向分片一般配合tile-columns使用需要分辨率允许。我常用的1080p组合是-cpu-used 4 -row-mt 1 -tile-columns 2 -tile-rows 2 -threads 8分辨率到4Ktile-columns可以考虑3甚至4。不过分片不是越大越好分片太多会增加重叠和同步开销画质损失也明显具体档位要压一两段样片自己看。此外-threads建议结合实际核心数设置设太高也不会更快反而增加调度开销。5.3 两遍VBR与GOP设置如果对最终文件大小有具体预期走两遍编码更可控ffmpeg -i input.mp4 -c:v libaom-av1 \ -b:v 2M -pass 1 -f null /dev/null ffmpeg -i input.mp4 -c:v libaom-av1 \ -b:v 2M -cpu-used 4 -row-mt 1 \ output.mkv第一遍分析内容分布第二遍按码率分配质量。要注意两遍的-cpu-used等参数保持一致否则可能产生统计偏差。第二遍命令里我故意没写-pass简写实际使用时第二遍写-pass 2即可。两遍编码适合有明确码率上限的交付场景比如平台上传限制或者你给客户承诺了目标文件大小。GOP长度用-g控制。直播和短视频场景我经常设-g 120来降低关键帧开销但编辑场景需要频繁定位建议-g设小一些比如30-60否则拖动时间轴时会出现明显卡顿。5.4 和SVT-AV1搭配使用的场景如果你的FFmpeg同时启用了SVT-AV1可以随时用-c:v libsvtav1对比。我的使用经验很直接批量转码、时间紧张的用SVT-AV1画质要求高、离线转码不着急的用libaom-av1。两者输出都可以用FFmpeg的-psnr和-sse指标做定量对比别凭肉眼瞎猜。实际测试时我会固定源视频、固定分辨率分别用两套编码器压出样本然后用FFmpeg自带工具计算PSNR和SSIM数值。对比结果通常符合预期libaom在低码率下细节保留更好SVT-AV1在相同速度下体积略大。当然具体数值和内容类型、预设档位都强相关建议你们也建立一套自己的评估流程。6. 常见问题与排查实录6.1 configure提示libaom not found这是最频繁出现的问题。原因99%是PKG_CONFIG_PATH没有指向libaom的pkgconfig目录。不要盲目重装libaom先执行find /opt/aom -name aom.pc pkg-config --modversion aom如果文件存在但pkg-config查不到确认PKG_CONFIG_PATH是否拼对、路径下文件是否有效。还有一种少见情况就是你同时装了多个libaom版本pkg-config优先找到了另一个不完整的库。这时候用pkg-config --variableprefix aom查看实际路径必要时把PKG_CONFIG_PATH里的顺序调整一下。6.2 NASM报错或汇编优化静默丢失分两种情况。一种直接报nasm not found好处理安装新版NASM即可。更隐蔽的是configure日志里显示汇编优化被禁用但命令仍然执行成功。检查方式是在FFmpeg configure日志中搜nasm相关内容确保识别到并启用了x86 asm否则后续编码性能会差一大截。libaom的CMake配置阶段如果NASM版本太旧也会出现类似问题这时删掉构建目录重新配置能解决很多隐藏问题。6.3 编码阶段提示Experimental encoder老版本FFmpeg对libaom-av1的默认标记是实验性不添加严格模式参数会直接拒绝编码。解决方法是加-strict -2新版FFmpeg已经解除这个限制但保留这个参数不影响使用。如果是从老版本升级上来的脚本这个参数可以一直带。我遇到过一个生产脚本里始终带着-strict -2刚开始以为是多余参数试着删掉后在新版本上没问题但后来有人拿同一个脚本回滚到旧版本就报错了。所以脚本和版本绑定很重要别轻易动已有参数。6.4 运行时报动态库缺失前面提过的libaom.so找不到问题本质是动态链接器的搜索路径不含/opt/aom/lib。设置LD_LIBRARY_PATH只能临时解决建议写入/etc/ld.so.conf.d/并执行ldconfig。我遇到过部署到另一台机器时漏了这一步服务起不来排查半天才意识到新机器没有配置库路径。建议在部署清单里显式加上这一步或者用ldd /opt/ffmpeg/bin/ffmpeg | grep aom提前检查。6.5 编码速度过慢怎么定位瓶颈先确认是不是没开-row-mt 1其次看-cpu-used是否太低。再用ffmpeg -i input.mp4 -c:v libaom-av1 -f null -检查纯编码速度。如果线程利用率上不去tile参数也要调整。最后检查CPU降频和散热AV1编码压力很大笔记本经常因为温度墙掉速台式机也要注意供电。另外如果输入分辨率很大建议先做分辨率缩放编码耗时能少一大截别让编码器去处理多余的像素。6.6 同一脚本在不同机型上输出不一致不同libaom版本之间编码质量差异很明显。项目里如果对编码结果有稳定性要求一定要把libaom和FFmpeg版本同时固定下来并用ffmpeg -version记录到日志。版本漂移是实际编码服务里最隐蔽但最伤人的问题某些线上文件突然体积变大、画质异常往往不是参数问题而是某个依赖被悄悄升级了。我个人在多次编译之后养成一个习惯把每次configure执行后的完整日志单独留一份尤其是里面搜得到libaom、nasm等关键依赖的检查结果。下次升级FFmpeg或者换机器部署时拿旧日志一对照能少排查很多问题。再补一句实在话——源码编译FFmpeg和AV1支持这个过程第一次跑通之后第二次会快很多别被网上各种报错贴吓住按顺序来先确保libaom本身被pkg-config识别到后面基本就是一路平趟。