【问题标题】:Insert keyframe into m4v/mp4 at specific times在特定时间将关键帧插入 m4v/mp4
【发布时间】:2018-08-23 22:48:19
【问题描述】:

我有一个面向教育工作者的程序(使用 electronjs 框架编写)播放视频,跳到视频中的预设点,如配套 JSON 文件中定义的那样。有时跳过后会出现明显的延迟,this answer 表明存在延迟是因为关键帧不常见。

假设这是正确的,我想在我知道播放器将跳到的 mp4 文件中的确切点插入关键帧。但是,其中一些视频文件已经很大,所以我不想减少关键帧间隔,从而使文件变得更大。我只需要强制整个文件中的几个关键帧。

我希望能够传递一个参数(例如,ffmpeg)以及我想要强制关键帧的时间。最好不要重新编码整个视频(就像this unanswered question),但如果我必须重新编码视频,我也可以这样做。

【问题讨论】:

  • 你看过 -force_key_frames 选项吗?例如ffmpeg -i input.mp4 -force_key_frames 0:05:00,0:10:00 out.mp4 ... 这将使关键帧尽可能接近 5 和 10 秒标记
  • 理论上,这可以在不重新编码整个视频的情况下完成 - 基本思想是将源流分段为每段一个 GOP。将违规片段重新编码为与源相同的比特流参数,然后使用 concat demuxer 重新拼接。
  • @Offbeatmammal 您的示例和文档都使用 HH:MM:SS 格式的时间。时间可以用秒来表示吗? (例如 7200.132 而不是 2:00:00.132
  • 如果您只提供一个数字(没有冒号),它看起来确实会恢复为秒。检查是否在您想要的位置插入了框架的快速方法是/ffprobe -select_streams v:0 -skip_frame nokey -show_entries frame=pkt_pts_time out.mp4

标签: video ffmpeg html5-video


【解决方案1】:

您可以使用 ffmpeg 使用 -force_key_frames 选项将关键帧插入到您想要的位置。

例如:

./ffmpeg -i input.mp4 -c:a copy -c:v copy -force_key_frames 0:05:00,0:10:00 out.mp4

将尽可能靠近 5 和 10 秒标记放置关键帧。时间值可以是 hh:mm:ss 格式,也可以是秒(单个值,没有冒号)。

您可以使用以下方法检查是否有框架插入到您想要的位置:

./ffprobe -select_streams v:0 -skip_frame nokey -show_entries frame=pkt_pts_time out.mp4

【讨论】:

  • 谢谢!我试过这个,输出质量较低。有没有一种简单的方法来匹配输入帧率等,还是我需要手动指定所有这些?
  • 我实际上并没有手动检查质量。我只是假设它的质量较低,因为文件要小得多。
  • 您可能想尝试在-force... 之前添加-c:a copy -c:v copy 以显式复制音频和视频(请参阅编辑后的答案)
  • 如果不重新编码 -force_key_frames 选项将不起作用,因此上述添加关键帧的命令根本不执行任何操作(因为 -c:v copy 保持相同的视频流不重新编码)。
猜你喜欢
  • 2013-02-23
  • 2018-11-05
  • 2015-06-26
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 2020-02-16
相关资源
最近更新 更多