如何映射用ffmpeg和视频字幕提取的帧? (帧精度问题)

时间:2019-11-12 15:12:09

标签: python video ffmpeg frame-rate subtitle

想为用ffmpeg提取的帧生成文本文件,其中包含该帧的字幕(如果有的话),在我也使用ffmpeg刻录了字幕的视频上。

我使用带有pysrt的python脚本打开subrip文件并生成文本文件。 我正在做的是,用ffmpeg用帧号命名每个帧,然后,由于它们是以恒定速率提取的,因此我可以使用公式t1 = fnum/fps轻松地检索帧的时间位置,其中{{ 1}}是使用文件名检索的帧的编号,而fnum是传递给ffmpeg进行帧提取的频率。

即使我使用相同的字幕文件来检索时间轴中的文本位置,也就是在视频中使用的那个字幕,我仍然会遇到准确性错误。大多数情况下,我缺少一些文本文件,或者某些文本文件不应该显示。

由于在谈论帧时时间并不是真正连续的,所以我尝试使用带有硬编码字幕的视频的fps重新校准fps,因此我们将fps t称为视频fps(我已经确保字幕刻录前后的视频fps相同)。我得到公式:vfps。 仍然不是100%准确。

例如,我的视频为30fps(t2 = int(t1*vfps)/vfps),而我提取的帧为4fps(vfps=30)。 提取的帧166(fps=4)没有显示字幕。在字幕文件中,上一个字幕以fnum=166结尾,下一个字幕以t_prev=41.330开始,这意味着t_next=41.400应该满足:t_sub,但我不能发生这种情况。

我尝试过的公式:

t_prev < t_sub and t_sub < t_next

使用的命令:

t1 = fnum/fps  # 41.5 > t_next
t2 = int(fnum*vfps/fps)/vfps  # 41.5 > t_next
# is it because of a indexing problem? No:
t3 = (fnum-1)/fps  # 41.25 < t_prev
t4 = int((fnum-1)*vfps/fps)/vfps  # 41.23333333 < t_prev
t5 = int(fnum*vfps/fps - 1)/vfps  # 41.466666 > t_next
t6 = int((fnum-1)*vfps/fps + 1)/vfps  # 41.26666 < t_prev

为什么会发生这种情况,我该如何解决?

我注意到的一件事是,如果我提取原始视频的帧和字幕的帧,对帧进行不同处理,结果不仅是字幕,而且背景也会有变化(这不应该发生) )。如果我两次使用相同的视频进行相同的体验,则差异为零,这意味着帧提取是一致的。

区别代码:

# burning subtitles
# (previously)
# ffmpeg -r 25 -i nosub.mp4 -vf subtitles=sub.srt withsub.mp4
# now:
ffmpeg -i nosub.mp4 -vf subtitles=sub.srt withsub.mp4
# frames extraction
ffmpeg -i withsub.mp4 -vf fps=4 extracted/%05.bmp -hide_banner

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以提取带有准确时间戳的帧,因此

ffmpeg -i nosub.mp4 -vf subtitles=sub.srt,settb=AVTB,select='if(eq(n\,0)\,1\,floor(4*t)-floor(4*prev_t))' -vsync 0 -r 1000 -frame_pts true extracted/%08d.bmp

这将从每个四分之一秒中提取第一帧。输出文件名的长度为8个字符,其中前5位是秒,后3位是毫秒。您可以根据最大文件持续时间更改字段大小。