资讯动态

Ubuntu 安装新版 FFmpeg 与视频抽帧实战指南

发布时间:2026/10/13 17:48:55 来源:尧图企业网站定制
1. 为什么我不推荐直接用 apt 装 FFmpeg如果你在 Ubuntu 上敲过sudo apt install ffmpeg大概率已经踩过这个坑装完之后ffmpeg -version一看版本号停在 4.x 甚至更早而官方早就迭代到 7.x 了。对于只是转个格式、压个视频的日常需求老版本够用但一旦你要做视频抽帧、逐帧图像分析、批量导出图片序列这类活儿老版本缺新滤镜、缺新编码器、缺硬件加速支持很多参数直接报Unrecognized option非常难受。我自己的经历是这样的早些年做一个视频数据预处理的活儿需要把一批监控视频按固定间隔抽成图片再喂给后面的图像处理流程。当时图省事用了系统自带的 FFmpeg结果发现-vf fps抽帧出来的时间戳对不上某些容器格式还识别不了折腾了大半天才意识到是版本太老。从那以后凡是涉及抽帧、转码这类对版本敏感的任务我一律自己编译或者用官方静态包绝不再碰系统源里的老古董。这篇内容就是把这套流程完整讲清楚在 Ubuntu 上装到较新的 FFmpeg然后用它做视频和图片之间的数据帧提取。所谓数据帧提取说白了就是两个方向——把视频拆成一帧一帧的图片或者把一堆图片合成一段视频。前者用于数据分析、训练素材准备、关键帧抓取后者用于延时摄影、GIF 制作、序列帧回放。适合做计算机视觉、视频处理、多媒体开发的读者也适合任何需要批量处理视频帧的人。先说结论装 FFmpeg 有三条路——系统源、官方静态包、源码编译。我推荐官方静态包省事、版本新、依赖干净追求极致可控或者要特定编译选项的再走源码编译。下面逐个拆。2. 三条安装路线的取舍与实操2.1 系统源安装最省事但版本最旧sudo apt update sudo apt install ffmpeg这条命令谁都会敲优点是依赖自动解决、升级跟着系统走。但 Ubuntu 的 LTS 版本为了稳定性软件包版本往往落后官方一到两年。你在 22.04 上装到的可能是 4.4在 24.04 上大概是 6.x而官方稳定版已经到 7.x 了。判断要不要用这条路看你的需求只是偶尔转个格式、切个片段系统源足够。要做抽帧、滤镜链、新编码器比如 AV1 相关系统源大概率不够。如果你已经装了系统源版本想升级先卸载干净再走下面的路线避免路径冲突sudo apt remove ffmpeg sudo apt autoremove注意卸载时留意有没有别的软件依赖它比如某些录屏工具、媒体播放器。apt autoremove之前先看一眼它打算删什么别把有用的东西一起带走。2.2 官方静态包我平时最常用的方案FFmpeg 官方为 Linux 提供了预编译的静态构建包解压即用不污染系统依赖版本还新。这是我最推荐的路线尤其适合不想折腾编译的人。操作步骤# 下载官方静态包以 amd64 为例具体链接以官方发布页为准 wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz # 解压 tar -xf ffmpeg-release-amd64-static.tar.xz # 进入解压出来的目录目录名带版本号 cd ffmpeg-*-amd64-static # 把可执行文件复制到系统路径 sudo cp ffmpeg ffprobe /usr/local/bin/ # 验证 ffmpeg -version这里有几个细节值得说。第一ffprobe一定要一起复制它是查看媒体信息的工具后面排查抽帧问题全靠它。第二复制到/usr/local/bin而不是/usr/bin是为了和系统包管理器管理的文件区分开将来想删直接删这两个文件就行不会影响 apt。第三如果/usr/local/bin不在你的 PATH 里极少见需要手动加一下。静态包的好处是它把依赖的库都打包进去了你不需要额外装一堆libavcodec-dev之类的东西。缺点是包体积大几十 MB而且更新要手动重新下载。我一般会写个小脚本记录当前版本隔几个月看一眼官方有没有新版。2.3 源码编译要定制就选它什么时候需要自己编译两种情况一是你要启用某些默认构建没开的编码器或滤镜二是你要针对特定硬件做优化比如启用某个 GPU 加速模块。编译流程大致如下# 装编译依赖 sudo apt update sudo apt install -y build-essential yasm nasm pkg-config \ libx264-dev libx265-dev libvpx-dev libfdk-aac-dev \ libmp3lame-dev libopus-dev libass-dev # 拉源码用官方仓库 git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg cd ffmpeg # 配置按需裁剪 ./configure --prefix/usr/local \ --enable-gpl --enable-libx264 --enable-libx265 \ --enable-libvpx --enable-libmp3lame --enable-libopus # 编译-j 后面跟 CPU 核心数 make -j$(nproc) # 安装 sudo make install./configure这一步是灵魂。--enable-gpl会启用 GPL 授权的组件比如 x264如果你要把产物用于闭源分发得注意授权问题。--prefix/usr/local让安装路径和系统隔离。编译时间取决于机器普通四核机器大概十几分钟到半小时。提示编译前务必确认yasm或nasm装好了汇编优化没它俩会直接报错。另外libfdk-aac属于非自由授权很多发行版默认源里没有需要额外配置源嫌麻烦可以先用内置的 aac 编码器顶着。三条路线对比一下路线版本新旧操作难度依赖干净度适合人群系统源旧极低一般轻度使用官方静态包新低高大多数用户源码编译最新高可控需要定制选哪条取决于你对版本和可控性的要求。我个人的默认选择是静态包省心。3. 抽帧之前先用 ffprobe 把视频底细摸清楚很多人一上来就ffmpeg -i input.mp4 output_%04d.png结果抽出来的帧要么数量不对要么尺寸不对要么时间间隔不是自己想要的。问题出在没先搞清楚源视频的基本参数。抽帧这件事七分靠前期分析三分靠命令。3.1 ffprobe 到底看什么ffprobe是 FFmpeg 套件里专门用来分析媒体文件的工具。拿到一个视频我习惯先跑这条命令ffprobe -v error -show_format -show_streams input.mp4输出信息很多重点看这几项r_frame_rate帧率比如30000/1001表示约 29.97 fps。注意它是分数形式别直接当整数用。avg_frame_rate平均帧率和上面可能略有差异。nb_frames总帧数有些容器不写这个字段可能显示 N/A。duration时长单位秒。width/height分辨率。codec_name编码格式比如 h264、hevc。pix_fmt像素格式比如 yuv420p。这些参数直接决定你抽帧的策略。比如帧率是 29.97你想每秒抽一帧就不能简单按每 30 帧取一帧来算否则时间会漂移。3.2 用一条命令拿到干净的关键字段-show_streams输出太啰嗦我更喜欢用-select_streams配合-show_entries精准取值ffprobe -v error -select_streams v:0 \ -show_entries streamwidth,height,r_frame_rate,nb_frames,duration \ -of defaultnoprint_wrappers1 input.mp4输出会是这样清爽的键值对width1920 height1080 r_frame_rate30000/1001 nb_frames5400 duration180.180000v:0表示第一条视频流。有些文件有多条视频流比如带多角度的指定v:0能避免歧义。-of defaultnoprint_wrappers1去掉多余的分隔符方便脚本解析。3.3 帧率是分数别踩这个坑r_frame_rate30000/1001这种写法新手容易直接当成 30000 或者 30 来用。实际上它是 29.97002997...。如果你要按时间抽帧用fps滤镜最稳妥它内部会正确处理分数帧率不需要你自己算。只有在你需要精确控制每 N 帧取一帧时才需要关心这个分数。我踩过一次坑手动按nb_frames / duration算帧率结果因为nb_frames在某些文件里不准算出来的值偏了抽帧间隔全乱。后来学乖了能用滤镜就用滤镜别自己造轮子。4. 视频转图片序列抽帧的几种姿势这是数据帧提取最核心的部分。抽帧不是只有一种抽法按目的不同至少有四种常见策略按固定帧间隔、按固定时间间隔、只抽关键帧、按场景变化抽。下面逐个讲并说清楚各自适合什么场景。4.1 按固定帧间隔抽每 N 帧取一张命令长这样ffmpeg -i input.mp4 -vf selectnot(mod(n\,10)) -vsync vfr output_%05d.pngselect滤镜里的n是帧序号mod(n,10)表示对 10 取余not(...)取反合起来就是帧序号能被 10 整除的帧保留。-vsync vfr是关键它告诉 FFmpeg 用可变帧率输出避免它自作主张补帧或丢帧。这条命令适合什么场景比如你的视频帧率很高60fps但后续分析不需要那么密每 10 帧取一张就够。优点是帧序号严格对齐方便回溯原始位置。注意-vsync vfr在新版本里被标记为过时推荐用-fps_mode vfr替代。如果你用的是 7.x建议换成新写法老写法虽然还能用但会打警告。4.2 按固定时间间隔抽每秒一张这是最常用的抽帧方式做缩略图、做时间序列分析都用它ffmpeg -i input.mp4 -vf fps1 output_%05d.pngfps1表示输出帧率为每秒 1 帧。想要每 2 秒一张就写fps1/2想要每秒 5 张就写fps5。这个滤镜的好处是它基于时间轴工作不管源视频帧率是多少、是不是分数帧率它都能正确按时间间隔取帧。为什么我推荐用fps而不是select因为fps处理的是时间select处理的是帧序号。当源视频帧率不规则比如可变帧率的录屏按帧序号抽会导致时间间隔不均匀而按时间抽则始终均匀。做数据分析时时间均匀性往往比帧序号对齐更重要。4.3 只抽关键帧又快又省空间关键帧I 帧是视频里可以独立解码的帧抽它不需要解码整段视频速度极快ffmpeg -skip_frame nokey -i input.mp4 -vsync vfr -frame_pts true keyframe_%05d.png-skip_frame nokey让解码器跳过所有非关键帧。-frame_pts true让输出文件名带上原始帧的时间戳PTS方便你知道每张图对应视频里的哪个时刻。这个方式适合快速浏览视频内容、生成预览图。缺点是关键帧的间隔不固定取决于编码时的 GOP 设置可能几秒一个也可能十几秒一个不能用来做严格的时间序列。4.4 按场景变化抽自动抓有内容的帧如果你只想抓画面发生明显变化的帧用select配合场景分数ffmpeg -i input.mp4 -vf selectgt(scene,0.3) -vsync vfr scene_%05d.pngscene是 FFmpeg 计算出的场景变化分数范围 0 到 1越大表示变化越剧烈。gt(scene,0.3)表示分数大于 0.3 的帧才保留。阈值需要根据视频内容调动作片调高些访谈类调低些。这个方式特别适合从长视频里挑出有信息量的画面比如从监控录像里找有人经过的片段。但阈值调不好会漏帧或抽太多建议先用小片段试。四种方式对比抽帧方式命令核心时间均匀速度典型用途固定帧间隔selectnot(mod(n,N))否中高帧率降采样固定时间间隔fps1是中缩略图、时序分析只抽关键帧-skip_frame nokey否快快速预览场景变化selectgt(scene,x)否慢内容筛选4.5 输出格式与命名别小看这两个细节输出图片格式直接写扩展名就行.png无损但体积大.jpg有损但小。做数据分析建议 PNG做预览图 JPG 够用。JPG 还能加质量参数ffmpeg -i input.mp4 -vf fps1 -q:v 2 output_%05d.jpg-q:v 2控制 JPG 质量范围 1 到 31数字越小质量越高。2 到 5 之间是肉眼几乎无损的甜区。命名里的%05d是占位符表示 5 位数字、不足补零输出就是output_00001.png、output_00002.png。位数一定要够否则帧数超过位数会乱序。比如你有 10 万帧用%04d就只能到 9999后面会覆盖。我一般用%06d保险。提示抽帧前先确认输出目录存在且可写FFmpeg 不会自动建目录。另外磁盘空间要留够1080p 的 PNG 单张可能好几 MB抽几千帧就是几十 GB。5. 图片序列合成视频反向操作同样有讲究抽帧的反向操作是把一堆图片合成视频。做延时摄影、把处理后的帧重新编码回视频都要用到它。这块的坑不比抽帧少。5.1 基础合成命令ffmpeg -framerate 25 -i img_%05d.png -c:v libx264 -pix_fmt yuv420p output.mp4-framerate 25指定输入图片序列的帧率注意这里是-framerate而不是-r两者在图片序列输入时含义不同。-c:v libx264指定用 H.264 编码。-pix_fmt yuv420p是兼容性关键很多播放器和平台只认这个像素格式不加的话可能生成出来别人打不开。5.2 图片编号不连续怎么办如果你的图片编号有跳号比如img_00001.png、img_00003.pngFFmpeg 默认会在缺号处停止。解决办法是用-start_number指定起始或者干脆用 glob 模式ffmpeg -framerate 25 -pattern_type glob -i *.png -c:v libx264 -pix_fmt yuv420p output.mp4glob 模式会按文件名排序读取所有匹配的图片跳号也不怕。但要注意排序是字典序img_10.png会排在img_2.png前面所以命名时位数一定要对齐。5.3 控制输出质量和体积H.264 的质量用-crf控制范围 0 到 51越小质量越高体积越大。18 到 28 是常用区间23 是默认值ffmpeg -framerate 25 -i img_%05d.png \ -c:v libx264 -crf 20 -preset medium \ -pix_fmt yuv420p output.mp4-preset控制编码速度和压缩率的平衡从ultrafast到veryslow。medium是默认追求速度用fast追求体积用slow。我一般用medium性价比最高。5.4 合成时帧率对不上的排查合成出来发现视频播放速度不对通常是帧率设置和图片数量不匹配。比如你拍了 300 张延时照片想让它播放 10 秒那帧率应该是 30。如果设成 25就会播放 12 秒。这个换算很简单帧率 图片数 / 期望时长。另一个常见问题是合成后视频时长和预期差很多多半是-framerate和-r混用了。记住输入图片序列用-framerate输出视频帧率用-r两者别搞反。6. 抽帧实战里那些文档不会写的坑前面讲的都是标准操作但真正干活时问题往往出在细节上。这一节把我这些年踩过的坑集中说一下都是文档里不会明写、但实际会遇到的。6.1 时间戳漂移为什么抽出来的帧对不上时间用select按帧序号抽帧时输出图片的 PTS 可能和原始时间对不上尤其是可变帧率视频。表现是你以为第 100 张图对应第 10 秒实际可能是第 9.8 秒。解决办法是加-frame_pts true让文件名带上真实 PTS或者改用fps滤镜按时间抽。6.2 内存爆掉长视频抽帧的正确姿势抽一个两小时的 4K 视频如果一次性跑FFmpeg 可能吃满内存。原因是它默认会缓冲。解决办法是加-threads限制线程数或者分段处理# 只处理前 60 秒 ffmpeg -t 60 -i input.mp4 -vf fps1 output_%05d.png-t 60表示只处理 60 秒。分段处理后用脚本拼接结果比一次性硬扛稳得多。6.3 色彩空间转换导致的偏色抽出来的 PNG 颜色和原视频不一样发灰或者偏色通常是色彩空间转换没处理好。视频一般是 YUVPNG 是 RGB转换时如果没指定矩阵颜色会偏。可以显式指定ffmpeg -i input.mp4 -vf fps1,scalein_rangefull:out_rangefull output_%05d.pngin_range和out_range控制色彩范围full表示全范围。具体用哪个取决于源视频不确定就先抽一张对比看看。6.4 硬件加速能快多少值不值得FFmpeg 支持用 GPU 做解码和缩放抽帧速度能快好几倍。以常见的 N 卡为例ffmpeg -hwaccel cuda -i input.mp4 -vf fps1,hwdownload,formatrgb24 output_%05d.png-hwaccel cuda启用硬件解码hwdownload把帧从显存拉回内存formatrgb24转成 PNG 需要的格式。但硬件加速不是万能的它支持的编码格式有限某些老视频用不了而且配置麻烦驱动版本不对就报错。我的建议是先用软件解码跑通流程确认结果正确再考虑上硬件加速。为了快几倍而引入一堆环境问题不划算。6.5 批量处理的脚本化思路实际项目里很少只处理一个视频。我一般写个 shell 脚本遍历目录#!/bin/bash for f in *.mp4; do name${f%.mp4} mkdir -p frames/$name ffmpeg -i $f -vf fps1 frames/$name/%05d.png done要点是每个视频单独建目录避免文件名冲突。${f%.mp4}是去掉扩展名。如果视频很多可以加-loglevel error减少输出或者用并行跑注意别把 CPU 跑满。注意并行跑之前先估算磁盘占用。一个视频抽几百帧几十个视频就是几万张图很容易把磁盘写满。我习惯先跑一个视频看单帧大小再乘以总数估算。7. 几个高频问题的快速定位最后整理一份排查清单遇到问题按这个顺序查基本能定位到原因。现象可能原因排查方向抽帧数量不对帧率是分数、用了 select改用 fps 滤镜用 ffprobe 核对帧率图片时间对不上PTS 漂移加 -frame_pts true颜色偏灰色彩范围不匹配显式指定 in_range/out_range合成视频打不开像素格式不兼容加 -pix_fmt yuv420p合成速度不对帧率设置错核对 -framerate 和图片数内存爆掉长视频一次性处理用 -t 分段限制线程命令报未知参数FFmpeg 版本旧升级到新版我个人在实际操作中的体会是抽帧这件事最容易被低估的就是前期分析。花两分钟用 ffprobe 看清楚源视频的帧率、时长、编码能省下后面半小时的调试。很多人急着敲命令结果在参数上反复试错反而更慢。另外一个小技巧抽帧前先用-t 5只处理前 5 秒快速验证命令和输出是否符合预期确认没问题再去掉-t跑全片。这个习惯帮我避免过好几次跑了一小时才发现参数错了的惨剧。视频处理是典型的慢工出细活前期多花点时间后面就少返工。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑