FFmpeg:是否可以在可变帧率视频中替换帧?

4

视频处理中的机器学习算法通常是在帧(图像)上工作,而不是在整个视频上。

在我的工作中,我使用ffmpeg将特定场景转换为一系列.png文件,对其进行某些处理(去噪、去模糊、上色、注释、修复等),将结果输出到相同数量的.png文件中,然后使用新帧更新原始视频。

这种方法适用于恒定帧速率(CFR)的视频。我将图片转换成这样(例如,在1:47开始的50帧序列):

ffmpeg -i input.mp4 -vf "select='gte(t,107)*lt(selected_n,50)'" -vsync passthrough '107+%06d.png'

在编辑完图像后,我用替换原始文件的方式进行操作(适用于12.5fps CFR视频):

ffmpeg -i input.mp4 -itsoffset 107 -framerate 25/2 -i '107+%06d.png' -filter_complex "[0]overlay=eof_action=pass" -vsync passthrough -c:a copy output.mp4

然而,我处理的许多视频都是可变帧率(VFR),这产生了一些挑战。

一个简单的解决方案是将VFR视频转换为CFR,无论如何ffmpeg都想这样做,但我想知道是否有可能避免这种情况。原因是CFR要么丢帧,由于机器学习视频处理的目的通常是改善输出,所以我想避免这种情况,要么重复帧 - 但是我正在使用的一个上采样算法使用前一个和下一个帧的数据 - 如果前一个或下一个帧是重复的,则没有数据进行上采样。

通过使用-vsync passthrough,我希望可以简单地删除-framerate选项,并保留原始帧,但是结果命令如下:

ffmpeg -i input.mp4 -itsoffset 107 -i '107+%06d.png' -filter_complex "[0]overlay=eof_action=pass" -vsync passthrough -c:a copy output.mp4

使用ffmpeg的默认帧率为25fps,且会丢失很多帧。有没有可靠的方法来替换VFR视频中的帧?
1个回答

1

是的,可以做到,但这很复杂。为了使此过程可靠地工作,覆盖视频必须与底部视频具有完全相同的帧时间戳。生成这样的VFR视频段叠加需要从源视频中捕获帧时间戳,以生成精确定时的替换段。

该过程的简短版本是用以下命令替换上述命令来提取图像:

ffmpeg -i input.mp4 -vf "select='gte(t,107)*lt(selected_n,50)',showinfo" -vsync passthrough '107+%06d.png' 2>&1 | 'sed s/\r/\n/g' | showinfo2concat.py --prefix="107+" >concat.txt

这需要一个可以下载的脚本,可以在这里找到。编辑图片后,使用以下命令更新源视频:

ffmpeg -i input.mp4 -f concat -safe 0 -i concat.txt -filter_complex"[1]settb=1/90000,setpts=9644455+PTS*25/90000[o];[0:v:0][o]overlay=eof_action=pass" -vsync passthrough -r 90000 output.mp4

其中,90000是时间刻度(时间基准的倒数),9644455是要替换的第一帧的PTS。

有关这些命令实际执行的详细信息,请参见


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接