本文主要记录在自托管媒体库场景下,扫描探测工具在 MediaInfo 与 ffprobe 之间应如何分工:速度差从哪里来、字段面谁更宽、哪些事实更适合交给 FFmpeg 视角,以及为何不宜一次性把扫描主数据源全量切到 ffprobe。

以 Octans 一类媒体库为例,扫描阶段要同时服务「详情页展示」和「播放决策输入」。两者对字段的语义并不相同:展示侧关心轨大小、商业编码名、HDR 文案;播放侧更关心全局 stream index、pix_fmt、色彩字段和 Dolby Vision side data。下面基于一次约千级文件的只读对比实验整理结论,命令与路径已通用化。

背景与问题

常见直觉是:既然播放最终走 FFmpeg,扫描是不是也应该统一用 ffprobe?

需要注意的是:

  • 轻量结构探测深度帧/包扫描不是同一种成本。
  • JSON 体积更大不等于业务字段更全
  • 播放链路需要的「权威 index」与 UI 需要的「可读元数据」可以分层,不必同一工具包办。

因此问题应收敛为:在真实片库上,轻量 ffprobe 与 MediaInfo 各擅长什么;全量替换会丢什么;更稳妥的路线是什么。

对比方法(可复现边界)

命令边界

本轮对比使用的是轻量探测,不是全文件深读:

# MediaInfo:JSON 输出
mediainfo --Output=JSON "$PATH"

# ffprobe:format / streams / chapters / programs,不读 packets / frames
ffprobe \
  -hide_banner \
  -loglevel error \
  -show_format \
  -show_streams \
  -show_chapters \
  -show_programs \
  -of json \
  "$PATH"

脚本对同一批文件交替调用顺序(偶数先 MediaInfo、奇数先 ffprobe),降低缓存顺序带来的系统性偏差。工具版本因环境而异;示例口径约为 MediaInfoLib 26.x 与 FFmpeg 7.x 系 ffprobe。

样本与成功率

某次真实库只读抽样(数量级示意,非普适性能表):

结果
样本规模约 1000 个文件(MKV 为主,兼 MP4 / WebM / TS)
两者命令成功率均可 100%(本轮无失败)
轨数量粗比视频 / 音频 / 字幕条数一致;等于字段值一致

这里的「轨数量一致」只说明 demux 层看到的轨条数对齐,不能用来证明展示字段可互相替换。

速度:轻量 ffprobe 明显更快

在上述轻量命令下,全库墙钟与分位数通常呈现:

指标(示意)MediaInfo轻量 ffprobe
总耗时量级数百秒级数十秒级
中位数单文件百毫秒~近秒数十毫秒
优势场景大体积 MKV 差距最大

需要强调的是:快的是命令边界,不是工具名本身

  • 轻量 ffprobe 只取 demuxer 能较快给出的 format / stream / tag / side data。
  • MediaInfo 更像媒体详情分析器,会归一化更多展示型字段(每轨大小、码率模式、商业名称、HDR mastering 文案等),成本更高。
  • 若改成 -show_packets / -show_frames / -count_frames 一类深度模式,ffprobe 的速度优势会明显缩小,甚至可能更慢。不能把轻量对比的速度结论外推到深度扫描。

与 ParseSpeed 的关系(旁证)

若扫描侧仍以 MediaInfo 为主,还可单独调 ParseSpeed 一类读取深度参数。经验上:

  • 中等 ParseSpeed(例如 0.3~0.7)在大库上墙钟接近,表级行数往往一致。
  • ParseSpeed=1 对真实大文件接近深读全文件,全量扫描可能进入「数十小时」量级,不适合作为线上库默认。
  • 个别极低 ParseSpeed 可能在部分库上造成字段快照差异,需要按字段验收,不能只看任务成功。

结论:扫描加速优先靠并发度、缓存、ParseSpeed 与是否二次深读,而不是假设「换成 ffprobe 就一定永远快」。

字段面:谁更宽、谁更贴播放

基础字段

容器格式、总时长、文件大小、总体码率、主视频编码与分辨率、主音频编码与采样率等,两者通常都能覆盖。字幕格式在本轮样本上也可对齐条数。

MediaInfo 更强的展示型字段

领域示例说明
轨大小视频 / 音频 StreamSize轻量 ffprobe 往往没有统一输出
码率语义轨码率、BitRate_Modeffprobe 覆盖因容器而异
音频展示商业名称、Delay、部分轨时长UI / NFO 友好
HDR10 文案mastering display、MaxCLL / MaxFALL轻量 ffprobe 常缺可直接用的字段
HDR / DV 文本HDR_Format* 系列覆盖面往往更宽

ffprobe 更贴播放链路的字段

领域示例说明
映射streams[].index与 FFmpeg -map 0:<index> 一致的权威 index
类型codec_type与 FFmpeg 实际处理一致
解码视角codec_nameprofilepix_fmt播放 / 滤镜输入
色彩color_range / color_space / transfer / primariestone mapping 决策更一致
DV side datadv_profiledv_bl_signal_compatibility_id部分场景 MediaInfo 文案模糊时的补强
TSprograms[]部分 TS 仅 ffprobe 暴露 program 结构
dispositiondefault / forced 等结构稳定,利于选轨与诊断

输出形态不要误读

  • ffprobe 的 JSON 平均更大,是因为每个 stream 都带大量固定结构字段(disposition、frame rate、time_base、tags 等)。
  • MediaInfo 的字段路径种类往往更多,更像「细分语义字典」。
  • 不能只用「JSON 更大」或「叶子更多」判断谁更全面,必须按业务字段验收。

路线建议:展示主源 + 播放补强

不建议当前全量替换 MediaInfo

主要风险:

  1. 丢失展示型字段(轨大小、商业名、Delay、HDR10 mastering 等)。
  2. 要用 ffprobe 补齐同类信息,往往要解析容器私有 tags(如 MKV 的 BPS / DURATION / NUMBER_OF_BYTES),再写一层归一化;复杂度不比维护 MediaInfo 主源低。
  3. 为补字段改深度扫描后,轻量对比的速度故事不再成立。

建议的职责分层

层级主来源用途
展示元数据MediaInfo详情页、列表、NFO、轨展示文案
播放事实ffprobe(窄补强)stream index、codec/pix/color、DV side data、program、disposition
业务归一化应用侧 resolver语言、标题、动态范围枚举、播放候选

短期可执行口径:

  1. 扫描展示仍以 MediaInfo 为主。
  2. 播放映射 index、DV configuration 等由 ffprobe 补强,避免把 MediaInfo 文案直接当 FFmpeg 契约。
  3. 逐字段迁移,不做一次性全替换;每个字段都要按容器做覆盖率抽检。
  4. 若评估深度 ffprobe,必须重跑基准,不能复用轻量速度表。

后续可验证项(未完成不等于已支持)

验证项目的
解析 MKV tags 中的时长 / 字节 / BPS是否能部分替代轨时长与大小
分容器比较 tag 稳定性避免把 MKV 私有 tag 当通用字段
小样本深度 ffprobe 基准补字段后是否仍有性能收益
HDR10 mastering 是否可通过其它参数暴露展示字段有无替代路线
planner 输入是否全部切到 FFmpeg 视角字段减少文案字段进入播放判断

注意事项

  1. 本文是实验与路线判断,不是某一版本扫描器的实现契约。
  2. 耗时与覆盖率数字随片库、磁盘、工具版本变化;文中表格用于说明量级与分工,不作为 SLA。
  3. 「轨数量一致」≠「字段可互换」。
  4. 内网报告目录、数据库路径、制品桶地址不应出现在对外文档;复现时用自有样本与本地输出目录即可。

相关阅读

同系列还可对照:

来源

本文改写自 Octans 项目研究文档中 MediaInfo / ffprobe 探测对比结论,并吸收 MediaInfo ParseSpeed 扫描基准中的旁证。命令与路径已通用化;具体覆盖率以目标环境复测为准。