为什么 image2 muxer 选项 frame_pts 是针对文件名的,而不是生成 PTS 而是生成索引号?我如何在文件名中获取 PTS?

为什么 image2 muxer 选项 frame_pts 是针对文件名的,而不是生成 PTS 而是生成索引号?我如何在文件名中获取 PTS?

我似乎对 PTS (显示时间戳) 的理解是,它总是以 time_base 的整数单位进行编码,time_base 是秒数的一小部分。我们有关系time=PTS*time_base

相反,我们有帧索引,通常在过滤器表达式变量中标记为“N”或“POS”。当我们假设帧速率恒定时,我们通常会利用关系N=time*frame_rate=PTS*time_base*frame_rate

这是我们几乎在 ffmpeg 中随处可见的,尤其是在 FFPROBE 和 showinfo 过滤器的输出以及 setpts 过滤器的变量中。所有上述模块都对 time、pts、n、position、frame_rate、time_base 进行了明确的区分和命名。

好吧,我承认 drawtext 过滤器会在我们访问“pts”函数时打印时间,但我认为这是一个非常糟糕的名字。

然后我尝试使用如下命令来提取所有帧,并尝试使用 image2 muxer 的文件名输出中的帧 PTS 来识别它们,以便轻松地将它们与 FFPROBE 的输出进行比较。SS 跳过第一秒,因此我们可以确认它不是从零开始的索引,copyts 保留源时间戳,vsync=0 保证我们在源帧的时间准确输出帧,而不会丢失或重复任何帧。 ffmpeg -ss 1 -copyts -i input.mp4 -vsync 0 -f image2 -frame_pts 1 output_%05d.jpg

当我对一个帧速率为 25 fps、时间基数为 1/12800 秒的文件使用此命令并像上面一样跳过第一秒时,第一个文件是“output_025.jpg”,而 ffprobe 显示时间 1 秒是 12800 PTS。这证实了这一点PTS=N/frame_rate/time_base=25/25*12800=12800。对于任何探测的帧,计算方法都相同,只是 PTS、时间和位置/索引的设置不同。

我们应该期望-FRAME_PTS生成一个 PTS,但我们得到的却是文件名中的帧索引。

文档中也明确写出了这一点。

为什么 image2 muxer-frame_pts如此不连贯?是不是因为它的名字不好,还是因为它的行为不正确?我是不是误解了什么?

是否有技巧可以在文件名中获取 PTS ?我不需要帮助来使用外部工具来解析和重命名输出,但我宁愿使用更简单的方法。

到目前为止,我只找到了 Gyan 的这个解决方法和另一个令人困惑的答案。Gyanhttps://superuser.com/a/1421195/549957 超级新手AU4000https://superuser.com/a/1479491/549957

上面链接的 Gyan 答案让我遇到了麻烦

  • 理解为什么-r选项不会发生-vsync 0严重矛盾,尽管文档中的说法完全相反,-r 选项可以复制/删除帧,而 vsync 0 选项可以禁用它
    • tldr 为什么当我增加 -r 时我没有得到额外的帧图像,是因为 vsync 0 吗?
  • 使用输出帧速率来伪造 PTS 代替索引的一般规则是什么?
    • Gyan 写了关于设置 -r 1000 来写毫秒这样的数字,但我想要一个 PTS
    • 我认为我可以使用 time_base 的乘法逆元作为 -r 帧速率来欺骗索引以反映 PTS,但我不确定它是否能在任何地方一致地起作用

答案1

默认情况下,image2 多路复用器将设置输出流是输出帧速率的倒数。这就是我设置-r 1000的原因-vsync 0,以获得相当于毫秒值的索引。

为了保持输入流的时间基准,添加-enc_time_base -1为输出选项。

相关内容