Ubuntu 20.04 源码编译 FFmpeg 全流程详解:依赖安装与错误排查
坐电脑前帮人排查FFmpeg编译问题前前后后少说也有几十次了。每次群里有人发截图说“configure报错”“make失败了”我扫一眼基本就能猜到缺哪个依赖。说真的Ubuntu 20.04 编译安装 FFmpeg 这件事难点不在命令有多复杂而在于很多人不知道每个步骤到底在干嘛一旦报错就抓瞎。这篇就把整个流程从头到尾拆开讲清楚你照着操作顺便把原理也搞明白以后再遇到类似开源项目编译思路都是通的。废话不多说直接进入正题。这篇内容适合刚接触Linux、第一次碰FFmpeg源码的初学者也适合那种“项目需要自定义编解码器被迫自己编译FFmpeg”的老哥参考。1. 为什么源码编译而不是直接 apt install1.1 发行版自带 FFmpeg 的局限很多人的第一反应是Ubuntu 不是有 apt 吗sudo apt install ffmpeg一条命令不就搞定了确实能装而且能用但这里有几个很实际的问题。第一版本旧。Ubuntu 20.04 的软件源里默认是 FFmpeg 4.2.x这是 2020 年左右发布的版本。放到现在很多新编码器、新滤镜、新的封装格式支持都没有。比如你项目里想用 AV1 编码或者想用新版 libvpx 的 VP9 性能优化apt 装的老版本基本指望不上。第二编解码器不全。FFmpeg 本身是“壳”真正的编码能力很大程度依赖外部库比如 libx264、libx265、libfdk-aac 这些。Ubuntu 出于许可证和发行政策的原因官方源里的 FFmpeg 默认关掉了一批功能尤其是--enable-nonfree这类选项在 apt 版本里是看不到的。你可以跑一下ffmpeg -buildconf看看系统里那个 FFmpeg 的编译配置会看到大量--disable-xxx这就是被裁剪过的证据。第三也是最容易被忽略的一点如果你是做开发想在自己写的程序里调用 FFmpeg 的库那 apt 源里的libavcodec-dev、libavformat-dev版本同样偏老。第三方项目往往要求比这更新的接口结果就是编译时头文件找不到符号特别闹心。所以结论很简单只是偶尔用命令行转个码apt 完全够一旦涉及自定义编译选项、新版特性、或者要基于 FFmpeg 做二次开发老老实实源码编译是绕不开的路。1.2 源码编译到底在做什么源码编译这事听起来高大上其实本质就三步configure检查环境、make编译、make install安装。configure的作用是探测你的系统里有哪些工具链、哪些外部库然后根据你传入的参数生成对应的 Makefile。如果你开了--enable-libx264但它发现系统里没装 libx264 的开发头文件就会直接报错退出。这一步很多人第一次跑不通过基本都是缺依赖。make就是真正拿着 Makefile 去调用 gcc把几万个源文件编译成可执行文件和动态库耗时看机器性能通常几分钟到十几分钟。make install则把编译好的二进制和库文件复制到指定目录默认是/usr/local/bin和/usr/local/lib。理解了这个流程后面再遇到问题你就能自己定位了——报错在哪个阶段就往哪个方向排查。2. 编译前的依赖准备2.1 基础工具链开始之前先把基础工具链装齐。这一步别偷懒后面所有坑的 70% 都能靠这一条命令提前规避。sudo apt update sudo apt install -y build-essential cmake git pkg-configbuild-essential包含 gcc、g、make 等核心编译工具。pkg-config是专门用来查找库头文件和链接参数的FFmpeg 的 configure 在检测外部库时主要就靠它。这里有个特别容易踩的坑汇编器。FFmpeg 里面大量使用汇编优化x264、x265 这些库也离不开汇编器所以系统里必须装了 nasm 或 yasm版本还不能太老。Ubuntu 20.04 的源里两个都有建议直接一起装上sudo apt install -y nasm yasm我见过不止一个人明明 libx264-dev 装了configure 还是报yasm not found最后发现汇编器压根没装。这类问题一次装全后面省心很多。2.2 编解码库怎么选FFmpeg 是一个框架真正的编码和解码能力是通过外部库来扩展的。我在实际项目里最常用的是下面这批你按需选择不用全装。# H.264/H.265 视频编码最常用的两个 sudo apt install -y libx264-dev libx265-dev # VP8/VP9WebM 生态常用 sudo apt install -y libvpx-dev # 音频编码 sudo apt install -y libmp3lame-dev libopus-dev libfdk-aac-dev # 字幕和滤镜相关 sudo apt install -y libass-dev libfreetype6-dev # ffplay 播放器需要 SDL2 sudo apt install -y libsdl2-dev # AV1 编码器可选但体积比较大 sudo apt install -y libaom-dev每个库对应什么场景我简单说一下方便你自己判断要不要装libx264H.264 编码器的业界标准几乎所有视频处理项目都要用强烈建议装。libx265H.265/HEVC压缩率比 H.264 高但编码速度慢。做视频存档、高压缩比转码场景才需要。libvpxGoogle 的 VP8/VP9 编码器Web 视频常用浏览器兼容性好。libmp3lame、libopus音频编码MP3 和 Opus 格式普通转音频必备。libfdk-aacAAC 编码器质量好但它用的是非自由许可证所以 configure 的时候必须额外加--enable-nonfree很多发行版源里默认不带这个。libaomAV1 编码器新一代标准但是编码极其耗时编译也慢。不是搞前沿编码研究的话建议先跳过。需要注意一点Ubuntu 20.04 的某些版本默认没有启用 universe 源libfdk-aac-dev在这个源里。如果上面装包时报“无法定位软件包”先确认一下源sudo add-apt-repository universe sudo apt update3. 下载源码与配置参数3.1 下载源码源码获取主要有两种方式下载压缩包或者 git clone。我推荐用 git clone 的方式因为后续如果想更新版本、切换分支比较方便而且很多第三方库比如 x264本身就是 git 仓库习惯 git 工作流会更顺手。cd ~ git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg cd ffmpeg如果你想用稳定版而不是 master可以切到 release 分支的 tag。比如 4.4.2 在当时是非常稳的版本很多生产环境都在用git checkout n4.4.2当然下载压缩包也可以wget https://ffmpeg.org/releases/ffmpeg-4.4.2.tar.bz2 tar xjf ffmpeg-4.4.2.tar.bz2 cd ffmpeg-4.4.2这里有个实际经验尽量用 release 版本而不是 master。master 虽然功能最新但偶尔会有编译不过或者行为不稳定的情况做项目讲究的是可复现固定版本至少能保证同一条命令在别人机器上也能编译通过。3.2 configure 参数逐个说明configure 是整个编译过程中最关键的一步。参数决定了你最终得到的 FFmpeg 支持哪些功能。我直接给一份我实际项目里常用的配置./configure \ --prefix/usr/local \ --enable-gpl \ --enable-nonfree \ --enable-libx264 \ --enable-libx265 \ --enable-libvpx \ --enable-libmp3lame \ --enable-libopus \ --enable-libfdk-aac \ --enable-libass \ --enable-libfreetype \ --enable-ffplay \ --enable-sdl2逐个解释一下--prefix/usr/local安装目录。默认其实也是/usr/local但显式写出来有个好处以后想卸载删这个目录就行。如果你不想污染系统目录也可以改成--prefix/opt/ffmpeg然后把/opt/ffmpeg/bin加进 PATH。--enable-gpl开启 GPL 许可证支持。libx264、libx265 这些库都是 GPL 的不开这个选项configure 会明确拒绝启用这些库。--enable-nonfree开了之后才能链接 libfdk-aac 这类非自由许可证库。代价是你的二进制不能公开发布只能自己用。--enable-libx264等显式启用对应的外部库。库装了但这里不开等于白装。--enable-ffplay编译出 ffplay 播放器可以用来快速预览视频。不然默认只编译 ffmpeg 和 ffprobe。--enable-sdl2ffplay 依赖 SDL2 窗口库这行要跟上面配合。跑完 configure 之后最后几行会输出一个“Enabled”和“Disabled”的列表建议养成习惯在这里扫一眼确认你要的功能都在 Enabled 列表里再去继续 make。这一步被很多人跳过结果编译装完才发现 x264 没启用又得回头重来。3.3 make 编译与安装configure 通过之后就是编译。命令很简单但有几个细节值得说make -j$(nproc)$(nproc)是获取 CPU 逻辑核心数-j指定并行任务数。比如 8 核的机器就是make -j8。如果你的机器内存比较小比如 2GB建议保守点用make -j2或者make -j4不然并行编译可能把内存吃满直接卡死。编译过程会有大量输出看到ERROR字样不要慌往上翻几屏找到第一条错误信息那才是根因。如果 make 中途失败修好问题之后重新跑make就好它会接着编译不需要从头开始。编译完成之后安装sudo make install sudo ldconfigldconfig这行往往被人忽略但它实际上很重要。FFmpeg 编译出来的动态库默认安装到/usr/local/lib如果这个路径不在动态链接器的搜索范围内运行时就会出现“找不到 libavcodec.so.58”之类的错误。Ubuntu 的/etc/ld.so.conf.d里通常会包含/usr/local/lib但不同环境有差异手动跑一下ldconfig是最稳妥的做法。装完之后如果你之前已经用 apt 装过 FFmpegbash 的 hash 缓存可能会让你输入ffmpeg时仍然调用旧版本。解决方法是hash -r which ffmpeg如果which ffmpeg显示的还是/usr/bin/ffmpeg说明/usr/local/bin没在 PATH 前面或者被 hash 缓存干扰了。正常 Ubuntu 系统里/usr/local/bin优先级高于/usr/binhash -r 之后应该会指向/usr/local/bin/ffmpeg。4. 安装后验证与动态库问题4.1 验证是否真正装好安装完成别急着跑项目先确认一下这次编译到底有没有生效。ffmpeg -version正常输出会包含版本号、编译配置信息。版本号是ffmpeg version n4.4.2这种代表你用的是编译的版本。然后看这一行ffmpeg -buildconf | grep x264能看到--enable-libx264才算真正把这功能打开了。同理可以检查libx265、libfdk-aac等。再进一步ffmpeg -encoders可以列出当前所有可用的编码器ffmpeg -encoders | grep x264 ffmpeg -encoders | grep fdk看到libx264和libfdk_aac就说明外部库已经链接进去了。到这一步编译安装才算真正成功。4.2 运行时报找不到 .so 文件的处理我最常遇到的问题就是编译安装完敲ffmpeg -version直接报ffmpeg: error while loading shared libraries: libavcodec.so.58: cannot open shared object file: No such file or directory原因很简单程序找到了但运行时动态链接器不知道去哪儿找 FFmpeg 的库文件。解决方式有两种。第一种把/usr/local/lib加进 ldconfig 配置echo /usr/local/lib | sudo tee /etc/ld.so.conf.d/ffmpeg.conf sudo ldconfig第二种临时设置环境变量export LD_LIBRARY_PATH/usr/local/lib:$LD_LIBRARY_PATH第二种只对当前终端窗口生效如果你想长期用可以写进~/.bashrc。但我个人推荐第一种一劳永逸干净利落。5. 常见错误速查与排障思路5.1 典型报错对照表我把这些年遇到过的高频报错整理成一张表你对着查就行。报错信息原因解决办法nasm not found或yasm not found汇编器未安装sudo apt install -y nasm yasmERROR: libx264 not found未装 libx264-dev或没开--enable-gpl装libx264-dev确保 configure 加了--enable-gpl --enable-libx264ERROR: libx265 not found未装 libx265-devsudo apt install -y libx265-devERROR: libfdk_aac not found未装 libfdk-aac-dev或没开--enable-nonfree先装包再确保 configure 加了--enable-nonfreeC compiler test failed缺少 gcc/make 基础工具链sudo apt install -y build-essentialERROR: x265 not found using pkg-configpkg-config 找不到库的 .pc 文件检查是否安装libx265-dev运行pkg-config --modversion x265验证运行 ffmpeg 报.so文件找不到动态链接器未找到/usr/local/libsudo ldconfig或配置/etc/ld.so.conf.d/ffmpeg.confmake中途卡死或无响应并行任务太多内存不足按内存减小-j参数比如make -j2configure 重新运行时出现奇怪报错之前的 Makefile/config 缓存干扰运行make distclean清理之后再重新 configure编译后ffmpeg仍显示旧版本bash hash 缓存或 PATH 顺序问题执行hash -r检查which ffmpeg5.2 排障的几个通用思路除了具体报错我有几个通用排障习惯非常管用。第一configure 报错时往上看前几条输出。FFmpeg 的 configure 检测外部库是逐个探测的比如check_lib x264失败了可能会连带影响后面所有跟 x264 有关的检测。你看到的最终错误往往是“连锁反应”真正的根源在最早那一行。第二每次改完 configure 参数重新跑之前先make distclean。这个命令会把之前生成的 Makefile 和编译中间文件清理干净。很多人改完参数直接重新 configure、make时不时会冒出来一些莫名其妙的缓存问题。虽然多数情况不清理也能过但养成了这个习惯能省很多不必要的排查时间。第三确认外部库是否安装完整不要只看包名。dev 包和运行包是两回事比如你要编译链接 libx264就得装libx264-dev只装libx264-xxx运行库是不行的。判断方法很简单dpkg -l | grep x264看有没有dev结尾的包。6. 进阶体验编译参数定制与卸载6.1 如何卸载源码安装的 FFmpeg源码编译不像 apt 那样有集中的包管理系统卸载靠两条路。如果你 configure 的时候指定了--prefix并且目录是独立的比如/usr/local/ffmpeg那直接删目录就行sudo rm -rf /usr/local/ffmpeg如果你用的默认/usr/local文件散落在里面的 bin、lib、include、share 下那就稍微麻烦点。但在源码目录里还有 Makefile 的情况下可以尝试sudo make uninstall这个命令会根据之前编译时的安装记录把文件删掉。但前提是你还没有make distclean而且 configure 的配置和生产环境时的保持一致。如果源码目录已经删了、Makefile 也没了就只能手动删除二进制和库。所以当年第一次在服务器上编译的时候我就养成了写一个小脚本记录安装文件的习惯make install之前make -n install install_files.txt把将要安装的文件列表留存下来后面真要卸载直接对照着删。6.2 进一步定制编译前面给的 configure 参数是通用型实际项目里通常还会按需裁剪。给你列几个我觉得比较实用的场景。需要把小体积的 FFmpeg 放到嵌入式设备或者和其它程序一起打包分发时可以考虑静态编译./configure --prefix/opt/ffmpeg-static --enable-static --disable-shared ...这样编出来的 ffmpeg 二进制不依赖一堆.so文件拷到别的机器直接能跑。缺点是体积大而且 GPL 库静态链接之后二进制的许可证问题更敏感自己内部用没事对外发布要小心。开发调试时建议保留 debug 符号。默认的编译配置已经带了-g如果你想深入排查崩溃问题可以在 configure 后面加--enable-debug3 --disable-optimizations这样 gdb 能显示出比较完整的调用栈。生产环境可别这么干性能会有明显下降。如果确实对文档没需求可以加一个--disable-doc省一点编译时间。编解码器模块也可以裁剪比如你只做 H.264 转 H.265可以把其他编码器禁用掉但裁剪的时候要谨慎解封装、滤镜这些基础模块别乱删宁可多留也不要少留不然跑起来才发现缺模块更痛苦。6.3 与 apt 版本混用的几个坑最后聊聊源码版和 apt 版混用这件事。我在自己的开发机上就吃过这个亏系统里有 apt 的 FFmpeg后来又源码编译装了一份新版命令用/usr/local/bin的新版没问题但某个 GUI 程序调用的却是 system 里 apt 的动态库。版本不匹配接口一变程序崩溃都找不出原因。所以我的建议是如果你决定源码编译 FFmpeg并且要长期用于自己的项目最好把 apt 版的 FFmpeg 显式卸载掉sudo apt remove ffmpeg libavcodec-dev libavformat-dev libavutil-dev当然这么做之前确认一下系统里其它软件不依赖这些包。一旦出问题再sudo apt install ffmpeg也随时能装回来不算风险操作。如果不想卸 apt 版那就从始至终明确自己用的是哪一份。编译项目的时候通过 pkg-config 指定用/usr/local/lib/pkgconfig下的.pc文件避免链接到 apt 版本的头文件和库。最后分享一个我的个人体会。很多人第一次编译 FFmpeg光看到 configure 那一大堆参数就头大觉得这东西太复杂。其实核心逻辑就一条你想要的每个能力都需要对应的外部库而外部库装好了要明确告诉 FFmpeg“我装好了你用吧”。把这个心智模型建立起来别说 FFmpeg以后再编译 OpenCV、GStreamer甚至其它 C/C 开源项目思路都是一样的。编译 FFmpeg 这件事我第一次花了将近一下午全耗在缺依赖和报错排查上。现在熟了一套标准流程下来十分钟不到。你踩过的坑越多对它的理解就越深。这次照着走一遍相信下次你就可以不看教程直接出门右转了。