注意:我最初错误地将 h.264 流称为更常见的 MP4 文件,抱歉
我知道通常需要在关键帧上开始分割 h.264,以便结果视频从关键帧开始,但我想知道流结构/规范是如何实现这一点的?
关键帧是否必须作为整个文件的固定参数每 X 帧出现一次,还是关键帧之间可以有不同的间隔?如果播放器只是按出现的帧来绘制整个帧(关键帧)或更新其中的一部分(非关键帧),那么关键帧间隔为什么重要?
如果间隔无关紧要,并且我们想要剪切每 100 个关键帧流的第 87 帧,我们能否使用 86 个前导帧来计算新文件的新关键帧,将剩余的 12 个非关键帧从原始文件中放入下一个关键帧,然后再放入下一个原始关键帧(第 100 帧)并从那里开始?
即文件最终以“新密钥,12 个原始非密钥,原始密钥,99 个原始非密钥,原始密钥...”结束。
答案1
关键帧可以随时出现,我找不到引用,但想象一下在一部有许多过场动画的电影中。为了保持视频的质量,您希望关键帧成为任何剧烈场景变化后的第一帧,否则,当视频压缩器尝试使用来自前一个场景的大量“增量”变化来创建新场景时,您最终会得到一片噪音风暴。
对于正常流来说,具有一致的关键帧时间可能是可以接受的,但对于最终内容来说,通过在场景变化边界处设置关键帧将实现更好的质量。
关键帧 (i 帧) 是视频中图像的完整帧。后续帧(增量帧)仅包含已更改的信息。关键帧将在流中出现多次,取决于它是如何被创建的或者如何被传输的。
它的确是可调整,取决于您对质量和比特率的要求。
这mp4 的默认值是每 250 帧一个关键帧(大约每 10 秒一次)。这对流媒体来说很不利,因为更改分辨率会更加困难。Youtube 使用 2 秒的关键帧间隔。
还有一些方法可以仅提取 iframe(关键帧),如BogoToBogo:缩略图(IFRAME/场景变化) - 2020
i 帧缩略图
以下命令将为每个 I 帧创建一个缩略图,名为 yi01.png、yi02.jpg、yi03.png...yi116
ffmpeg -i yosemiteA.mp4 -f image2 -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync vfr yi%03d.png
select='eq(pict_type,PICT_TYPE_I)'
:提取 I 帧图像vsync
:视频同步方式。vfr
:可变帧率。