How to Create M3U8 with FFmpeg Segment Muxer
This guide explains how to generate an M3U8 index playlist file while
splitting a live stream using FFmpeg’s segment muxer. You
will learn the exact command-line parameters required to slice your
input stream into TS (Transport Stream) segments and simultaneously
output a continuously updated HLS-compatible M3U8 playlist.
The Basic Command
To split an incoming stream and generate an M3U8 index file, use the
-f segment muxer along with the -segment_list
and -segment_list_type options.
Here is the fundamental command:
ffmpeg -i input_stream -codec copy -f segment -segment_time 10 -segment_list playlist.m3u8 -segment_list_type m3u8 segment_%03d.tsParameter Breakdown
-i input_stream: The source of your live stream (e.g., an RTMP feed, RTSP stream, or a local file).-codec copy: Copies the video and audio streams without re-encoding, saving CPU resources.-f segment: Specifies that thesegmentmuxer should be used to split the stream.-segment_time 10: Sets the target segment length to 10 seconds. Note that FFmpeg will split at the nearest keyframe (I-frame) after this duration.-segment_list playlist.m3u8: Defines the name of the output index/playlist file.-segment_list_type m3u8: Forces FFmpeg to format the index file as an HLS/M3U8 playlist.segment_%03d.ts: The naming pattern for the generated TS segments (e.g.,segment_001.ts,segment_002.ts).
Configuring for Live Streams
By default, the segment muxer behaves like a
Video-on-Demand (VOD) recorder, appending all segments to the M3U8 file
and adding an end tag (#EXT-X-ENDLIST). For a true
live stream, you must configure a sliding window to
keep only the most recent segments in the playlist.
Use the following options to optimize the playlist for live broadcasting:
ffmpeg -i input_stream -codec copy -f segment -segment_time 6 -segment_list_size 5 -segment_list_flags +live -segment_list_type m3u8 segment_%03d.tsKey Live Parameters
-segment_list_size 5: Limits the M3U8 playlist to only contain the 5 most recent segments. Older segments are removed from the index file as new ones are added.-segment_list_flags +live: Instructs the muxer to generate a live-compatible playlist. This prevents the#EXT-X-ENDLISTtag from being written to the end of the M3U8 file, allowing players to keep fetching updates.
Handling Keyframe Intervals (GOP Size)
Because FFmpeg can only split a stream on a keyframe, your segments
might not be exactly equal to the -segment_time value if
the source stream has irregular keyframe intervals.
To ensure precise segment lengths, you can force a constant Group of Pictures (GOP) size during encoding:
ffmpeg -i input_stream -c:v libx264 -g 60 -keyint_min 60 -f segment -segment_time 2 -segment_list playlist.m3u8 -segment_list_type m3u8 segment_%03d.tsIn this example: * -g 60 forces a
keyframe every 60 frames. * If your stream is 30 frames per second
(fps), a keyframe will occur exactly every 2 seconds, matching the
-segment_time 2 duration for perfectly split segments.