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.ts

Parameter Breakdown


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.ts

Key Live Parameters


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.ts

In 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.