在调节用于 DASH 播放的流时,随机访问点必须在所有流中的源流时间完全相同。执行此操作的常用方法是强制固定帧速率和固定 GOP 长度(即每 N 帧一个关键帧)。
在 FFmpeg 中,固定帧速率很容易(-r NUMBER)。
但是对于固定的关键帧位置(GOP 长度),有三种方法……哪一种是“正确的”?FFmpeg 文档对此非常含糊。
-c:v libx264 -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE:scenecut=-1
Run Code Online (Sandbox Code Playgroud)
是否应该关闭场景切换似乎存在一些争论,因为当场景切换发生时关键帧“计数器”是否重新启动尚不清楚。
-g GOP_LEN_IN_FRAMES
Run Code Online (Sandbox Code Playgroud)
不幸的是,这只是在 FFMPEG 文档中顺便记录,因此这个论点的效果非常不清楚。
-force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)
Run Code Online (Sandbox Code Playgroud)
这是明确记录的。但是,“时间计数器”是否在每个关键帧后都重新启动,目前还不清楚。例如,在预期的 5 秒 GOP 中,如果scenecut
libx264 在 3 秒内注入了一个关键帧,那么下一个关键帧是 5 秒后还是 2 秒后?
事实上,FFmpeg 文档区分了这个和-g
选项,但它并没有真正说明上面的这两个选项有何不同(显然,-g
将需要固定的帧速率)。
看起来-force_key_frames
会更好,因为它不需要固定的帧速率。然而,这要求
scenecut
关键帧。如果-g
不强制固定帧速率 ( …
我不想为 FFMPEG/libx264 (-r/-framerate) 提供固定的帧速率,而是想指定一个具有 MAXIMUM 值的可变帧速率,并允许 libx264 在它认为合适的时候降低帧速率。这里的想法是在有扩展静止帧之类的东西时获得额外的压缩(这在我的源视频中发生了很多)。
我意识到预测或双向 MPEG 帧会压缩得非常好,但也有可能源帧速率小于我打算转码的帧速率(可能导致更大的流!)。
在 FFmpeg 中,在两段视频内容之间进行交叉淡入淡出实际上是相当复杂的。没有像音频那样的“交叉淡入淡出”过滤器。
什么是有效的方法?
使用 FFMPEG,如何将视频分成相等长度的片段,这些片段可能或可能不从关键帧开始?
假设您熟悉分段格式和break_non_keyframes选项,FFMPEG 似乎并没有达到我的预期(从我阅读的内容来看......无法再找到链接)。
ffmpeg -i ... -f segment -break_non_keyframes 1 -segment_time 2 -c copy 2secs%03d.ts
Run Code Online (Sandbox Code Playgroud)
即,创建一个实际上可能比所需片段(根据需要包括整个 GOP)更长的片段。
例如,假设一个 3 帧 GOP,其愚蠢的帧速率为 1 FPS,具有以下愚蠢的 IBP 节奏:
01 02 03 11 12 13 21 22 23 31 32 33
I B P I B P I B P I B P
Run Code Online (Sandbox Code Playgroud)
如果我想将其分成 2 秒的片段,则期望看到生成以下片段(括号中的帧不会显示在该片段中):
01 02 03 (03 not displayed in this segment, only used for decoding)
01 02 03 11 (... 01 and …
Run Code Online (Sandbox Code Playgroud)