FFmpeg 三件套常用命令:ffmpeg、ffplay、ffprobe
- 跨平台与构建差异
- 参数位置:-i 前后语义不同
- 1. 媒体流分离与封装
- 2. 转码与压缩
- 3. 视频剪切与拼接
- 4. 提取帧、生成 GIF、截图
- 5. 录制与推流
- 6. ffplay 播放与预览
- 7. ffprobe 媒体信息分析
- 8. YUV 裸数据
- 9. 日志控制与调试
- 10. 常见踩坑
FFmpeg 项目通常提供三个命令行工具,它们共享同一套编解码器和解析逻辑,但定位不同:
| 工具 | 定位 | 典型用途 |
|---|---|---|
ffmpeg |
多媒体处理 | 转码、剪切、封装、推流、截图 |
ffplay |
播放器 | 快速预览、验证解码、播放裸流/RTSP |
ffprobe |
媒体分析 | 查看 codec、时长、码率、帧率等元数据 |
简单关系:
ffmpeg是“生产车间”,负责输入 → 处理 → 输出。ffplay是“试播厅”,让你直接看到或听到结果,不做文件输出。ffprobe是“体检仪”,只读取不修改,输出结构化信息。
三件套命令都遵循类似参数风格,但作用域不同:
ffmpeg [全局/输入选项] -i 输入 [输出选项] 输出
ffplay [选项] 输入
ffprobe [选项] 输入
FFmpeg 命令的参数顺序有讲究,但一般记忆方式如下:
ffmpeg [全局选项] [输入选项] -i 输入 [输出选项] 输出
核心原则:-i 之前的是影响输入读取或全局行为的选项,-i 之后的是影响输出的选项。某些选项(如 -ss、-t)放在输入或输出位置语义不同,放在 -i 前通常更快。
跨平台与构建差异
- 本文的 FFmpeg 参数适用于 Windows、macOS 和 Linux;多行命令中的
\是 Bash/zsh 续行符,Windows PowerShell 应改用反引号,CMD 则使用^。 ffplay依赖 SDL,部分 Linux 发行版的精简包或自编译版本不包含它;用ffplay -version确认是否可用。libx264、libx265等第三方编码器及 NVENC、AMF、VideoToolbox 等硬件编码器取决于 FFmpeg 编译选项、驱动和硬件。先执行ffmpeg -encoders确认编码器存在。- 文中使用的
grep、head是 POSIX Shell 工具;Windows 中可用 PowerShell 的Select-String、Select-Object -First 1替代,或直接使用 ffprobe 的 JSON 输出交给程序解析。
参数位置:-i 前后语义不同
FFmpeg 的选项按 -i 划分作用域:
| 位置 | 作用对象 | 典型选项 |
|---|---|---|
-i 之前 |
输入(解封装/解码)或全局 | -ss、-t、-re、-thread_queue_size |
-i 之后 |
输出(编码/封装) | -c:v、-c:a、-b:v、-s、-r、-f |
1. -ss 的位置差异
# 快但不精确:先 seek 到 30s,再开始解码
ffmpeg -ss 00:00:30 -i input.mp4 -c copy output.mp4
# 慢但精确:从头解码,到 30s 才开始输出
ffmpeg -i input.mp4 -ss 00:00:30 -c:v libx264 output.mp4
- 放
-i前:FFmpeg 直接跳转到最近关键帧,速度快,但-c copy时剪切点会偏移到关键帧。 - 放
-i后:FFmpeg 必须逐帧解码到目标位置,速度慢,但帧级精确。
2. -t 的位置差异
# 只读取输入前 10 秒
ffmpeg -t 10 -i input.mp4 -c copy out.mp4
# 从输出起点算,只输出 10 秒(常与 -ss 后位置配合)
ffmpeg -i input.mp4 -ss 30 -t 10 -c copy out.mp4
3. 为什么 -i 前通常更快
-i 前的选项作用于 demuxer 阶段,可以跳过部分输入数据;-i 后的选项作用于输出阶段,通常要等解码器完整跑过对应片段。
4. 常见组合示例
ffmpeg -ss 00:01:30 -i input.mp4 -t 20 -c copy output.mp4
这里 -ss 00:01:30 在 -i 前快速定位,‑t 20 在 -i 后控制输出 20 秒,是“快切 + 控长”的典型写法。
1. 媒体流分离与封装
分离视频、音频流
# 只保留视频,去掉音频
ffmpeg -i input.mp4 -vcodec copy -an output_video.mp4
# 只保留音频,去掉视频
ffmpeg -i input.mp4 -acodec copy -vn output_audio.aac
-an:不输出音频(audio none)-vn:不输出视频(video none)-c copy/-vcodec copy/-acodec copy:直接复制流,不重新编码,速度快且无损
视频解复用为原始码流
# H.264 裸流(Annex B)
ffmpeg -i test.mp4 -c:v copy -an -f h264 test.h264
ffmpeg -i test.avi -c:v copy -an -f h264 test.h264
视频封装(音视频合并)
ffmpeg -i video.mp4 -i audio.aac -c copy output.mp4
ffmpeg -i video.mp4 -i audio.aac -vcodec copy -acodec copy output.mp4
如果合并后音画不同步,通常是因为两个文件的时间基不一致,需要重新编码至少其中一路,或者显式指定时间戳:
ffmpeg -i video.mp4 -i audio.aac -c:v copy -c:a aac -shortest output.mp4
-shortest:在较短流结束时停止输出,避免一路流结束后出现静音/黑屏
2. 转码与压缩
常见转码
# 转码为 H.264 裸流
ffmpeg -i test.mp4 -c:v libx264 -s 352x278 -an -f h264 test.h264
# 禁用 B 帧、指定 GOP 长度
ffmpeg -i test.mp4 -c:v libx264 -bf 0 -g 25 -s 352x278 -an -f h264 test.h264
# 转码为 Xvid 封装
ffmpeg -i test.avi -vcodec mpeg4 -vtag xvid -qscale:v 0 test_xvid.avi
# 转码为 H.265/HEVC,通常能以更低码率达到相近画质
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -tag:v hvc1 -c:a aac output.mp4
-crf:libx265 默认 28,范围 051,越小质量越高;同画质下比 libx264 的 crf 值通常高 46-tag:v hvc1:在 MP4 容器中标记为hvc1,确保 macOS/iOS 播放器兼容(默认hev1在 QuickTime 中可能无法硬解)- 硬件加速编码可用
hevc_nvenc(NVIDIA)、hevc_amf(AMD)或hevc_videotoolbox(macOS)
常用视频参数:
| 参数 | 含义 | 说明 |
|---|---|---|
-b:v |
视频码率 | 如 -b:v 1000k;不指定时由编码器、码率控制模式和输入决定 |
-r |
帧率 | 如 -r 30;不指定时通常保留输入时间戳节奏 |
-s |
分辨率 | 如 1920x1080,注意用 x 而非 * |
-aspect |
画面比例 | 如 16:9、4:3 |
-g |
GOP 大小 | 关键帧间隔,影响 seek 精度和码率 |
-bf |
B 帧数量 | 设为 0 可降低编码/解码延迟 |
-vcodec / -c:v |
视频编码器 | 如 libx264、hevc_nvenc、copy |
-vn |
不输出视频 | 提取音频时常用 |
常用音频参数:
| 参数 | 含义 | 说明 |
|---|---|---|
-ar |
采样率 | 如 44100、48000 |
-ac |
声道数 | 如 1(单声道)、2(立体声) |
-b:a |
音频码率 | 如 128k |
-acodec / -c:a |
音频编码器 | 如 aac、libmp3lame、copy |
-an |
不输出音频 | 提取视频时常用 |
3. 视频剪切与拼接
按时间剪切
ffmpeg -ss 00:01:30 -i input.mp4 -t 20 -c copy output.mp4
-ss 00:01:30:从 1 分 30 秒开始-t 20:持续 20 秒
快速但不精确:copy 模式下剪切点会就近对齐到关键帧,可能导致前后多几帧。需要精确到帧时改用重新编码:
ffmpeg -ss 00:01:30 -t 20 -i input.mp4 -c:v libx264 -c:a aac output.mp4
新版 FFmpeg 也支持在 -i 后写 -ss,这样语义上是“先读取到该位置再处理”,精度更高但速度较慢:
ffmpeg -i input.mp4 -ss 00:01:30 -t 20 -c:v libx264 -c:a aac output.mp4
拼接多个视频
推荐用 concat demuxer,先准备列表文件 list.txt:
file 'part1.mp4'
file 'part2.mp4'
file 'part3.mp4'
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4
-safe 0:允许使用绝对路径或特殊字符路径- 拼接文件格式、分辨率、编码参数必须一致;不一致时先统一转码
4. 提取帧、生成 GIF、截图
提取视频帧为图片
# 每秒 1 帧
ffmpeg -i input.mp4 -r 1 -f image2 image-%03d.jpeg
# 按固定帧率 30.5 fps 提取
ffmpeg -i input.mp4 -vf fps=30.5 %3d.jpg
# 每 2 秒一帧
ffmpeg -i input.mp4 -vf fps=1/2 output_%03d.jpg
# 缩放为原尺寸一半,指定画质
ffmpeg -i input.mp4 -vf "scale=iw/2:ih/2" -qscale:v 2 -r 1 output_%03d.jpg
-qscale:v/-q:v:JPEG 质量,范围 2~31,越小质量越高。视频编码时推荐用-crf替代,能更好平衡质量与码率-f image2:强制输出为图片序列,通常可省略,FFmpeg 会根据扩展名自动推断
生成 GIF
ffmpeg -i input.mp4 \
-vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=128[p];[s1][p]paletteuse" \
output.gif
fps=10:GIF 帧率scale=320:-1:宽度 320,高度按比例lanczos:缩放算法,质量较好palettegen/paletteuse:生成并应用调色板,减少颜色断层
5. 录制与推流
录制 RTSP 流
ffmpeg -rtsp_transport tcp -i rtsp://192.168.3.205:5555/test -c copy out.mkv
-
-rtsp_transport tcp可降低复杂网络环境下 UDP 丢包造成的花屏;低延迟场景可按实际网络改回 UDP。 -
选用 MKV 是因为它更适合流复制和进程意外中断;若必须交付 MP4,建议按时间分段输出,避免异常中断时索引未写完整。
-
HTTP/HTTPS 流可使用协议层重连选项;它们必须放在对应的
-i前:ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 \ -i https://example.com/live.ts -c copy out.ts-reconnect、-reconnect_streamed、-reconnect_delay_max是 HTTP 协议选项,不能用于 RTSP;RTSP 断流自动重连应由调用脚本或进程守护实现。
循环 RTMP 推流
ffmpeg -stream_loop -1 -i zyhc.mp4 \
-c:a aac -ar 44100 -b:a 48k \
-c:v libx264 -b:v 1024k \
-f flv rtmp://192.168.100.240:8020/live/1234
-stream_loop -1:无限循环输入文件-f flv:RTMP 通常要求 FLV 封装格式
6. ffplay 播放与预览
ffplay 是 FFmpeg 自带的简单播放器,基于 SDL。它不做文件输出,只用于快速验证媒体文件能否正常解码、画面是否正确、音频是否同步。
基础播放
ffplay input.mp4
ffplay input.mp3
ffplay input.wav
常用播放选项
# 静音播放
ffplay -an input.mp4
# 只播放音频
ffplay -vn input.mp4
# 循环播放
ffplay -loop 0 input.mp4
# 从指定时间开始播放
ffplay -ss 00:01:30 input.mp4
# 限制播放时长
ffplay -t 20 input.mp4
# 指定窗口大小
ffplay -x 1280 -y 720 input.mp4
# 指定视频滤镜(实时预览效果)
ffplay -vf "scale=640:360,eq=contrast=1.2" input.mp4
# 播放时显示更多信息
ffplay -showmode 1 input.mp4
| 参数 | 含义 |
|---|---|
-an |
不播放音频 |
-vn |
不播放视频 |
-loop 0 |
无限循环 |
-ss |
起始播放时间 |
-t |
播放时长 |
-x / -y |
窗口宽高 |
-vf |
视频滤镜 |
-af |
音频滤镜 |
-showmode |
显示模式(0=视频,1=波形,2=频谱) |
播放网络流与裸数据
# 播放 RTSP 流
ffplay -rtsp_transport tcp rtsp://192.168.3.205:5555/test
# 播放 RTMP 流
ffplay rtmp://192.168.100.240:8020/live/1234
# 播放 YUV 裸数据
ffplay -f rawvideo -video_size 1920x1080 -pix_fmt yuv420p input.yuv
# 播放 PCM 裸音频
ffplay -f s16le -ar 44100 -ac 2 input.pcm
-rtsp_transport tcp:强制使用 TCP 传输 RTSP,避免 UDP 在复杂网络下丢包花屏- 裸数据(YUV/PCM)没有文件头,必须手动指定格式、分辨率、采样率等参数
7. ffprobe 媒体信息分析
ffprobe 用于探测媒体文件的元数据,不修改文件。它的输出格式灵活,可默认文本、JSON、XML、CSV 等,适合脚本化分析。
常用输出格式
# 默认文本输出
ffprobe input.mp4
# JSON 输出完整信息
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
# XML 输出
ffprobe -v quiet -print_format xml -show_format -show_streams input.mp4
# CSV 输出,便于脚本解析
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate,bit_rate -of csv=p=0 input.mp4
查询指定流
# 只看视频流(v:0 表示第一个视频流)
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate,bit_rate -of default input.mp4
# 只看音频流(a:0 表示第一个音频流)
ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,sample_rate,channels,bit_rate -of default input.mp4
# 查看容器格式信息
ffprobe -v error -show_entries format=format_name,duration,bit_rate,size -of default input.mp4
帧与包信息
# 查看所有帧信息(输出量大,建议加 -v quiet 或输出到文件)
ffprobe -v quiet -print_format json -show_frames input.mp4 > frames.json
# 查看所有包信息
ffprobe -v quiet -print_format json -show_packets input.mp4 > packets.json
# 统计视频总帧数(需完整遍历,较慢)
ffprobe -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames -of default input.mp4
# 只查看关键帧时间戳
ffprobe -v error -select_streams v:0 -skip_frame nokey -show_frames \
-show_entries frame=best_effort_timestamp_time -of csv=p=0 input.mp4
| 参数 | 含义 |
|---|---|
-show_format |
显示容器格式信息 |
-show_streams |
显示所有流信息 |
-show_frames |
显示每帧信息 |
-show_packets |
显示每个包信息 |
-select_streams v:0 |
选择第一个视频流 |
-select_streams a:0 |
选择第一个音频流 |
-count_frames |
统计帧数 |
-print_format |
输出格式:default/json/xml/csv/ini |
-show_entries |
只显示指定字段 |
-of |
同 -print_format |
常见脚本用法
# 获取视频时长(秒)
ffprobe -v error -show_entries format=duration -of csv=p=0 input.mp4
# 获取视频分辨率
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 input.mp4
# 判断是否为关键帧开头的文件
ffprobe -v error -select_streams v:0 -show_frames \
-show_entries frame=key_frame -of csv=p=0 input.mp4 | head -1
输出 1 表示首帧是关键帧。不要以 pict_type=I 判断:I 帧不一定是可随机访问的关键帧。
8. YUV 裸数据
YUV 转 AVI
ffmpeg -s 1920x1080 -pix_fmt yuv420p -f rawvideo -i input.yuv -c:v mpeg4 output.avi
YUV 裸数据没有文件头,必须指定 -s(分辨率)、-pix_fmt(像素格式),否则 FFmpeg 无法解析。
常见 YUV 像素格式:
yuv420p:最常用,4:2:0 采样yuv422p:4:2:2 采样yuv444p:4:4:4 采样,无压缩色度
9. 日志控制与调试
ffmpeg -hide_banner -v warning -i input.mp4 -r 10 %04d.jpg
-hide_banner:隐藏版本和编译配置信息-v/-loglevel:日志级别
级别从多到少:
debug > verbose > info > warning > error > fatal > panic > quiet
quiet:完全不输出,配合-stats可以只显示进度warning:只显示警告和错误,适合脚本批量处理
10. 常见踩坑
-s 352*278写法错误:应使用x,即-s 352x278,否则部分版本会报错。copy模式下无法同时改码率或分辨率:-c copy意味着不解码,所以-b:v、-s等参数无效。需要改这些参数时必须重新编码。- YUV 文件必须指定格式参数:缺少
-s或-pix_fmt会报Invalid data found。 - GIF 调色板数量:默认 256 色,如果颜色断层严重,可提升
max_colors或改用split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse=dither=bayer。 - 拼接失败:先检查各文件编码是否一致;不一致时先用统一参数转码一次再 concat。
本文链接:FFmpeg 三件套常用命令:ffmpeg、ffplay、ffprobe - https://h89.cn/archives/244.html
版权声明:原创文章 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接和本声明。