如何用FFmpeg结合帧时间戳修正OpenCV录制的帧率异常视频?
解决方案
完全可以用FFmpeg直接处理,不需要拆分帧为图片,具体步骤如下:
1. 预处理时间戳文件
你用time.time()生成的是Unix绝对时间戳,需要转换成相对第一帧的时间差(单位:秒),这样FFmpeg才能正确识别每帧的呈现时间(PTS)。
用简单的Python脚本处理原始时间戳文件(假设原始文件名为raw_timestamps.txt,每行一个时间戳):
with open("raw_timestamps.txt", "r") as f_in: timestamps = [float(line.strip()) for line in f_in if line.strip()] base_time = timestamps[0] with open("relative_timestamps.txt", "w") as f_out: for t in timestamps: f_out.write(f"{t - base_time:.6f}\n")
2. 生成正确的VFR视频
用FFmpeg的setpts滤镜替换原视频的错误PTS,生成匹配实际帧率波动的VFR视频:
ffmpeg -i input.mp4 -vf "setpts='file=relative_timestamps.txt'" -an -c:v libx264 -crf 23 -pix_fmt yuv420p correct_vfr.mp4
-an:如果原视频没有音频可保留该参数;若有音频需额外处理同步(可忽略如果不需要音频)-crf 23:x264编码器的质量参数,数值越小质量越高(范围0-51)setpts='file=...':读取相对时间戳文件,将每帧的PTS设置为对应值,还原真实帧率
3. 转换为CFR视频
将VFR视频转成固定30FPS的CFR视频,用-vsync cfr强制帧同步:
ffmpeg -i correct_vfr.mp4 -vsync cfr -r 30 -c:v libx264 -crf 23 -pix_fmt yuv420p final_cfr_30fps.mp4
-vsync cfr:确保输出为恒定帧率,FFmpeg会自动补帧或丢帧匹配30FPS-r 30:指定目标帧率
一步完成(可选)
如果不需要单独保留VFR视频,可以合并两步直接输出CFR视频:
ffmpeg -i input.mp4 -vf "setpts='file=relative_timestamps.txt',fps=30" -an -c:v libx264 -crf 23 -pix_fmt yuv420p final_cfr_30fps.mp4
内容的提问来源于stack exchange,提问作者Bojan
相关产品推荐
相关产品推荐

