简介:FFmpeg 3.4.2 预编译多媒体处理库面向Windows开发者,适用于32位与64位系统环境,可用于在自有应用中集成音视频编解码、格式转换、流媒体推拉流及滤镜处理等能力。压缩包内共149个文件,包括111个头文件、16个导入库、16个动态链接库与6个命令行工具,整体约27.45MB,目录按include、lib、bin划分,结构清晰。其中头文件定义完整API接口,动态库封装H.264、AAC等主流编解码核心功能,导入库供链接器构建可执行程序,命令行工具可直接处理转码、剪辑、音轨提取等任务。这套预编译包免去自行编译FFmpeg源码的繁琐流程,开发人员只需引用头文件并链接对应库,即可快速调用C API或借助其他语言绑定实现多媒体功能,提升集成效率。目前已有307人学习下载,适合希望快速上手FFmpeg的入门及中级开发者参考使用。
1. 这个 rar 里装的 FFmpeg 3.4.2,到底还值不值得折腾
“ffmpeg3.4.2.rar”这个压缩包,我拿到过不止一次。它不是官网标准格式,更像某个项目组内部流传的资源:里面要么是 FFmpeg 3.4.2 的完整源码树,要么是某台机器上编出来的可执行文件加一堆动态库。3.4.2 是 2018 年发布的稳定分支,很多工控软件、旧服务器、嵌入式板子上的音视频业务至今还跑在它上面,新版本换 API 太频繁,老工程根本不敢动。这篇文章不是让你从零学 FFmpeg 的,而是拿到这个 rar 之后怎么验货、怎么编出能用的二进制、怎么调转码参数、怎么避开我踩过的那几个大坑。适合维护老项目的朋友,也适合第一次在 Linux 上折腾老版本 FFmpeg 的人。
2. 先验货:解压 rar 后的目录结构与平台选型
拿到ffmpeg3.4.2.rar之后,第一件事不是赶紧解压编译,而是确认这个包到底装了什么。不同来源的包,内容差别非常大,用错了会浪费半天时间。
2.1 用 file 和 unrar 看包内真实内容
在 Linux 环境下处理 rar 包,我一般是先看文件类型,再列包内清单,不要靠后缀名猜。
file ffmpeg3.4.2.rar unrar l ffmpeg3.4.2.rarfile能显示 rar 版本和是否加密;unrar l会列出所有文件,不实际解压。没有 unrar 的话,用7z l ffmpeg3.4.2.rar效果一样。列出的清单里如果看到configure、Makefile、libavcodec/、ffbuild/这类目录,说明是源码包,需要自己编译;如果看到bin/ffmpeg、bin/ffprobe加一堆.so或.dll,那就是预编译好的二进制包,直接跳到平台验证。
这里有个常见的误判:有人把源码包解压后,直接找一个旧路径下的ffmpeg可执行文件说“版本没问题”,结果那个二进制根本不是 3.4.2 编出来的。源码包和二进制包的验证方式完全不同,必须先区分开。
2.2 二进制包先做“体检”:版本、依赖、运行平台
如果是预编译包,我一般不会立刻拿到业务目录,而是先跑三条命令。
./ffmpeg -version ldd ffmpeg uname -a-version会显示版本号、编译配置和可用的编解码器列表,能确认它确实是 3.4.2。ldd在 Linux 下查看可执行文件依赖的动态库,如果有 “not found”,说明机器上缺libavcodec.so.57之类的库;如果机器是 ARM 而包是 x86_64 的,uname -a一看就知道。Windows 下可以用依赖查看工具,但我更推荐直接跑ffmpeg -version看是否报DLL 加载失败,比逐个文件点开快。
依赖这块是最容易翻车的地方。很多预编译包为了体积把 FFmpeg 做成了动态链接全部插件,换一台机器就起不来。我习惯把包放在/opt/ffmpeg342这种独立目录,然后用export LD_LIBRARY_PATH=/opt/ffmpeg342/lib:$LD_LIBRARY_PATH运行,确保加载到的是包内自带的.so,而不是系统里旧版本。
2.3 源码包先看 configure 支持哪些功能
如果是源码包,我会先看一眼配置选项,判断这个包当初的构建方向。
./configure --help | grep -- '--enable-'输出会列出--enable-libx264、--enable-libfdk-aac、--enable-vaapi、--enable-openssl等开关。FFmpeg 3.4.2 的很多功能不是默认开启的,比如 libx264 和 libfdk-aac 都需要额外依赖,硬件加速也要单独打开。这个步骤能让我知道编译前要装哪些第三方库,避免 configure 到一半报错。
另外,要留意configure文件是否有可执行权限。从 Windows 打包拷到 Linux 的源码包,经常丢了执行位,需要chmod +x configure。这种不起眼的小问题,能卡住一两个小时。
3. 从源码编译 FFmpeg 3.4.2:configure 参数与依赖取舍
如果你手上是源码包,那编译这一步躲不开。FFmpeg 3.4.2 的编译不算难,但参数取舍直接影响后面用起来顺不顺手。常见做法是先把基础编码能力编出来,再根据业务需求加硬件加速和滤镜。
3.1 最小化编译配置:H.264 和 AAC 就够用
大多数业务场景只需要把视频转成 H.264,音频转成 AAC,所以这个最小集能覆盖八成需求。我一般这样编:
sudo apt-get install build-essential yasm libx264-dev libfdk-aac-dev libmp3lame-dev ./configure --prefix=/opt/ffmpeg342 \ --enable-gpl \ --enable-nonfree \ --enable-libx264 \ --enable-libfdk-aac \ --enable-libmp3lame \ --disable-doc make -j$(nproc) sudo make install--prefix指定安装路径,避免污染系统目录;--enable-gpl是因为 libx264 是 GPL 协议,不开的话 configure 会直接拒绝;--enable-nonfree是为了启用 libfdk-aac,这个库的许可不是自由软件,两者需要同时打开。--disable-doc跳过文档编译,能省不少时间。make -j$(nproc)用所有 CPU 核心并行编译,首次编大概三到五分钟。
有个细节:如果你的项目里不需要 fdk-aac,只是用内置的 aac 编码器,那--enable-nonfree可以不加,但内置 aac 的质量在低码率下明显弱于 fdk-aac。我通常在需要音频直播的场景保留 fdk-aac,其他场景直接去掉。
3.2 加上硬件加速:VAAPI 与 NVIDIA 的配置
转码如果只在 CPU 上跑,单路 1080p 都要占满好几个核。需要高吞吐时,我一般启用硬件加速。FFmpeg 3.4.2 的 VAAPI 支持已经比较成熟,配置方式如下。
sudo apt-get install libva-dev libva-drm2 ./configure --prefix=/opt/ffmpeg342 \ --enable-gpl \ --enable-libx264 \ --enable-libfdk-aac \ --enable-vaapi \ --enable-hwaccel=h264_vaapi make -j$(nproc) sudo make install--enable-vaapi打开 VAAPI 解码和编码;--enable-hwaccel=h264_vaapi是让 H.264 解码走硬件。这里要注意,3.4.2 的 VAAPI 编码器是h264_vaapi,不是libx264,两者不能混用。如果你的显卡是 NVIDIA,需要加--enable-nvenc来启用硬件编码器,但 3.4.2 对 NVENC 的支持没有 VAAPI 稳定,建议先用软件 x264 兜底。
3.3 并行编译与增量修改的正确姿势
编译过程中我习惯把日志存下来,出错时能快速定位。
make -j8 2>&1 | tee build.log grep -i "error" build.logtee把输出同时写到终端和 build.log,grep -i error查找所有错误信息。如果你调整了 configure 参数,不能直接再跑 make,要先清理。
make distclean ./configure ...(新参数) make -j8make distclean会删除所有临时对象文件和编译产物。很多人直接再make,导致旧配置残留,编出来的二进制还是旧功能。每次改 configure 之后必须 distclean,这是血泪经验。
4. 转码实践:用 3.4.2 把常见格式压成 H.264 + AAC
编译通过后,真正的工作是调命令。FFmpeg 3.4.2 的命令行风格和现在的主流版本差别不大,但某些参数(比如-tune、-f flv的处理)有老版本特有的行为。下面几个命令是我在实际业务里用顺手的组合。
4.1 最基础的转码命令:从 MP4 到 MP4
把一个视频文件转成 H.264 + AAC 的 MP4,最简命令是:
ffmpeg -i input.mkv \ -c:v libx264 \ -c:a libfdk_aac \ -b:a 128k \ -pix_fmt yuv420p \ output.mp4-c:v libx264指定视频编码器;-c:a libfdk_aac使用 fdk-aac 音频编码器,如果编译时没带,可以用内置的aac替换;-b:a 128k是音频码率,语音类内容 64k 就够,音乐建议 192k。-pix_fmt yuv420p非常关键,很多高清源是 yuv444p,不转的话部分播放器画面发绿或打不开。
这里有个 3.4.2 的坑:内置aac编码器在 128k 以下音质衰减明显,而libfdk_aac在低码率下依然能保持人声清晰。如果你发现转出来的视频音频发闷,先检查是不是用了aac而不是libfdk_aac。
4.2 面向网络传输的低延迟参数组合
如果是直播推流,不能直接用上面的命令,要额外设置关键帧间隔和编码延迟。
ffmpeg -i input.mkv \ -c:v libx264 \ -preset veryfast \ -tune zerolatency \ -g 60 \ -sc_threshold 0 \ -b:v 2500k \ -c:a libfdk_aac \ -f flv rtmp://192.168.1.10/live/stream-preset veryfast牺牲一点压缩率换取编码速度;-tune zerolatency是 x264 专门为低延迟场景设计的优化,会关闭或减小 B 帧缓冲,对直播至关重要。-g 60表示每 60 帧一个关键帧,在 30fps 下就是两秒一个 IDR,网络抖动时播放器能在两秒内恢复。-sc_threshold 0禁用场景切换自动插关键帧,否则画面剧烈变化时会插入额外 IDR,导致码率波动。-f flv封装成 FLV 推给 RTMP 服务器。
这些参数在 3.4.2 上都是完整支持的,但有个细节:-tune zerolatency需要 libx264 支持 tunning 模块才有效,如果你的 x264 是系统自带的旧版本,可能不认zerolatency,会报Error setting option tune,这时要重新编译 x264 源码。
4.3 滤镜链:缩放、去隔行、字幕烧录
处理视频源时,滤镜链是绕不开的。一条典型命令如下。
ffmpeg -i interlaced.ts \ -vf "yadif=1,scale=1280:720,subtitles=sub.srt" \ -c:v libx264 \ -c:a libfdk_aac \ output.mp4yadif=1是去隔行滤镜,参数 1 表示启用帧加倍模式,能消除画面抖动;scale=1280:720强制缩放;subtitles=sub.srt烧录字幕,需要编译时带--enable-libass。滤镜按从左到右的顺序执行,先去隔行再缩放,然后烧字幕,顺序错了会导致效果不对。比如先缩放再去隔行,隔行痕迹会被放大,转换质量下降。
这里提醒一下:subtitles滤镜在 3.4.2 里有个老 bug,对某些 UTF-8 编码的字幕文件会乱码。解决方法是把字幕文件转成 UTF-8 无 BOM,或者用force_style强制指定字体参数。
5. 避坑指南:编译报错、运行崩溃与版本联动问题
FFmpeg 3.4.2 的坑我基本都踩过一遍,这一章挑出最影响效率的几个,按“现象—原因—解决”的方式写出来。
5.1 configure 报错 “x264 not found”,但系统明明装了 libx264-dev
现象是执行./configure --enable-libx264时,终端提示ERROR: x264 not found,但dpkg -l | grep x264确实有包。
原因是 FFmpeg 的 configure 依赖 pkg-config 来查 x264,而 x264 的.pc文件没有放到 pkg-config 默认搜索路径里。很多时候我们用apt-get install libx264-dev安装的 x264 太新或路径不对,3.4.2 的 configure 根本找不到。
解决办法有两种:先确认 pkg-config 能查到,然后设置环境变量。
pkg-config --exists x264 && echo found export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig ./configure --enable-libx264如果 x264 是手动编译安装的,把PKG_CONFIG_PATH指向你安装的/usr/local/lib/pkgconfig即可。另外libx264-dev版本太新也可能导致 3.4.2 的 configure 检查失败,因为新版 x264 的x264.h里某个结构体变了。这种情况下我一般不用系统包,而是从源码编一个旧版 x264,再编 FFmpeg,省得折腾。
5.2 运行时提示 libavcodec.so.57: cannot open shared object file
现象是做转码时,程序启动一两秒后直接崩溃,终端报找不到.so文件。
原因是 FFmpeg 3.4.2 的库文件是动态链接的,安装到了/opt/ffmpeg342/lib,但这个目录不在系统的动态库搜索路径里。你执行/opt/ffmpeg342/bin/ffmpeg时,加载器找不到libavcodec.so.57。
解决方法是把库路径写进 loader 配置。
echo "/opt/ffmpeg342/lib" > /etc/ld.so.conf.d/ffmpeg342.conf sudo ldconfig注意ldconfig需要 root 权限,执行后运行ldd ffmpeg应该能看到所有依赖都找到了。如果你没有 root,只能在启动脚本里加上export LD_LIBRARY_PATH=/opt/ffmpeg342/lib:$LD_LIBRARY_PATH,但每次都要带环境变量,容易漏。我习惯用 ld.so.conf 方式,一劳永逸。
5.3 GCC 10 以上编译时大量 “multiple definition” 错误
现象是执行make时,报错堆满屏幕,比如libavcodec/xxx.o: multiple definition of 'some_func',这在高版本 GCC 下非常常见。
原因是 GCC 10 默认启用-fno-common,而 FFmpeg 3.4.2 部分代码里存在跨文件定义的全局变量,在旧标准下允许合并,在新标准下被视为重复定义。
解决办法是给 configure 加上额外的 CFLAGS。
./configure --extra-cflags="-fcommon" ... make -j8-fcommon会恢复旧的合并语义,让编译通过。如果项目里不允许用 GCC 10,也可以直接安装 GCC 7 或 8 来编,但加-fcommon是最快的方式。我编 3.4.2 时,默认就会加上这个参数,省得 lineno 反复翻车。
5.4 OpenSSL 版本不兼容导致无法启用 HTTPS 拉流
现象是./configure --enable-openssl后报OpenSSL not found,或者编出来了但运行时说Error: 'openssl' is not supported。
原因是 OpenSSL 3.0 把很多旧 API 标记为废弃或删除了,FFmpeg 3.4.2 的tls_openssl.c还在用旧结构体,直接编译不了。系统里默认装的可能是 OpenSSL 3.0。
解决办法是拉流前先在本地装 OpenSSL 1.1.1,并让 pkg-config 找到它。
sudo apt-get install libssl-dev # 有时这是 1.1.1,有时是 3.0 openssl version # 确认版本如果你必须用 HTTPS 拉流,我建议编译时先不要开--enable-openssl,用--enable-gnutls替代。gnutls 对 3.4.2 的兼容性更好,而且不需要清理旧 OpenSSL。拿不准时,先用 rtmp/rtsp,业务能跑再换 HTTPS。
5.5 系统已装新版 FFmpeg,导致二进制库版本错乱
现象是手动运行/opt/ffmpeg342/bin/ffmpeg没问题,但某个程序调用 FFmpeg 库时崩溃,报version mismath或者symbol not found。
原因是操作系统里已经存在另一个 FFmpeg(可能是系统包或用户自己装的),程序的动态链接把新旧两个版本的.so都加载了,符号冲突。
解决方法是先搞清楚程序加载的是谁的库。
ldd your_program | grep avcodec看输出里libavcodec.so的路径。如果指向/usr/lib/x86_64-linux-gnu/libavcodec.so.57,但你的程序头文件是在/opt/ffmpeg342下编的,那就是混用了。这时候要把程序链接时的-L和-I指向/opt/ffmpeg342,并且在运行前确保LD_LIBRARY_PATH只包含/opt/ffmpeg342/lib,避免两个库同时存在。我一般把老版本编成静态库--disable-shared,程序直接静态链接,彻底杜绝这种问题。
6. 让老版本跑出新效果:用 3.4.2 做 RTSP 拉流与低延迟推流
3.4.2 虽然老,但在网络流处理上一点不落伍。我最近一个项目就是用它做 RTSP 拉流转推,下面这套参数组合实测能在局域网内把延迟压到一秒以内。
6.1 拉取 RTSP 流并转推 RTMP
ffmpeg -rtsp_transport tcp \ -i rtsp://192.168.1.20/stream \ -c:v copy \ -c:a aac \ -f flv rtmp://192.168.1.10/live/stream-rtsp_transport tcp强制用 TCP 拉流,避免 UDP 丢包导致的画面花屏;-c:v copy直接复制视频流,不重新编码,CPU 占用几乎为零,延迟最低。这里只转音频为 AAC,因为源音频可能是 G.711,RTMP 不支持,必须转。如果源音频已经是 AAC,可以把-c:a aac也改成-c:a copy。
6.2 用探测参数进一步降低启动延迟
RTSP 流在开始播放时,FFmpeg 会先探测一段数据,导致启动慢几秒。用下面参数可以缩短。
ffmpeg -rtsp_transport tcp \ -probesize 32768 \ -analyzeduration 1000000 \ -i rtsp://192.168.1.20/stream \ -c:v copy -c:a copy \ -f flv -flvflags no_duration_filesize \ rtmp://192.168.1.10/live/stream-probesize 32768限制探测缓冲区为 32KB,-analyzeduration 1s限制分析时长,它们能显著减少启动等待。-flvflags no_duration_filesize是 3.4.2 里一个比较冷门的参数,它禁止 FLV 头写入时长信息,某些老播放器遇到带 duration 的 flv 流会缓冲异常,去掉后反而更稳定。
6.3 验证延迟与画质的简单方法
我习惯用 ffprobe 看包的时间戳来验证延迟,而不是肉眼看画面。
ffprobe -show_packets -select_streams v \ -i rtmp://192.168.1.10/live/stream 2>&1 \ | grep -m 5 "pts_time"-show_packets会输出每个包的 PTS,-select_streams v只看视频流,grep -m 5取前五个时间戳。如果 PTS 之间差值接近1/fps(比如 30fps 对应约 0.033s),说明流正常;如果出现跳跃或长时间不增长,说明拉流或推流环节有缓冲积压,需要调-probesize或用 TCP 传输。
说到测量,我踩过最深的坑是直接拿手机秒表掐画面延迟,结果把摄像头到屏幕的显示延迟也算了进去。正确做法是找一个视频源打上当前系统时间的水印(用drawtext滤镜),然后从播放端截屏对比时间差,才能算出真实链路延迟。
3.4.2 这套东西,我用了三年还没完全丢开。每次升级版本,总有几个旧设备因为驱动或库依赖跟不上而新代码跑不起来,最后还是要回来编一个 3.4.2 备用。把这个压缩包的编译和避坑经验整理下来,也是给自己留一份使用手册。下次你再拿到一个类似的 rar,先别急着解压到系统目录,按第二、三章的流程验一遍,后面会省很多事。希望帮到你。
本文还有配套的精品资源,点击获取