3.2 ffprobe 工具:动手前先看清单


3.2 ffprobe:动手前先看清单

本节摘要:ffprobe 是 FFmpeg 的「侦察兵」,不改动文件就能把它的容器、流、编码、时长、元数据全报出来。本节讲透 ffprobe 的常用参数、输出解读,以及如何用 JSON 输出把它接进脚本做批量检测。

学习目标

阅读完本节,你应当能够:

  1. 用 ffprobe 查出一个文件的容器、流、编码、帧率、码率等全部关键信息
  2. 理解默认输出、-show_streams-show_format-show_packets 的区别
  3. -of json-select_streams 把探测结果变成结构化数据,接入自动化

一、一段历史:为什么要先有「侦察兵」

早期的音视频工具链里,分析文件靠人肉:拿十六进制查看器翻文件头,查 MP4 的 box、查 H.264 的 SPS/PPS,光「这个文件是什么格式」就能耗掉半天。ffprobe 把这件事变成了一个命令:它复用 FFmpeg 的解封装与分析能力,把文件从头到尾「读一遍但不开工」,然后列清单给你。

为什么值得专门学它?因为 90% 的转码失败,都源于「你以为输入长什么样」。ffprobe 的价值在于把「我以为」换成「它实际是」,这是后面一切操作的地基。

二、核心原理: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 的输出结构

下面这张图把 ffprobe 的输出层级和对应的命令选项对应起来。

用图记住 ffprobe 的输出结构

图说明:三层侦察

容器层回答「这是什么盒子」,流层回答「里面装了什么货」,帧层回答「货的排列规不规矩」。三层分别对应 -show_format-show_streams-show_frames。脚本化时固定组合 -v error -of json -select_streams,输出干净可解析。

要点回顾

  • 侦察优先:转码前先 ffprobe,把「我以为」换成「它实际是」,避免盲目套参数
  • 三层输出:容器层(-show_format)、流层(-show_streams)、帧层(-show_frames)
  • 编号通用:ffprobe 的 Stream 编号就是 ffmpeg 的 -map 编号,侦察结果可直接当参数
  • 脚本化配方:-v error + -of json + -select_streams,输出干净可解析
  • 时间戳排查:-show_frames 看 pts_time 与 key_frame,能定位音画不同步

下一节看管线的出口验收工具 ffplay——怎么不转码就把滤镜效果和同步问题试出来。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U