FFmpeg HLS Segment Duration and Playlist Size

This guide explains how to configure HTTP Live Streaming (HLS) segment duration and manage the maximum segment count in a rolling live playlist using FFmpeg. By combining the -hls_time and -hls_list_size flags with proper keyframe alignment, you can control playback latency, maintain a fixed-length live window, and prevent disk storage exhaustion.

Essential FFmpeg HLS Parameters

To create a rolling live HLS playlist, FFmpeg relies on three primary options:

  • -hls_time <seconds>: Sets the target segment duration. FFmpeg will try to split segments at this interval.
  • -hls_list_size <number>: Defines the maximum number of segments displayed in the .m3u8 playlist file. Setting this to a positive integer creates a sliding/rolling window. Setting it to 0 saves all segments (used for Video on Demand).
  • -hls_flags delete_segments: Automatically deletes older video segments (.ts files) from disk as they fall off the rolling playlist.

The Keyframe Alignment Requirement

HLS segments can only split on video keyframes (I-frames). If your video's Group of Pictures (GOP) size does not align with your target segment duration, FFmpeg will not be able to cut segments at the exact duration specified by -hls_time.

To guarantee accurate segment cuts, set the GOP size using -g to match your frame rate multiplied by the desired segment duration, and force fixed keyframe intervals using -keyint_min and -sc_threshold 0.

Complete Example Command

The following command takes an input stream, transcodes it to H.264 video at 30 frames per second, and creates a rolling HLS playlist with 4-second segments and a maximum of 5 segments in the playlist:

ffmpeg -i input.mp4 \
  -c:v libx264 -preset veryfast -r 30 -g 120 -keyint_min 120 -sc_threshold 0 \
  -c:a aac -b:a 128k \
  -f hls \
  -hls_time 4 \
  -hls_list_size 5 \
  -hls_flags delete_segments \
  -hls_segment_filename "segment_%03d.ts" \
  playlist.m3u8

Breakdown of the Command

  1. -r 30: Sets the output video frame rate to 30 frames per second.
  2. -g 120 and -keyint_min 120: Places a keyframe every 120 frames. At 30 fps, 120 frames equal exactly 4 seconds, matching the -hls_time 4 value.
  3. -sc_threshold 0: Disables scene-change detection to prevent FFmpeg from generating extra, unplanned keyframes that would result in irregular segment lengths.
  4. -hls_time 4: Sets the target segment length to 4 seconds.
  5. -hls_list_size 5: Limits the .m3u8 playlist to a rolling window of the 5 most recent segments (a 20-second live buffer).
  6. -hls_flags delete_segments: Removes expired .ts segments from local storage once they are no longer listed in the rolling playlist.
  7. -hls_segment_filename "segment_%03d.ts": Defines the naming pattern for generated segment files.