问题出现得很突然,日志倒是留得挺全。视频 25fps,用 -vf fps=2 抽帧做画面理解,回填字幕时按帧序号乘 0.5 秒算时间,结果每条字幕比实际早 0.4 秒,越往后偏移越大。
刚开始盯着「帧序号从 1 开始,公式按 0 推的」,折腾了半个多小时,排掉了。
把日志和配置对完,能解释这个现象的基本就这几处。fps 滤镜按可变帧率重采样,序号不再均分。也可能是容器 start_time 不是 0,时间轴整体前移。
少数情况下是编码时间基与秒换算没除对分母。
第一件事是看容器的起始时间与时间基
ffprobe -v error -show_entries format=start_time,duration -show_entries stream=time_base,r_frame_rate -of json in.mp4
随后改用按时间点精确抽帧
ffmpeg -y -ss 12.5 -i in.mp4 -frames:v 1 -q:v 2 shot_12_5.jpg
从帧的 pts 直接算秒数
ffmpeg -i in.mp4 -vf "fps=2,showinfo" -f null - 2>&1 | grep pts_time | head -5
等前面都确认过,再按修正后的时间轴重排字幕
python retime.py --srt in.srt --offset -0.4 --out fixed.srt
别只看报错消失,验证要多做一步。抽帧时间与 pts 对得上,字幕落在画面对应位置,最后一条的偏差不超过 40 毫秒。
容易忽略的是,按帧序号乘间隔只在恒定帧率且从零开始时成立,真实素材几乎不满足,直接读 pts 最稳。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
