M3U8 File Documentation
Summary
An .m3u8 file is a UTF-8 M3U Playlist File: a plain-text playlist that contains no audio or video itself, only a list of tracks or stream URLs beginning with an #EXTM3U header. It comes in two forms — a local playlist of file paths you open in VLC, and an HLS streaming manifest (defined by RFC 8216) that lists media segments and quality variants. To play either, open it in VLC; to save an HLS stream as one file, use yt-dlp or ffmpeg. Its MIME type is application/vnd.apple.mpegurl.
Technical details
| Feature | Value |
|---|---|
| Full name | UTF-8 M3U Playlist File (also HLS streaming manifest) |
| File extension | .m3u8 |
| MIME type | application/vnd.apple.mpegurl (HLS) or audio/x-mpegurl |
| Format type | Plain-text playlist; no embedded media |
| Encoding | UTF-8 (this is what distinguishes .m3u8 from ASCII .m3u) |
| First line | #EXTM3U (required for an extended/HLS playlist) |
| Two roles | Local file-list playlist, or HLS adaptive-streaming manifest |
| M3U origin | Nullsoft Winamp playlist, late 1990s |
| HLS developer | Apple Inc. (HLS uses .m3u8 since 2009) |
| HLS standard | RFC 8216 (2017) |
| Playlist types (HLS) | Master playlist (variants) and Media playlist (segments) |
| Key HLS tags | #EXT-X-STREAM-INF, #EXTINF, #EXT-X-TARGETDURATION, #EXT-X-KEY, #EXT-X-ENDLIST |
| Segment formats | MPEG-2 Transport Stream (.ts) or fragmented MP4 (.m4s) |
| Encryption | Optional AES-128 / SAMPLE-AES via #EXT-X-KEY |
| Open standard | Yes (RFC 8216) |
| Plays in | VLC, mpv, IINA, PotPlayer; Safari plays HLS natively |
| Download to MP4 | yt-dlp or ffmpeg (fetches and merges the segments) |
| Related extensions | .m3u, .ts, .mp4, .pls, .mpd, .vtt |
| Specification | RFC 8216 |
What is an M3U8 file?
An .m3u8 file is a UTF-8 M3U Playlist File: a plain-text list of media references that contains no audio or video of its own. The M3U format began as the playlist format for Nullsoft’s Winamp in the late 1990s; the “8” in .m3u8 simply means the same text format saved in UTF-8, so it can hold non-ASCII filenames and titles that a plain ASCII .m3u cannot. The file is just text, and the first line of any extended playlist is the literal marker #EXTM3U.
A common misconception is that .m3u8 was invented by Apple. It was not: the playlist format is Nullsoft’s. What Apple did was adopt .m3u8 as the manifest format for HTTP Live Streaming (HLS) in 2009, and that use was later standardised as RFC 8216 in 2017. That is the crux of the format today: the same .m3u8 extension covers two very different real-world files — a simple local playlist, and an HLS streaming manifest — and telling them apart is the first thing to understand.
Local playlist versus HLS manifest
The local playlist is the original meaning: a list of paths to audio or video files on disk (or on the network), optionally annotated, that a media player loads to play your files in order. This is the “playlist of my songs” sense. It is small, hand-editable, and useless the moment the files it points to move or disappear.
The HLS manifest is the dominant modern meaning. Nearly every website that streams video delivers it as HLS, so an .m3u8 you capture from a browser’s network tab is almost always an HLS manifest, not a song list. HLS breaks a video into many short segments and describes them — and the available quality levels — in .m3u8 text. Opening either kind in a text editor immediately reveals which you have: a local playlist lists file paths, while an HLS manifest is full of #EXT-X- tags and segment URLs.
Local playlist syntax: #EXTM3U and #EXTINF
An extended local playlist starts with #EXTM3U, then repeats a two-line pattern for each track: an #EXTINF line giving the track’s duration in seconds and its title, followed by the path or URL to the media file.
#EXTM3U
#EXTINF:213,Aphex Twin - Xtal
music/01 - xtal.flac
#EXTINF:246,Boards of Canada - Roygbiv
music/roygbiv.mp3
Lines beginning with # that are not recognised tags are comments; every other non-blank line is a URI, which may be a relative path (resolved against the playlist’s own location) or an absolute URL. A player reads the list top to bottom and plays each entry in turn. That is the whole format for a local playlist; the negative duration -1 is used when the length is unknown, as with a live radio stream URL.
The HLS master playlist and #EXT-X-STREAM-INF
HLS uses two levels of .m3u8. The top level is the master playlist, which does not list any media segments at all; it lists the variant streams — the same content encoded at several bitrates and resolutions — and points to a separate media playlist for each. Each variant is declared with an #EXT-X-STREAM-INF tag whose attributes describe the rendition, followed on the next line by the URL of that variant’s own .m3u8.
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=1280000,RESOLUTION=640x360,CODECS="avc1.4d401e,mp4a.40.2"
360p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2560000,RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2"
720p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=7680000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
1080p/index.m3u8
The BANDWIDTH attribute (bits per second) is what enables adaptive bitrate streaming: a player estimates the viewer’s available throughput and picks the highest variant that fits, switching up or down as conditions change so the video keeps playing instead of buffering. RESOLUTION and CODECS let the player rule out renditions it cannot display or decode before it ever fetches a segment. The master playlist is fetched once at the start of playback.
The HLS media playlist: segments and EXT-X tags
Each variant URL points to a media playlist, and this is where the actual segments live. A media playlist lists short chunks of the stream, each a few seconds long, with an #EXTINF giving the chunk’s exact duration and the next line giving its URL. Several #EXT-X- tags frame the list:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:6.000,
segment0.ts
#EXTINF:6.000,
segment1.ts
#EXTINF:4.500,
segment2.ts
#EXT-X-ENDLIST
| Tag | Meaning |
|---|---|
#EXT-X-VERSION | Compatibility version of the playlist syntax |
#EXT-X-TARGETDURATION | Upper bound (seconds) on any segment’s length; every #EXTINF must be ≤ this |
#EXT-X-MEDIA-SEQUENCE | Sequence number of the first segment listed (advances in live streams) |
#EXT-X-PLAYLIST-TYPE | VOD (fixed) or EVENT (segments appended over time) |
#EXT-X-ENDLIST | Marks the end of a video-on-demand playlist; absent in a live stream |
The presence or absence of #EXT-X-ENDLIST is what separates video-on-demand from live. A VOD playlist lists every segment and ends with #EXT-X-ENDLIST; the player knows the full timeline up front and can seek anywhere. A live playlist has no end tag: the player re-fetches the manifest every few seconds, and the server keeps appending new segments and advancing #EXT-X-MEDIA-SEQUENCE as old ones fall off the front of the window.
Segments, fragmented MP4 and EXT-X-KEY encryption
The segment URLs point to the real media. Classic HLS uses MPEG-2 Transport Stream chunks (.ts files), each carrying a few seconds of coded audio and video; newer HLS uses fragmented MP4 segments (.m4s), signalled by an #EXT-X-MAP tag that names the initialisation segment holding the codec setup. Either way, a player fetches the segments in order and feeds them to its decoder, so the continuous stream is reassembled from many small HTTP requests — which is exactly why HLS works over ordinary web servers and CDNs.
HLS can encrypt its segments. An #EXT-X-KEY tag names the encryption method (commonly AES-128, or SAMPLE-AES) and the URI of the key needed to decrypt the following segments, plus an optional initialisation vector. A player must fetch that key — usually from an authenticated endpoint — before it can play the encrypted chunks, which is how paid and DRM-adjacent streams keep the raw segments useless to anyone without authorisation. Because keys and segment URLs are frequently token-signed and time-limited, a saved .m3u8 often stops working once its tokens expire, which is the usual reason a captured manifest “won’t play” later.
Downloading an HLS stream into one file
Because an HLS .m3u8 is only a list of segment URLs, saving the stream as a single file means fetching every segment the playlist points to and concatenating them. Two tools do this well. ffmpeg can read the manifest directly and copy the segments into a container without re-encoding: ffmpeg -i index.m3u8 -c copy out.mp4 merges the .ts or fMP4 segments into one MP4. yt-dlp wraps the same job with a friendlier interface: yt-dlp "<m3u8 url>" resolves the master playlist, picks a variant, downloads the segments and merges them. For an audio-only HLS stream, yt-dlp -x --audio-format mp3 "<url>" extracts the audio.
This only fetches what the playlist references, so a local playlist — a list of files already on disk — cannot become an MP4 this way; there is no remote stream to pull. And saving a stream may breach a site’s terms or copyright, so it applies only to streams you are entitled to access. A related caution: because an .m3u8 can point a player at arbitrary remote URLs, inspect an unfamiliar playlist in a text editor before opening it, and prefer yt-dlp or ffmpeg directly over the ad-laden “m3u8 downloader” websites that tend to bundle unwanted software.
FAQ
What is the difference between M3U and M3U8?
They are the same playlist format; .m3u is ASCII and .m3u8 is UTF-8, so .m3u8 supports non-ASCII filenames and titles. .m3u8 is also the standard extension for HLS streaming manifests, which is why the extension carries the streaming association.
Is an M3U8 audio or video?
Neither, by itself — it is a playlist. It only references media. The old “audio” label is outdated: today most .m3u8 files are HLS manifests for streaming video, though a local playlist can list songs, videos or both.
References
- RFC 8216 — HTTP Live Streaming (HLS)
- Apple Developer — HTTP Live Streaming
- yt-dlp — stream downloader
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.