科技 · 实用指南
FFmpeg 拼接提示 DTS 非单调?接受成片前先审查数据包时间
成功完成流复制拼接,可能保留每一帧解码画面,却压缩播放时间。选择修复方法前,先比较媒体流参数、片段时长和两种时间戳。

FFmpeg 的 DTS 非单调警告本身不能证明画面帧被删除;命令成功退出也不能证明输出可靠。拼接任务可能保留解码后的画面内容,却给它们分配错误的播放时间轴。
先保留输入、拼接列表、完整命令与日志。确认警告实际对应哪条媒体流,再区分参数不兼容、片段时长错误,以及真正缺失的时间戳。替换工作副本前,把内容与时间作为两个不同结果核验。
保留证据,确认实际媒体流
保持原片段不变,把实验输出写入新文件。保存完整 FFmpeg 版本、拼接列表、命令、stderr 与媒体流映射。警告中的输出索引取决于映射;不能默认 0:1 永远是音频,也不能只检查第一条视频流。
对每个输入执行 ffprobe -v error -show_streams -show_format -of json input.mp4,将示例换成真实路径。比较对应媒体流的数量、类型、编码、time_base、画面尺寸、像素格式、采样率和声道布局。额外音轨、字幕或数据需要明确保留;使用自动选择的命令成功,不证明所有需要的媒体流都被包含。
添加时间戳参数前定位边界
针对有问题的视频流,执行 ffprobe -v error -select_streams v:0 -show_packets -show_entries packet=pts_time,dts_time,duration_time -of json input.mp4;另行检查 a:0 或实际对应的流。JSON 可能省略不可得的值。应把它们记为未知而非零,并比较以时间表达的字段,不要直接比较不同时间基准下的原始计数。
检查相关尾部数据包,以及拼接列表中的 duration、inpoint、outpoint 指令。解复用器按时长偏移后续文件;猜测的时长可能在参数一致时仍让下一片段提前开始。帧间编码的剪切也可能输出请求边界附近的额外数据包。容器标称时长不一定等于精确的剪辑切点。
区分缺失时间戳与已有错误时间轴
当前格式参考把 +genpts 定义为:解码时间戳存在时,生成缺失的呈现时间戳。分别检查 PTS 与 DTS。仅列 DTS 的报告出现 N/A,不能证明 PTS 不存在;缺字段或已经出现倒退,都不能直接推导出通用修复命令。
同样,avoid_negative_ts 会平移时间戳,但不能证明时间基准兼容或拼接时长正确。降低日志等级隐藏警告,只改变可见性。测试参数时应保留原始日志,将新的数据包时间、时长与必要内容同基线比较。
按测量结果修复并确认范围
如果测量证据表明只有拼接时长错误,在副本上测试修正后的 duration;不要为了消除警告而编一个数字。媒体流不兼容时,可先制作兼容副本,或采用解码后的 concat 滤镜并重新编码。滤镜要求对应媒体流与从零开始的片段时间戳,分辨率必须明确统一。
同步的视频与音频应一起处理。滤镜对非末尾片段采用最长媒体流的时长,必要时给较短音频补静音;不同帧率可能产生可变帧率输出。应明确选择预期结果。一名历史用户改用 MKV 成功,只证明该个案,不能保证换容器能修复所有输入。
分别验证内容与播放时间
我们用 Ubuntu FFmpeg 6.1.1 测试了四种隔离的纯视频情况:两个两秒 H.264 片段正常拼接为四秒。把首段 duration 写成 0.5 秒,得到 37 条警告与 2.5 秒输出;加上 +genpts 也没有改变结果。另一次时间基准不一致测试产生 50 条警告与 1.967031 秒输出。全部成功退出,且有序的 100 帧解码哈希仍一致。
这些合成实验没有复现你的片段、音频或内容丢失故障。SWGDE 说明解码帧与采样哈希可用于核对内容;时间字段还需单独比较。检查实际结果中的接缝、能识别的首尾内容、同步与预期总时长。哈希一致或编码没有警告,都不能单独证明播放时间正确,也不能恢复来源中不存在的字节。
