Watch at Ease看见世界,读懂生活。

科技 · 实用指南

FFprobe 选中了封面?先核实视频流,再传给 FFmpeg

先排除附加图片,数清候选流,再把真实流索引用于同一文件的预览检查。

区分零条、一条和多条非封面视频候选的示意图
原创说明示意图:先数清合格候选流,再选择目标。 Watch at Ease

文件中的某条视频流可能只是封面图片。脚本若把第一条视频记录当成主视频,就可能读到封面的尺寸,或生成错误缩略图。先查看流清单;更换输出编码器并不能证明输入选对了。

本流程适用于完整且不再变化的本地文件,目标是生成单一视频流的检查预览。候选为零条、一条或多条时分别处理;它不会删除媒体库封面、自动判断首选机位,也不负责修复直播流映射。

1. 缩小范围前,保存完整清单

记录文件路径、大小、修改时间,以及 FFmpeg 和 ffprobe 的具体构建版本。使用不会继续变化的副本,尤其要避开仍在下载或被其他软件重写的文件。运行 ffprobe -v error -show_streams -show_format -of json "INPUT",保存标准输出、错误输出和退出码。把 INPUT 换成真实路径。探测失败应单独处理;残缺或空白 JSON 不代表清单获取成功。

逐条查看 index、codec_type、codec_name、尺寸、标签和 disposition。不能因为某个案例的封面使用 MJPEG,就排除所有 MJPEG 流;缺少帧数或看似为零的帧率也不能单独确定主视频。一个独立的 Stack Overflow 问题展示了这种布局:附加 MJPEG 图片位于 H.264 视频之前。

2. 先数候选,再作选择

运行 ffprobe -v error -select_streams V -show_entries stream=index,codec_name,width,height:stream_disposition=default,attached_pic:stream_tags=title,language -of json "INPUT"。这里必须注意大写 V。命令成功后才读取 streams 数组;没有的可选元数据仍记为未知。它会排除被识别为封面的流,但无法识别所有标签错误的静态图片。

零条候选:保留清单,停止视频预览流程;带封面的音频文件可能正常出现这种结果。一条候选:保留其真实 index,再验证画面。多条候选:比较标签、尺寸与预览,明确选择目标轨道。default 标记或更高分辨率可以提供线索,却不能替你决定内容用途。不要仅为了消除歧义而加上 :0。

3. 传递真实索引,不传数组位置

假设过滤后的 JSON 只有一行,内容包含 index: 1。它在数组里是 streams[0],但对应的仍是输入流 1。把同一文件作为 FFmpeg 的第一个输入时,应使用显式映射 0:1:前面的 0 表示输入文件,后面的 1 表示该文件中的流。脚本应把 index 字段与选定文件和选择依据一起保存。

文件、输入顺序或解复用选项改变后,应重新探测。不要把这套流程直接套到直播地址、不断更新的播放列表或持续增长的录制文件:再次打开时看到的清单可能不同。Jellyfin 的一个直播电视报告描述了这种枚举不一致;它是具体用户报告,并非所有本地容器或直播源行为一致的保证。

4. 另存预览,并区分错误分支

以已核实的索引 1 为例,运行 ffmpeg -hide_banner -loglevel error -nostdin -n -i "INPUT" -map 0:1 -frames:v 1 "preview-check.jpg"。替换成实际索引,并使用尚不存在的输出文件名。此命令有意只生成一张图片,不含音频或其他轨道。打开图片,确认可辨认的内容属于目标视频;若开头是黑帧,可另取稍后位置的样本核对。

如果画面选择正确,却仍出现编码器或位流滤镜错误,应检查完整命令,而不是删除封面。Immich 曾有缩略图故障:HEVC 元数据滤镜过宽地作用于视频流,连 MJPEG 附图也被包含。项目修复把滤镜限定到选定流,并于 2026 年 5 月 1 日获批准合并。这说明参数作用范围是另一类问题,不能据此断言当前所有 Immich 安装都有该故障。

5. 用有边界的证据验收选择

我们的合成测试使用 Ubuntu FFmpeg 6.1.1-3ubuntu5。带封面的 MP3 返回一条 v 流、零条 V 流;音频在前的 MP4 返回一条 V 候选,绝对索引为 1,数组位置却是 0;含两条视频的 MP4 返回两条候选,因此流程停止并等待人工选择。单候选预览可以打开,所选流完整解码退出码为零,三份输入文件的哈希均未改变。

这些测试没有复现 Immich 报告中的 DJI 原文件,也未测试直播或所有 FFmpeg 版本。处理自己的文件时,保存清单、选择的索引、完整命令和结果。还可用 ffmpeg -hide_banner -loglevel error -nostdin -i "INPUT" -map 0:1 -f null - 检查所选流解码,须换成正确索引;它会读取该流,耗时可能覆盖整段视频的处理过程。除退出码外,还要检查错误输出。一张正确图片或无报错解码,都不能证明选中了首选机位,或后续导出保留了全部轨道。

数组位置为零但输入流索引为一的示例图
原创说明示意图:JSON 数组位置和输入流索引是不同坐标。 Watch at Ease