FFmpeg Segment Muxer to Generate M3U8 Playlist

This article explains how to use the FFmpeg segment muxer to split a video file into HTTP Live Streaming (HLS) segments and generate an M3U8 playlist. You will learn the exact FFmpeg command structure, the key parameters required for segmentation, and how to ensure precise segment splitting by managing keyframes.

The segment muxer in FFmpeg is a highly flexible tool that splits an input stream into temporal chunks (segments) and outputs a list file, such as an M3U8 playlist, to index them.

The Basic Command

To convert an MP4 video into HLS segments using the segment muxer, run the following command in your terminal:

ffmpeg -i input.mp4 -c:v libx264 -c:a aac -g 120 -sc_threshold 0 -f segment -segment_time 4 -segment_list playlist.m3u8 -segment_format mpegts output_%03d.ts

Parameter Breakdown

  • -i input.mp4: Specifies the source video file.
  • -c:v libx264 -c:a aac: Encodes the video to H.264 and the audio to AAC, which are the standard formats for HLS compatibility.
  • -f segment: Tells FFmpeg to use the segment muxer.
  • -segment_time 4: Sets the target duration for each segment in seconds (in this case, 4 seconds).
  • -segment_list playlist.m3u8: Specifies the name and format of the playlist file that indexes the segments. FFmpeg automatically formats this as an HLS playlist because of the .m3u8 extension.
  • -segment_format mpegts: Sets the output container format for the individual segments to MPEG-TS, which is the standard format used for HLS.
  • output_%03d.ts: Defines the naming pattern for the output segment files. %03d is a sequential placeholder that outputs files as output_001.ts, output_002.ts, etc.

Achieving Precise Segment Lengths (Keyframe Alignment)

FFmpeg can only split a video at a keyframe (I-frame). If there is no keyframe at your designated -segment_time, FFmpeg will wait for the next keyframe, resulting in uneven segment lengths.

To ensure exact 4-second segments, you must force keyframes at regular intervals using the -g (Group of Pictures/GOP) and -sc_threshold flags:

  • -g 120: Sets the maximum distance between keyframes. If your input video is 30 frames per second (fps), setting this to 120 forces a keyframe every 4 seconds (\(30 \text{ fps} \times 4 \text{ seconds} = 120\) frames).
  • -sc_threshold 0: Disables scene change detection, preventing FFmpeg from inserting extra keyframes at natural scene cuts, which would otherwise disrupt your segment timing.