Force Strict Keyframe Interval in libvpx-vp9
This article explains how to configure the libvpx-vp9
encoder in FFmpeg to enforce a strict maximum keyframe interval (GOP
size). You will learn the specific command-line parameters required to
disable scene-cut detection and lock keyframes to a precise, consistent
interval, which is essential for adaptive bitrate streaming protocols
like DASH and HLS.
To force a strict keyframe interval when encoding VP9 video with
libvpx-vp9, you must define the maximum and minimum
keyframe intervals and disable the encoder’s automatic scene-cut
detection. Without disabling scene detection, the encoder will insert
extra keyframes at scene changes, breaking the strict interval alignment
required for multi-bitrate streaming segmenters.
The Core FFmpeg Parameters
You can enforce a strict keyframe interval using the following three parameters in your FFmpeg command:
-g <value>: Sets the Group of Pictures (GOP) size, which is the maximum interval between keyframes (frames).-keyint_min <value>: Sets the minimum interval between keyframes. To force a strict interval, set this to the same value as-g.-sc_threshold 0: Disables scene-cut detection. Setting this to0prevents FFmpeg and thelibvpx-vp9library from inserting keyframes at arbitrary scene changes.
Step-by-Step Implementation
To calculate the correct -g and -keyint_min
values, multiply your video’s frame rate (fps) by your desired keyframe
interval in seconds.
For example, if your video is 30 fps and you want a strict keyframe interval of 2 seconds, your target frame interval is 60 frames (\(30 \times 2 = 60\)).
Example Command
Run the following command to encode a video with a strict 2-second keyframe interval at 30 fps:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -g 60 -keyint_min 60 -sc_threshold 0 -b:v 2M output.webmAlternative Method: Time-Based Keyframe Forcing
If your source video has a variable frame rate (VFR), frame-based
intervals might not result in perfectly timed segments. In this case,
you can force keyframes at exact time intervals using the
-force_key_frames expression:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -force_key_frames "expr:gte(t,n_forced*2)" -sc_threshold 0 -b:v 2M output.webmIn this command, "expr:gte(t,n_forced*2)" forces a
keyframe precisely every 2 seconds, regardless of the frame rate, while
-sc_threshold 0 ensures no additional keyframes are
generated by scene changes.