FFmpeg Segment Muxer: Split Live Stream at Keyframes

This article explains how to use the FFmpeg segment muxer to split an incoming live video stream into smaller, sequential chunks precisely at keyframe boundaries. You will learn the exact command-line parameters required to ensure seamless playback, avoid video corruption, and manage how FFmpeg handles keyframes (I-frames) when slicing a live stream with or without re-encoding.

The Challenge of Splitting Live Streams

When splitting a live video stream into segments (for HTTP Live Streaming (HLS), archiving, or processing), video players require each segment to start with a keyframe (I-frame). If a segment starts with a B-frame or P-frame, the player cannot render the video until it encounters the next keyframe, resulting in frozen frames, green screens, or decoding errors.

FFmpeg’s segment muxer can split streams automatically, but how it behaves depends entirely on whether you are re-encoding the video or copying the stream directly.


Method 1: Splitting Without Re-encoding (Stream Copy)

If you want to split the stream without re-encoding (using -c copy), FFmpeg is highly efficient and uses minimal CPU. However, because it cannot create new keyframes, FFmpeg can only split the video at existing keyframes.

If you specify a segment time of 10 seconds, but your stream only has keyframes every 12 seconds, FFmpeg will wait until the 12-second mark to create the split.

Command Example:

ffmpeg -i rtmp://live.example.com/input -c copy \
-f segment \
-segment_time 10 \
-reset_timestamps 1 \
-segment_format mpegts \
output_%03d.ts

Parameter Breakdown:


Method 2: Splitting with Exact Timing (Re-encoding)

If you require your segments to be split at exact mathematical intervals (e.g., precisely every 5 seconds), you must re-encode the stream. This allows FFmpeg to force keyframes to occur exactly when the segment split is scheduled.

Command Example:

ffmpeg -i rtmp://live.example.com/input \
-c:v libx264 -force_key_frames "expr:gte(t,n_forced*5)" \
-c:a aac \
-f segment \
-segment_time 5 \
-reset_timestamps 1 \
-segment_format mp4 \
output_%03d.mp4

Parameter Breakdown for Exact Splits:


Choosing the Right Segment Format

While MPEG-TS (.ts) is the traditional standard for live stream segmentation due to its resilience to stream interruptions, you can also use MP4 (-segment_format mp4) or WebM (-segment_format webm).

For modern streaming protocols like LL-HLS or DASH, you may want to output fragmented MP4s by adding the appropriate muxer flags:

ffmpeg -i rtmp://live.example.com/input -c copy \
-f segment \
-segment_time 6 \
-segment_format_options movflags=frag_keyframe+empty_moov+default_base_moof \
-reset_timestamps 1 \
output_%03d.mp4