StreamTest

How to read an M3U8 playlist file line by line

An M3U8 playlist is read top to bottom as alternating metadata tags and URIs: every line starting with # is a tag that describes what follows, and every non-# line is a URI to either a variant playlist or a media segment. Once you know the dozen tags that appear in practice, the whole file reads like a table of contents rather than a mystery format.

There are two kinds of M3U8 file that look similar but mean different things: a master playlist, whose URIs point to other playlists, and a media playlist, whose URIs point to actual audio/video segments. Knowing which one you are looking at changes how every subsequent line should be interpreted.

How do you tell a master playlist from a media playlist at a glance?

Look at the first tag after #EXTM3U. If you see #EXT-X-STREAM-INF, it is a master playlist and each STREAM-INF line is immediately followed by a URI to another .m3u8 file, one per quality variant. If you instead see #EXT-X-TARGETDURATION and #EXTINF, it is a media playlist and the URIs point directly to segment files.

A master playlist never contains #EXTINF or segment files itself; it only ever fans out to media playlists. Treating a master playlist's STREAM-INF lines as if they were segments is the most common beginner misread.

What do the tags at the top of a media playlist mean?

#EXT-X-VERSION:N declares which protocol version the playlist uses; higher versions unlock features like fMP4 segments (needs 7) or the EXT-X-MAP tag. Players should reject a playlist using a feature that requires a higher version than the one declared.

#EXT-X-TARGETDURATION:N is the maximum segment duration in whole seconds, rounded up; it tells the client how often to poll a live playlist and how large a buffer to allocate. #EXT-X-MEDIA-SEQUENCE:N gives the sequence number of the first segment listed, which lets a client detect gaps if segments were skipped between polls.

#EXT-X-PLAYLIST-TYPE, when present, is either EVENT (segments only appended, never removed) or VOD (the complete, final list). Its absence on a playlist without #EXT-X-ENDLIST means a live sliding window, where old segments drop off the front as new ones are appended.

What does each #EXTINF line tell you about a segment?

#EXTINF:6.006, is followed on the next line by the segment URI; the number is the segment's duration in seconds, and the text after the comma is an optional human-readable title that almost no player displays. The duration does not need to be a round number, and real encoders rarely produce exactly 6.000 due to frame-boundary rounding.

If a segment's EXTINF duration exceeds the playlist's declared TARGETDURATION, the playlist is technically non-compliant; some players tolerate it, Apple's Media Stream Validator will flag it as an error.

How do EXT-X-KEY and EXT-X-MAP change how you read the URIs that follow?

#EXT-X-KEY:METHOD=AES-128,URI="...",IV=0x... appears before the segments it applies to and stays in effect until a new EXT-X-KEY line overrides it; every following segment must be decrypted with that key before decoding. METHOD=NONE turns encryption back off for subsequent segments.

#EXT-X-MAP:URI="init.mp4" appears once before the first EXTINF when segments are fragmented MP4, and points at an initialization segment containing the moov box the decoder needs before it can parse any following .m4s segment. Skipping it produces segments a demuxer cannot open on its own.

What does EXT-X-PROGRAM-DATE-TIME add to a segment line?

#EXT-X-PROGRAM-DATE-TIME:2026-09-16T10:00:00.000Z maps the start of the following segment to wall-clock time, which is what lets a player show an accurate live-edge clock or seek to a specific real-world time in a DVR window. It should appear at least once near the start of a live playlist, and ideally on every segment for accurate seeking.

Without it, a player only knows relative position within the sliding window, not absolute time, so any "jump to 10:05am" feature or synchronized multi-camera switch has nothing to anchor to.

What marks the end of a playlist, and what if it is missing?

#EXT-X-ENDLIST marks a VOD playlist as complete; once a client sees it, it stops polling and knows the segment list will never change again. A live playlist simply never includes this tag.

If a playlist looks finished (segments stop being added) but never sends ENDLIST, well-behaved clients keep polling forever, wasting requests. This usually indicates the origin failed mid-stream rather than ended cleanly, and is a useful diagnostic signal on its own.

Step by step

  1. Confirm the file starts with #EXTM3U on the very first line.
  2. Check the next few tags to decide: STREAM-INF means master playlist, TARGETDURATION/EXTINF means media playlist.
  3. For a master playlist, read each STREAM-INF line's BANDWIDTH and RESOLUTION, then follow its URI to the corresponding media playlist.
  4. For a media playlist, note VERSION, TARGETDURATION, and MEDIA-SEQUENCE from the header block.
  5. Walk the EXTINF/URI pairs in order, noting any EXT-X-KEY or EXT-X-MAP that changes how following segments are handled.
  6. Check for EXT-X-ENDLIST at the bottom to know whether you are looking at a fixed VOD list or a live snapshot.

Run it yourself

Free, no sign-up, and every finding links to an explainer.

Frequently asked questions

Is M3U8 just M3U with a different file extension?
M3U8 is M3U required to be UTF-8 encoded, plus the extended tag set (EXT-X-* tags) defined by the HLS specification. A plain .m3u file with only basic #EXTINF lines and no HLS-specific tags will not work as an HLS stream even if renamed to .m3u8.
Why do some URIs in the playlist look like full URLs and others like just a filename?
Both are valid; a bare filename like segment012.ts is a relative URI resolved against the playlist's own URL, while a full URL overrides that and can point anywhere, including a different CDN or domain. Relative URIs are more common because they let the same playlist be served from multiple CDN edges without rewriting.
What does a negative or zero MEDIA-SEQUENCE mean?
A MEDIA-SEQUENCE of 0 is normal at the very start of a live stream or in a VOD playlist and is not an error. It should never go negative; a compliant encoder only increments it as segments are dropped from the front of a live sliding window.
Can an M3U8 playlist reference segments in more than one format?
No, all segments referenced by a single media playlist must share the same container and codec profile, since the client sets up one demuxer/decoder pipeline per playlist. Different formats belong in separate variant playlists listed from the master.

HLS findings, explained

Read next

Last reviewed 2026-09-16.