本节摘要:ffprobe 是 FFmpeg 的「侦察兵」,不改动文件就能把它的容器、流、编码、时长、元数据全报出来。本节讲透 ffprobe 的常用参数、输出解读,以及如何用 JSON 输出把它接进脚本做批量检测。
阅读完本节,你应当能够:
-show_streams、-show_format、-show_packets 的区别-of json 和 -select_streams 把探测结果变成结构化数据,接入自动化早期的音视频工具链里,分析文件靠人肉:拿十六进制查看器翻文件头,查 MP4 的 box、查 H.264 的 SPS/PPS,光「这个文件是什么格式」就能耗掉半天。ffprobe 把这件事变成了一个命令:它复用 FFmpeg 的解封装与分析能力,把文件从头到尾「读一遍但不开工」,然后列清单给你。
为什么值得专门学它?因为 90% 的转码失败,都源于「你以为输入长什么样」。ffprobe 的价值在于把「我以为」换成「它实际是」,这是后面一切操作的地基。
ffprobe 的输出分成几层,各取所需:
-show_streams:每条流的信息,最常用-show_format:容器级信息(时长、总码率、元数据)-show_packets:逐包信息,调试帧级问题用-show_frames:逐帧信息,分析时间戳用先看默认输出长什么样:
ffprobe input.mp4
输出(节选):
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4': Duration: 00:00:10.04, start: 0.000000, bitrate: 952 kb/s Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720, 30 fps, 750 kb/s, SAR 1:1 DAR 16:9 Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 192 kb/s
解读要点:
Input #0, mov,mp4,...:容器是 MP4 家族的 MOV 格式Duration: 10.04:总时长 10 秒零 4 毫秒Stream #0:0:第一条流,视频;h264 (High):H.264 High Profile;yuv420p:像素格式;1280x720:分辨率;30 fps:帧率Stream #0:1:第二条流,音频;aac (LC):AAC LC 档;48000 Hz:采样率;stereo:双声道这条命令几秒就能跑完,但它给出的信息,足够你判断「这个文件能不能直接进某个管线」。
# 只显示视频流,过滤成 JSON ffprobe -v error -select_streams v:0 -show_streams -of json input.mp4
输出(节选):
{ "streams": [ { "index": 0, "codec_name": "h264", "profile": "High", "width": 1280, "height": 720, "r_frame_rate": "30/1", "avg_frame_rate": "30/1", "bit_rate": "750000", "pix_fmt": "yuv420p" } ] }
-select_streams v:0 表示只选第 0 条视频流;a:0 选音频;-of json 把输出变成 JSON。这是脚本化的关键——后面接 jq、Python 都能直接解析。
# 列出所有关键帧的时间戳,排查音画不同步 ffprobe -v error -show_frames -select_streams v:0 -show_entries frame=key_frame,pts_time -of csv input.mp4
输出(节选):
frame,1,0.000000 frame,0,0.033000 frame,0,0.066000 frame,0,0.099000 frame,1,0.200000
第一行 frame,1,0.000000:第 0 帧是关键帧(key_frame=1)且 PTS 为 0;后续帧间隔约 0.033 秒(即 30 fps)。如果看到 pts_time 出现负值或乱序,时间轴大概率有问题。
# 遍历目录下所有 mp4,逐个输出「文件名: 分辨率: 帧率」 for f in *.mp4; do info=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height,avg_frame_rate -of csv=p=0 "$f") echo "$f: $info" done
结果示意:
clip1.mp4: 1280,720,30/1 clip2.mp4: 1920,1080,25/1 vertical.mp4: 1080,1920,30/1
这就是「容器与流的侦察」最实际的应用:先看清全部素材,再决定转码策略,避免对每个文件盲目套同一套参数。
⚠️ 常见坑:
-v error不加上时,ffprobe 会把版本信息和进度都打到 stderr,脚本里一旦用2>重定向就会混入垃圾。固定-v error是脚本化第一习惯。
💡 关键直觉:ffprobe 看到的「Stream #0:0」编号,就是 ffmpeg 里
-map 0:0的编号。探测输出的编号与命令输入的编号完全对应,侦察结果可以直接当命令参数用。
下面这张图把 ffprobe 的输出层级和对应的命令选项对应起来。

容器层回答「这是什么盒子」,流层回答「里面装了什么货」,帧层回答「货的排列规不规矩」。三层分别对应 -show_format、-show_streams、-show_frames。脚本化时固定组合 -v error -of json -select_streams,输出干净可解析。
下一节看管线的出口验收工具 ffplay——怎么不转码就把滤镜效果和同步问题试出来。