Back

Blog details

What Is an M3U8 File? How HLS Video Segmentation Works

AIOZ Network
9 min readSeptember 05, 2026
aioz-streamguide
What is an M3U8 file? How HLS video segmentation works, AIOZ Stream knowledge hub

An M3U8 file is a plain-text playlist that tells a video player which short media segments to fetch, in what order and at which quality. HLS streaming works by cutting an encoded video into those segments, often about 6 seconds each, and listing them in M3U8 manifests.

Don't confuse this with upload chunking. The chunked upload tutorial covers splitting a source file into 50-200MB parts to get it onto AIOZ Stream's servers, which you do once. Segmentation happens after encoding, and it shapes every playback you serve.

TL;DR:

  • Upload chunking happens once, when your file goes up. Playback segmentation decides how the finished stream is delivered every time someone presses play.
  • HLS uses two tiers of M3U8 file: a master playlist that lists each bitrate-ladder rung, and one media playlist per rung that lists the segments a player requests in order.
  • Segment duration is a tradeoff. Apple moved its HLS guidance from a 10-second to a 6-second target to balance faster ABR switching against request overhead.
  • A media playlist can point to separate segment files, or use EXT-X-BYTERANGE to serve sub-ranges of one larger file.
  • On AIOZ Stream you choose the format and container per quality (HLS or DASH, MPEG-TS or fMP4), and you can import an existing HLS ladder from an M3U8 URL without re-encoding.

Updated Oct 29, 2026: merged our 2024 post on HLS and transcoding into this guide as a new section and FAQ entry.

Updated Oct 28, 2026: added a labelled diagram, an example media playlist, AIOZ Stream's container options and M3U8 import, and the HLS URL on live sessions.

What is the difference between a master and media playlist?

HLS uses two kinds of M3U8 file, and what their URI lines point to is what tells them apart. The IETF's HLS specification puts it this way: "A Playlist is a Media Playlist if all URI lines in the Playlist identify Media Segments. A Playlist is a Master Playlist if all URI lines in the Playlist identify Media Playlists."

The master playlist is the file your player fetches first. It has one entry per rung in the bitrate ladder, and each entry carries the BANDWIDTH attribute covered in the ABR article. Each entry points to a separate media playlist, and that file lists the playable content: "A Media Playlist contains a list of Media Segments, which, when played sequentially, will play the multimedia presentation." Think of the master playlist as the table of contents and the media playlist as the chapter where the video lives.

Diagram of an HLS stream in M3U8 files: a master playlist points to a 1080p and a 720p media playlist, each listing about 6-second segments, with VOD ending in EXT-X-ENDLIST and live using a sliding window

What's inside a media playlist?

A handful of tags do most of the work. Here is a minimal VOD media playlist with three segments. We wrote it for this post to show the shape, so it isn't taken from a real stream:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:6.0,
seg0.ts
#EXTINF:6.0,
seg1.ts
#EXTINF:4.2,
seg2.ts
#EXT-X-ENDLIST

EXTINF sits before every segment and states its duration; the spec says "This tag is REQUIRED for each Media Segment." EXT-X-TARGETDURATION sets a ceiling for the whole playlist, and every segment must stay at or under it. EXT-X-VERSION declares which protocol features the playlist uses. It is required whenever a tag beyond the original baseline appears.

EXT-X-MEDIA-SEQUENCE numbers the first segment currently listed and defaults to 0 if absent. On a live playlist, that number has to climb each time an old segment drops off. EXT-X-PLAYLIST-TYPE says whether the playlist can still grow (EVENT, segments only get appended) or is finished (VOD, nothing changes once published). EXT-X-ENDLIST is the explicit signal that no more segments are coming, and it is what turns an open live playlist into a closed one.

How transcoding and segmentation work together

Segmentation needs something to cut, and transcoding supplies it. HLS is the protocol Apple created to send live and on-demand video from ordinary web servers and CDNs, and it never ships one large file. Every quality level a player can switch to has to exist as its own encoded copy before anyone cuts it into segments. Our overview of how the main streaming protocols compare shows where HLS sits next to DASH, WebRTC, RTMP and SRT.

AIOZ's docs describe transcoding as converting video "from one codec or format to another", either on the fly or as a step before streaming. In an HLS workflow it does three separate jobs for you. It makes the source playable on devices that can't decode the original format, and it produces the quality levels the player switches between. It also compresses each level to a size your viewers' connections can carry.

From upload to playback, an HLS pipeline runs in five steps:

  1. Prepare the source. You start with one high-quality master file.
  2. Transcode. The encoder makes one rendition per rung of the ladder, for example 1080p, 720p and 480p.
  3. Segment. Each rendition is cut into short segments.
  4. Write the playlists. Each rendition gets its own media playlist, and one master playlist lists all of them.
  5. Stream. Your player fetches the master playlist, picks a rendition and downloads its segments in order. When your bandwidth changes, the player moves to another media playlist.

Switching in step 5 only works if the renditions line up. RFC 8216 says "Matching content in Variant Streams MUST have matching timestamps", and every media playlist in the set must share one target duration. That's what lets a player leave the 1080p playlist after one segment and continue in the 720p playlist at the same point in the video. The codec choice in step 2 is a separate decision, covered in our guide to H.264, H.265 and VP9.

Why segment duration is a tradeoff

Shorter segments let an ABR algorithm react to a changing connection sooner, because the next decision point is always close. They also mean more playlist entries, more HTTP requests, and slightly worse compression, since each segment has to be decodable on its own. Longer segments compress a little better and cut request overhead. The cost is that your player can stay stuck on a bad bitrate decision for longer before it gets the next chance to switch.

Apple's HLS guidance moved on this exact tradeoff and said so directly: "We used to recommend a ten-second target duration... we do believe that going forward, six seconds makes for a better tradeoff." Apple also acknowledged that re-encoding existing content to a new target has a cost, so the shorter number isn't free. The duration also drives buffering. HLS clients are expected to start roughly three segments behind the live edge, so a 6-second target means about 18 seconds of buffer. The glass-to-glass latency article applies the same three-segment logic to startup delay.

One file or many? EXT-X-BYTERANGE

A media playlist doesn't need a separate file per segment. The EXT-X-BYTERANGE tag lets it describe a segment as a byte range inside one larger file, written as #EXT-X-BYTERANGE:<n>[@<o>]: a length in bytes and an optional offset. When you leave the offset out, the spec says "the sub-range begins at the next byte following the sub-range of the previous Media Segment." So sequential segments don't each need their own offset written out.

That packaging gives you fewer files to manage on the server than hundreds of small .ts or .m4s files. In exchange, every client has to handle range requests against one large resource instead of simple whole-file fetches.

How do live and VOD manifests differ?

A VOD media playlist is static: every segment is listed once, EXT-X-ENDLIST appears, and the file never changes after publishing. A live playlist is a sliding window that grows at one end and can shed old segments at the other, and the spec limits how fast it may shrink.

A server can't remove a segment if that would leave less than three target durations of content in the playlist. Every removal also increments EXT-X-MEDIA-SEQUENCE, so your player can tell what was dropped. Removed segments have to stay reachable for their own duration plus the duration of the longest playlist that contained them. That way a client that was mid-request when a segment rolled off doesn't hit a dead link. None of this applies to VOD, which is why EXT-X-PLAYLIST-TYPE matters: it tells a client up front which rules govern the file.

How AIOZ Stream handles it

When you upload a video, AIOZ Stream builds the manifests and segments for you. In the create-video request, each entry in qualities sets a resolution, a type of hls or dash, and a container_type. For HLS the container is mpegts or mp4, and for DASH it is fmp4. The docs also note that on Apple platforms, HLS plays HEVC/H.265 only from fMP4/CMAF segments, while H.264 works in both MPEG-TS and fMP4.

What the docs don't list is a segment-duration or byte-range setting; packaging beyond the container choice is automatic. For live broadcasts, the session object returned by the live streaming API includes an hls_url in its assets, alongside a player_url and an iframe.

If your library is already packaged as HLS, you can import it instead of re-uploading. You send the URL of a master playlist in source_url, and AIOZ Stream copies every rendition and segment byte for byte, with nothing re-encoded. The docs give this request:

curl --location 'https://api.aiozstream.network/api/media/create' \
--header 'stream-public-key: your_public_key_here' \
--header 'stream-secret-key: your_secret_key_here' \
--header 'Content-Type: application/json' \
--data '{
    "title": "My imported video",
    "source_url": "https://cdn.example.com/videos/my-video/master.m3u8"
}'

The import rules map directly onto the tags above. Your source must be a master playlist where every variant declares RESOLUTION, and a bare media playlist is rejected. Each variant must end with EXT-X-ENDLIST, so live and EVENT playlists aren't supported. EXT-X-BYTERANGE and encryption through EXT-X-KEY aren't supported either, and each variant may have at most one EXT-X-MAP. MPEG-TS and fMP4 segments both work. The limits are 2 MiB per playlist, 200 MiB per segment, 5,000 segments per rendition, 10 renditions per video and 4 hours per rendition.

A successful request returns 202 Accepted with status transcoding, and the video turns done when the copy finishes. The full requirements are in the Import video from M3U8 URL guide.

Frequently Asked Questions

Is this the same "chunking" as the chunked video upload tutorial?
No. Upload chunking splits a large source file into 50-200MB parts for a one-time upload. This article covers playback segmentation, which divides a finished, encoded video into short segments a player streams.

Do you need to transcode a video before HLS segmentation?
Yes, if you want adaptive bitrate. Each quality level must exist as its own encoded rendition before it is segmented, and a single rendition gives the player nothing to switch to.

What's the difference between a master playlist and a media playlist?
A master playlist lists media playlists, one per bitrate-ladder rung. A media playlist lists the short segments that play back in sequence.

Why did Apple change its recommended segment duration from 10 to 6 seconds?
To rebalance ABR reaction speed against request overhead: shorter segments let a player react to network changes sooner, at the cost of more requests.

What does EXT-X-BYTERANGE do?
It lets a playlist describe a segment as a byte range inside one larger file instead of a separate segment file, which reduces the number of files a server manages.

Can I set a custom segment duration on AIOZ Stream?
Not through a documented API field. You choose resolution, format, container, codec and bitrate per quality, and AIOZ Stream generates the manifests.

Can I import an existing HLS video into AIOZ Stream?
Yes, if it is a finished, unencrypted master playlist without byte ranges and every variant declares a resolution. AIOZ Stream copies the renditions without re-encoding them.

References

We only send updates when meaningful changes ship, and you can unsubscribe anytime

Related Content

blog thumbnail

Video Streaming Protocols: HLS, DASH, WebRTC, RTMP and SRT

Video streaming protocols move video from encoder to viewer. See how RTMP, SRT, HLS, DASH and WebRTC differ in latency, transport and where each one fits.

aioz-streamguide
7 min readNovember 04, 2026
blog thumbnail

What Is Decentralized Live Streaming and How Does It Work?

Decentralized live streaming sends a real-time broadcast through independently run nodes instead of one company's servers. Here's how each stage of it works.

aioz-streamguide
6 min readNovember 03, 2026
blog thumbnail

Video Streaming Glossary: Codecs, Protocols and Delivery A-Z

A video streaming glossary of 114 terms, from AAC and ABR to WebRTC and Widevine, each defined in plain English with sources and links to the deep posts.

aioz-stream
23 min readOctober 31, 2026
blog thumbnail

Monitor Livestream Health With Bitrate, FPS and Viewer Count

Read the AIOZ Stream Statistics panel: bitrate in and out, FPS in and out and current viewers, plus the documented rules for each and what the docs leave out.

aioz-streamguide
6 min readOctober 30, 2026
blog thumbnail

How to Embed a Livestream on Your Website (Link or iFrame)

Embed an AIOZ Stream livestream with the Share button's iframe or send the Public Playback URL as a link. Covers API fields, public access limits and doc gaps.

aioz-streamguide
6 min readOctober 27, 2026
blog thumbnail

Stream Key vs Streaming Session: Preconfiguring a Livestream

Learn how a stream key differs from a streaming session on AIOZ Stream, what each one stores, and what to preconfigure before you go live. Docs-based guide.

aioz-streamguide
7 min readOctober 23, 2026