
接到一个内网项目需求要在银河麒麟V10的机器上离线安装ffmpeg机器是aarch64架构没有外网软件源也没法直接访问互联网。一开始我以为跟普通Linux离线安装一样结果折腾下来发现坑不少麒麟V10有不同的分支版本、ARM源里好多包根本不存在、网上找的二进制不是架构不匹配就是glibc版本不对。这篇文章我会把完整的离线安装思路拆开来讲包括如何判断系统底子和架构、三条可行的安装路线静态二进制、本地yum源、源码编译以及每条路线的实操步骤和我在过程中踩过的坑适合需要在内网、离线环境部署ffmpeg的运维和开发人员参考。1. 动手前先搞清楚你的麒麟V10是什么底子很多教程一上来就让你执行apt或者yum但麒麟V10的版本分支比较多包管理器、软件源、默认安装的库都不一样。先把这个搞清楚后面所有步骤才不会走弯路。1.1 麒麟V10的两个主流分支直接决定包管理工具银河麒麟V10大体上有两个分支。一个是桌面版大多数时候基于Debian体系另一个是高级服务器版一般基于CentOS/RHEL体系。前者用apt/dpkg后者用yum/dnf。如果你在一台机器上用apt的结果去套另一台机器的yum那基本是装不上的。判断方法很简单打开终端执行cat /etc/os-release如果输出IDkylin且PRETTY_NAME是类似Kylin Linux Advanced Server V10 (SP2)这就是服务器版包管理用yum。如果显示的是桌面版的标识那大概率是Debian体系用apt。再补充一条命令很多麒麟系统在/etc/下还有kylin-release或.kyinfo文件cat /etc/kylin-release我遇到过一些机器os-release写的模棱两可反而是kylin-release里的信息更准确。建议两条命令都跑一下不要只看一条就下结论。1.2 一条命令识别CPU架构别把x86_64和aarch64搞混离线安装ffmpeg时架构是最容易翻车的点。麒麟V10现在支持的CPU很多飞腾、鲲鹏是aarch64海光、兆芯以及常规Intel/AMD是x86_64还有一些老的龙芯机型是mips或loongarch。uname -m输出x86_64下载amd64/x86_64的包输出aarch64下载arm64/aarch64的包输出armv7l或更早的32位麒麟上现在少见但是也有存量机器还有一条命令可以看更完整的CPU信息lscpu | grep Architecture这里要特别提醒很多人以为aarch64和arm64是两个不同的东西其实在打包和软件源里arm64就是aarch64的Debian系叫法两者是同一个指令集。所以看到arm64的包用在一台显示aarch64的系统上是完全正确的。真正需要担心的反而是把x86_64的包硬塞给aarch64的机器结果就是典型的Exec format error。机器显示架构CPU类型示例选择安装包时注意x86_64Intel、AMD、海光、兆芯对应amd64/x86_64包aarch64飞腾FT-2000、鲲鹏920对应arm64/aarch64包loongarch64龙芯3A5000及之后需特殊处理社区包较少armv7l老式32位ARM存量机器不建议装新版ffmpeg2. 离线安装前先想清楚这三条路线离线装ffmpeg不是只有一种做法。很多人一上来就搜ffmpeg离线安装包然后随便下一个.rpm或者.tar.gz装上跑不起来才回头查原因。其实根据你的使用场景至少有三条路线可以走各有优劣。2.1 静态编译二进制最快但功能边界固定官方社区有维护的静态构建包里面是编译好的ffmpeg可执行文件直接解压就能跑。它的特点是几乎所有常见扩展库都被静态链接进了二进制文件里不依赖系统的动态库非常适合离线环境。你只需要下载对应架构的压缩包传到内网机器上就能用。适合的场景只要命令行转码、抽帧、推流不想管复杂的依赖关系有多台同架构机器要批量部署或者只是临时用一下。缺点同样明显功能是编译时写死的你想自己加一个编码器比如某些专利编码器静态包如果没有内置你就没办法通过装个库让它启用只能换别的方案。2.2 本地yum/apt离线源更正规但需要整理依赖如果你希望在内网多台机器上都能通过yum install -y ffmpeg这种标准方式安装而且未来还可能装其他软件包那么先在一台能联网的机器上把ffmpeg以及它的全部依赖rpm包下载下来再导入内网搭建一个本地yum源是比较合理的做法。这个方案的优势是经过了包管理器的依赖解析安装后软件处于受系统管理的状态卸载、升级都比较方便。但它也有明显的坑麒麟V10的默认源里经常没有ffmpeg。因为ffmpeg涉及一些许可证上的历史原因很多企业级Linux发行版的默认软件源都不带编译好的ffmpeg包。你需要先找到能提供ffmpeg rpm包的外部源再把它们全部拉下来这个过程相当考验耐心。2.3 源码编译适合定制功能但依赖清单很繁琐如果你需要特定版本的ffmpeg、需要开启某个编译选项硬件加速、特定编码器或者需要在Qt等开发工程里链接ffmpeg的库文件那就必须走源码编译这条路。源码编译离线环境下最痛苦的是依赖收集。ffmpeg本身不带x264、x265、mp3lame这些外部库编译选项里想启用它们就需要提前把对应的源码包全部下载好然后按顺序先编译安装这些依赖库再编译ffmpeg本身。三条路线的对比我整理了一下方案部署速度依赖管理定制能力维护成本踩坑概率静态二进制最快解压即用内置不用管低编译时已定死低低本地yum源中等要建repo包管理器托管中依赖官方源中高源码编译慢要装好多依赖手动管理链路高想加什么加什么高最高我的习惯是命令行用、临时用它就选静态二进制生产环境大规模交付优先看能不能搭一个本地源有明确的功能定制需求或者要二次开发再考虑编译。3. 最省事的路线拷贝一个静态编译的ffmpeg如果你的需求就是给机器装一个能用的ffmpeg静态二进制通常是我最先尝试的方案因为整个过程可以在五分钟内完成。3.1 在联网机器上找到架构和版本都匹配的静态包ffmpeg社区维护的静态构建包是最常被使用的来源它同时提供amd64和arm64两个架构的release构建。进入下载页面后要选择和你目标机器架构一致的包aarch64机器下载带arm64标识的tar.xz压缩包x86_64机器下载带amd64标识的tar.xz压缩包版本上我建议选最新的release稳定版而不是git master开发版。开发版功能更新但偶尔会有不稳定的情况内网环境没有外网去查更新稳妥最重要。下载完成后压缩包大概几十MB可以用U盘、内网文件服务器或者现有的运维通道传到目标机器上。3.2 解压、放置到/usr/local/bin、验证执行权限上传到目标机器后找一个合适的目录解压比如/optcd /opt tar -xJf ffmpeg-release-arm64-static.tar.xz cd ffmpeg-release-arm64-static解压后目录里一般有ffmpeg、ffprobe、ffplay三个可执行文件以及一些文档。验证一下是否静态链接file ffmpeg ldd ffmpeg如果file显示statically linked而ldd提示not a dynamic executable说明这个二进制是完全静态的系统里缺什么库都不影响它运行。接下来拷贝到/usr/local/bincp ffmpeg ffprobe /usr/local/bin/ chmod x /usr/local/bin/ffmpeg /usr/local/bin/ffprobe为什么要放/usr/local/bin而不是/usr/bin麒麟的类CentOS服务器版有些安全策略会把系统盘关键目录做保护/usr/bin在重启后可能被还原到初始状态。/usr/local/bin的规则相对宽松放这里更安全。执行一下看版本ffmpeg -version能看到版本号和编译配置就说明安装成功了。3.3 静态包也有盲区哪些编码器可能找不到静态包内置了一大堆编码器和解码器常用的libx264、libx265、libmp3lame、libopus等基本都在。但有一个容易被忽略的libfdk_aac。这是AAC编码器里音质公认比较好的一种因为许可证问题很多静态构建默认不包含它需要--enable-nonfree才编译进去。如果你发现ffmpeg -encoders | grep fdk没有任何输出而业务又明确要求用libfdk_aac那静态包这条路就不适合你了得考虑源码编译。检查方式ffmpeg -encoders | grep -E 264|265|libmp3lame|fdk如果还差什么编码器看对应位置有没有输出再决定是换一个静态构建包还是直接转方案。4. 相对正规的路线搭建本地yum源用yum install安装静态二进制虽然好用但它游离在系统包管理之外。在内网环境下如果有多台机器都要装ffmpeg而且未来可能安装其他多媒体相关软件我更建议你建立一个本地yum仓库把ffmpeg装成系统包。这样以后升级、卸载都有章可循。4.1 在能联网的机器上先找到ffmpeg的rpm包先说一个现实问题麒麟V10的默认软件源里通常没有ffmpeg。RHEL/CentOS系默认源也不带。你需要找一个能提供ffmpeg rpm包的第三方yum源常见的包括EPEL、RPM Fusion等。在联网机器上先把这些源配置好然后使用yumdownloader把ffmpeg以及它的全部依赖rpm包拉下来。注意这一步最好用和目标机器相同操作系统版本的机器来做避免系统库版本差异。yum install -y yum-utils createrepo yumdownloader --resolve --destdir/opt/ffmpeg_rpms ffmpeg参数解释--resolve自动下载ffmpeg所依赖的所有rpm包--destdir指定下载目录下载完成后检查一下目录ls /opt/ffmpeg_rpms这里要特别提醒--resolve解析的依赖版本和当前系统的库版本有关。如果下载机器和目标机器系统库版本差距太大内网安装时可能出现requires X 1.0的冲突。4.2 在内网机器上创建repo并完成安装把整个/opt/ffmpeg_rpms目录拷贝到内网目标机器上然后在目标机器上生成repo元数据cd /opt/ffmpeg_rpms createrepo .生成repodata目录后写一个repo文件比如/etc/yum.repos.d/local-ffmpeg.repo[local-ffmpeg] nameLocal FFmpeg RPMs baseurlfile:///opt/ffmpeg_rpms enabled1 gpgcheck0注意gpgcheck0因为本地rpm包默认没有导入对应公钥时开启校验会导致安装被拒绝。如果你有公钥可以放进系统那保留gpgcheck1更安全。然后刷新缓存并安装yum clean all yum makecache yum install -y ffmpeg4.3 ARM架构的麒麟服务器版依赖找不到才是最大拦路虎上面的流程在x86_64架构的麒麟服务器版上通常走得更顺一些但如果你面对的是aarch64的麒麟机器麻烦就大了。很多第三方yum源在ARM架构上根本没有编译好的ffmpeg包或者有包但依赖的其他东西缺失。我遇到的情况是RPM Fusion的aarch64仓库时有时无有时能找到旧版本有时整个目录都是404。EPEL虽然支持aarch64但里面也不带ffmpeg。这种情况下变通的办法是到独立的rpm包搜索站点上找已经打包好的aarch64 rpm包手工下载ffmpeg主包、ffmpeg-libs包以及它们依赖的SDL2、libvdpau等包放进同一个目录再createrepo。这个过程比较痛苦因为依赖关系要自己一个个点开看稍不留神就漏一个。如果你的机器数量不多而你对包管理又没有执念遇到ARM架构时优先考静态二进制方案这是我一直以来的实际经验省下的时间够你多处理好几台机器了。5. 要定制功能时源码编译也没那么可怕如果你最终需要的是齐全的编码器、硬件加速支持或者要给Qt、Java之类的开发环境提供ffmpeg库静态二进制满足不了yum源又找不到包那就只能源码编译。5.1 编译前的依赖清单与下载顺序源码编译ffmpeg之前需要把依赖库的源码包预先下载好。这里列一份我常用的清单按编译顺序排列依赖库源代码包名示例作用nasmnasm-2.15.05.tar.xz汇编器编译x264等必须yasmyasm-1.3.0.tar.gz汇编器部分库需要zlibzlib-1.2.13.tar.gz基础压缩库libx264x264-master.tar.bz2H.264编码器libx265x265_3.5.tar.gzH.265/HEVC编码器libvpxlibvpx-1.13.0.tar.gzVP8/VP9编码器libmp3lamelame-3.100.tar.gzMP3编码器libopusopus-1.4.tar.gzOpus音频编码器libvorbislibvorbis-1.3.7.tar.gzVorbis音频编码器opensslopenssl-3.0.8.tar.gzhttps/rtmp等协议支持ffmpegffmpeg-6.1.tar.xz主程序把这些源码包全部下载到一个目录通过U盘或内网文件服务器传到目标机器。编译顺序一般是nasm/yasm这类工具链 → 各种编码器依赖库 → 最后才是ffmpeg。每个依赖库基本都是标准的./configure make make install三步走。以libx264为例tar -xf x264-master.tar.bz2 cd x264-master ./configure --prefix/usr/local --enable-shared --enable-static make -j$(nproc) make install这里--prefix/usr/local很重要它决定了头文件和库文件的安装位置后续ffmpeg的configure需要靠PKG_CONFIG_PATH找到这些库。5.2 ffmpeg的configure参数逐项说明再给你一份配置ffmpeg的configure参数非常多我挑几个必须解释的--prefix安装目录默认是/usr/local--enable-gpl启用GPL许可证的组件编译libx264、libx265时必须加--enable-libx264启H.264编码器--enable-libx265启用H.265编码器--enable-libmp3lame启用MP3编码器--enable-libopus启用Opus编码器--enable-libvorbis启用Vorbis编码器--enable-libvpx启用VP8/VP9编码器--enable-openssl启用加密协议相关支持--enable-nonfree启用非自由许可证的组件如果你要用libfdk_aac必须加一份经过我实测的配置参考./configure \ --prefix/usr/local/ffmpeg \ --enable-gpl \ --enable-version3 \ --enable-nonfree \ --enable-libx264 \ --enable-libx265 \ --enable-libmp3lame \ --enable-libopus \ --enable-libvorbis \ --enable-libvpx \ --enable-openssl然后编译安装make -j$(nproc) make install编译完的ffmpeg安装在/usr/local/ffmpeg目录下不会污染系统其他路径。但要注意编译时如果开启了--enable-shared我习惯把ffmpeg自身编译成动态库方便Qt工程链接运行时需要让系统找到动态库echo /usr/local/ffmpeg/lib /etc/ld.so.conf.d/ffmpeg.conf ldconfig5.3 ARM架构上源码编译的三个常见报错ARM架构aarch64上编译ffmpeg和依赖库整体过程和x86_64一样但有几个问题更容易撞上。第一个报错nasm/yasm not found。编译libx264时会调用汇编器来优化关键代码。如果系统没有装nasm会直接报nasm not found。解决办法就是先编译安装nasm并把它加进PATH。第二个报错内存不足编译进程被kill。有些后端用的虚拟机配置只有2G内存make -j$(nproc)会同时起很多编译任务内存瞬间被打爆。解决方法是降低并行度make -j2如果还不行就make -j1慢是慢一点但至少不会中途挂掉。第三个报错libx264 not found。明明已经编译安装过libx264但ffmpeg的configure还是找不到。这通常是因为pkg-config的搜索路径没有包含libx264的.pc文件。执行一下export PKG_CONFIG_PATH/usr/local/lib/pkgconfig:/usr/local/ffmpeg/lib/pkgconfig:$PKG_CONFIG_PATH然后再执行configure网络上有大量这个坑的提问基本都是漏了这一步。5.4 编译后如何在Qt等开发环境里调用如果你在麒麟V10上用Qt做应用开发需要通过调用ffmpeg的库处理音视频编译安装完ffmpeg之后在Qt工程的.pro文件里加上INCLUDEPATH /usr/local/ffmpeg/include LIBS -L/usr/local/ffmpeg/lib -lavformat -lavcodec -lavutil -lswscale -lswresample在C源码里包含头文件时用extern C包裹避免C的名称修饰导致链接失败extern C { #include libavformat/avformat.h #include libavcodec/avcodec.h }我自己在实际项目里遇到过一个问题编译链接都通过了但程序一运行就报cannot open shared object file。原因就是前面提到的ld.so.conf.d没配置好系统运行时找不到/usr/local/ffmpeg/lib里的动态库。执行一次ldconfig再重启程序就正常了。6. 安装完成后花十分钟跑一遍基础验证不管通过哪种方式安装装完之后的验证环节不能省。有时候版本号能显示出来但实际编码时才发现某个编码器不可用内网环境排查起来很麻烦。6.1 三条命令确认安装状态第一条是版本确认ffmpeg -version第二条看编译配置确认你想要的功能到底有没有被编译进去ffmpeg -buildconf第三条看编码器和解码器的支持情况ffmpeg -encoders ffmpeg -decoders在三者的输出前面加上-hide_banner可以去掉开头冗长的版权信息只留关键部分ffmpeg -hide_banner -encoders | grep 264如果这里能看到libx264或者libx265说明核心编码能力是完整的。6.2 转码、抽帧、提取音频、推流四类实用测试安装ffmpeg的目的是使用所以我每次装完都会跑几个典型命令确认调用链正常。用一段测试视频执行以下操作转码把H.264视频转成H.265ffmpeg -i input.mp4 -c:v libx265 -c:a copy output_265.mp4注意-c:v libx265后面的编码器名称要和实际编译进去的一致如果没编进去会直接报Unknown encoder。抽帧在指定时间点截取一张图片ffmpeg -ss 00:01:30 -i input.mp4 -frames:v 1 -q:v 2 frame.jpg-ss放在-i之前表示快速定位放后面表示精确到帧但慢-frames:v 1表示只取一帧-q:v 2控制输出图像质量数值越小质量越高。提取音频为MP3ffmpeg -i input.mp4 -vn -c:a libmp3lame -q:a 2 output.mp3推流到内网RTMP服务器ffmpeg -re -i input.mp4 -c copy -f flv rtmp://192.168.1.10/live/stream-re是以源文件真实帧率读取-c copy是流复制不做重新编码-f flv指定输出封装格式。这组命令在直播推流场景很常用装完顺手验证一下不亏。6.3 批量处理的小技巧用Shell做循环内网机器如果要做批量转码手动一条条执行命令不现实。我通常写一个简单的for循环for v in *.mp4; do ffmpeg -i $v -c:v libx264 -c:a aac ${v%.mp4}_h264.mp4 done这个循环会把当前目录下所有mp4文件转成H.264编码的新文件。${v%.mp4}是Shell的参数扩展作用是去掉文件名末尾的.mp4后缀再接新的后缀。实际用下来还有一个小提示批量任务建议加上-nostdin参数避免ffmpeg在交互模式下等待标准输入导致脚本挂起ffmpeg -nostdin -i $v -c:v libx264 -c:a aac ${v%.mp4}_h264.mp47. 麒麟V10离线安装ffmpeg的踩坑实录这部分是我自己实际趟过的坑记录下来给后面的人参考。每个坑都写了报错特征、原因和解决办法能帮你省不少排查时间。7.1 架构选错执行报Exec format error有次我在一台飞腾CPU的机器上执行从网上找来的ffmpeg一运行就报bash: ./ffmpeg: cannot execute binary file: Exec format error第一反应是文件损坏重新传了一遍还是同样报错。后来用file ffmpeg看了一眼发现这是x86-64的二进制而机器是aarch64。折腾了半天就是下载时没注意架构。后来我养成了习惯不管是下载rpm包还是静态二进制先确认目标机的uname -m对照着架构去找文件。顺手把file命令列在前面几秒钟就能排查掉这个低级错误。7.2 装完重启后ffmpeg消失系统安全机制惹的祸还有一次我把ffmpeg复制到了/usr/bin目录当时执行得好好的结果一重启命令找不到了。查了一下才发现麒麟服务器版对/usr等系统关键目录有保护机制重启后会把部分路径还原到初始状态。解决办法是避免把自装软件放到/usr/bin和/bin这些由系统严格管辖的目录优先选择/usr/local/bin。同时用rpm -V或者对系统做完整备份的方式确认改动在重启后是否保留。后来我部署到麒麟的机器一律约定放在/usr/local/bin下没有再出现过这个问题。7.3 yum本地源安装时被依赖包版本冲突卡住内网搭建yum源的过程中最容易遇到的问题就是rpm包的依赖冲突。报错通常是Error: Package: ffmpeg-4.x.x-1.el8.aarch64 Requires: libavcodec61.so.61()(64bit)这表示你下载ffmpeg主包的时候没有把对应的ffmpeg-libs包拉到同一个repo里。yum解析时找不到这个库就拒绝了安装。解决办法是把ffmpeg相关的所有子包ffmpeg、ffmpeg-libs、ffmpeg-devel等和它们的依赖全部放进同一个目录再createrepo尽量从同一套源里拉取混用不同源的包版本很容易把依赖关系搞乱。7.4 批量部署时我习惯用一个脚本搞定所有事最后分享一个实际部署经验。静态二进制方案下我通常会把ffmpeg、ffprobe两个可执行文件、一个版本说明再加上一个简单的部署脚本打包成一个ffmpeg-offline-arm64-6.1.tar.gz。部署的时候只需要tar -xzf ffmpeg-offline-arm64-6.1.tar.gz cd ffmpeg-offline-arm64-6.1 sh install.sh脚本内容很简单检查架构、复制文件到/usr/local/bin、执行ffmpeg -version验证。#!/bin/bash if [ $(uname -m) ! aarch64 ]; then echo Error: this package is for aarch64, current arch is $(uname -m) exit 1 fi cp ffmpeg ffprobe /usr/local/bin/ chmod x /usr/local/bin/ffmpeg /usr/local/bin/ffprobe ffmpeg -version这样即使在完全断网、没有软件源的情况下任何一台同架构的麒麟机器都能在几分钟内完成ffmpeg部署。内网环境干多了你会发现真正靠谱的不是某个特定命令而是一套自己验证过、可以反复复用的流程。