M3U8 File Format in HLS: Developer Guide

What is an m3u8 file?

The m3u8 file is a playlist file format used in the HTTP Live Streaming (HLS) protocol, based on the UTF-8 encoded m3u playlist. An m3u8 file is essentially a text file that contains metadata and segment information for media streams, enabling clients to dynamically adapt video streams under different bandwidth conditions.

Basic Structure Analysis

A simplest m3u8 file must start with the #EXTM3U tag, which is the identifier for the m3u8 file:

#EXTM3U

Master Playlist

The Master Playlist contains multiple stream versions with different bit rates, allowing the client to automatically select the most suitable stream based on network conditions:

#EXTM3U
#EXT-X-VERSION:6

# Video stream
#EXT-X-STREAM-INF:BANDWIDTH=1500000,RESOLUTION=640x360,CODECS="avc1.42e00a,mp4a.40.2"
video_low.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=854x480,CODECS="avc1.4d401f,mp4a.40.2"
video_medium.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=4500000,RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2"
video_high.m3u8

#EXT-X-I-FRAME-STREAM-INF:RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2",BANDWIDTH=92606,AVERAGE-BANDWIDTH=47706,URI="video_high_I-Frame.m3u8"
  • #EXT-X-VERSION: Specifies the HLS protocol version. If ≥ 7, it indicates fmp4 encapsulation; ≤ 6 does not determine the encapsulation form, and you also need to check for the presence of #EXT-X-MAP.

  • #EXT-X-STREAM-INF: Describes the properties of the subsequent stream, including:

    • BANDWIDTH: Bandwidth requirement (bits per second)
    • RESOLUTION: Resolution
    • CODECS: Codec information. Common codec information includes:
      • avc: h264 encoding
      • hvc: h265 encoding
      • dvc: h265 Dolby Vision encoding
      • mp4a: Audio aac encoding, suitable for music, podcasts, short videos
      • ac-3: Audio Dolby Digital, suitable for DVD, SD TV
      • ec-3: Audio Enhanced Dolby, suitable for Blu-ray, 4K streaming, cinema
  • #EXT-X-I-FRAME-STREAM-INF: This content is the #EXT-X-I-FRAME-STREAM-INF tag used in the M3U8 playlist to describe I-Frame (Key Frame) stream information, mainly used to support fast seeking, preview, or thumbnail generation for video. The specific meanings of the parameters are as follows:

    • BANDWIDTH: Bandwidth requirement (bits per second)

    • RESOLUTION: Resolution

    • CODECS: Codec information. Common codec information includes:

    • AVERAGE-BANDWIDTH=47706: The average bandwidth requirement of this keyframe stream, in bps, serving as a reference for the player when selecting a stream (reflecting overall bandwidth consumption better than peak bandwidth).

    • URI: Points to the index file address of this keyframe stream. This index file (video_high_I-Frame.m3u8) contains specific information such as the location and duration of all keyframes, allowing the player to directly obtain keyframe data at the target time point.

Media Playlist

The Media Playlist contains information about the actual media segments:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:10.0,
segment0.ts
#EXTINF:10.0,
segment1.ts
#EXTINF:10.0,
segment2.ts
#EXT-X-ENDLIST

Description of key tags:

  • #EXT-X-TARGETDURATION: Specifies the maximum duration of each segment (in seconds)
  • #EXT-X-MEDIA-SEQUENCE: The sequence number of the first segment in the playlist
  • #EXTINF: Segment duration, followed by the segment filename
  • #EXT-X-ENDLIST: Indicates the playlist is no longer updated (if present, it signifies VOD; live streams lack this field)

Initialization Segment (init segment)

To improve efficiency and compatibility, and to support HEVC (H265) playback, Apple released HLS 7.0 (#EXT-X-VERSION=7) at the 2017 WWDC, starting support for fMP4 (Fragmented MP4) based slicing. fMP4 is a fragmented version of the MP4 format where each slice is an independent, playable MP4 file. It not only has lower encapsulation overhead but also integrates better with the MPEG-DASH protocol. Later, based on fmp4, further support for the CMAF encapsulation standard was added. After adopting the CMAF standard, content providers only need to encode and store a single video file to serve both HLS and DASH clients, significantly saving storage and CDN costs.

For fMP4 and CMAF containers, the m3u8 file will contain the #EXT-X-MAP tag, used to specify the initialization segment (init segment), which is key to parsing fMP4.

The initialization segment is usually an independent, small file containing the moov atom from the ISO Base Media File Format (i.e., the MP4 container format).

Example:

#EXT-X-MAP:URI="init.mp4"

You can use tools like ffprobe to view its detailed information. The command is as follows:

ffprobe -v error -show_format -show_streams init.mp4

Example of displayed content:

[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10

...
[FORMAT]
filename=init.mp4
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
...
[/FORMAT]
    • Key Information
      • codec_name: Shows the encoding format: h264, H265.
      • format_name field:
        • If it is mp4 or mov,mp4,m4a,3gp,3g2,mj2, it is fMP4.
        • If it is mpegts, it is TS encapsulation.

Subtitle Track Configuration

HLS supports multiple subtitle formats, including WebVTT, TTML, and CEA-608/708. Subtitles are implemented by defining the EXT-X-MEDIA tag in the Master Playlist:

#EXTM3U
#EXT-X-VERSION:6

# Video stream
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=854x480
video_medium.m3u8

# Subtitle track - English
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English",DEFAULT=YES,
             FORCED=NO,LANGUAGE="en",URI="subtitles_en.m3u8"

# Subtitle track - Chinese
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="中文",DEFAULT=NO,
             FORCED=NO,LANGUAGE="zh",URI="subtitles_zh.m3u8"

# Subtitle track - Japanese
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="日本語",DEFAULT=NO,
             FORCED=NO,LANGUAGE="ja",URI="subtitles_ja.m3u8"

Example of a subtitle playlist (WebVTT format):

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD

# Specify WebVTT format
#EXT-X-SUBTITLES-FORMAT:WEBVTT
#EXT-X-SUBTITLES-LANGUAGE:en

#EXTINF:10.000,
subtitle0.vtt
#EXTINF:10.000,
subtitle1.vtt
#EXTINF:10.000,
subtitle2.vtt
#EXT-X-ENDLIST

Chapter Configuration

In M3U8 (HLS protocol), support for “Chapters” is mainly implemented through #EXT-X-CHAPTER series tags, used to divide video content into multiple logical chapters (such as intro, main feature acts, outro, etc.), facilitating the display of chapter lists and quick seeking by players. These tags are defined in HLS protocol version 8 and above (EXT-X-VERSION:8+).

Tag Purpose
#EXT-X-CHAPTER Marks the start of a chapter, requires URI or TIME-OFFSET to define chapter position
#EXT-X-CHAPTER-ID Assigns a unique ID to the chapter (optional, used to identify the chapter)
#EXT-X-CHAPTER-DURATION Defines the duration of the chapter (optional, unit: seconds, precise to 9 decimal places)
#EXT-X-CHAPTER-TITLE Defines the title of the chapter (optional, used for player display, supports UTF-8 characters)
#EXT-X-CHAPTER-URI Points to the media fragment corresponding to the chapter (optional, if the chapter corresponds to an independent media stream)
#EXT-X-CHAPTER-TIME-OFFSET Defines the start time offset of the chapter within the main media stream (relative to the start of the stream, unit: seconds)

2. Two Scenarios for Chapter Support and Examples

Scenario 1: Chapters are time segments within the same media stream (Most Common)

Chapters are divided based on the main media stream’s timeline, requiring no additional media files, and defining the start position via TIME-OFFSET only.

#EXTM3U
#EXT-X-VERSION:8  # Must use version 8 or above
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0

# Chapter 1: Intro (Starts at 0s, lasts 30s)
#EXT-X-CHAPTER
#EXT-X-CHAPTER-ID:chapter1
#EXT-X-CHAPTER-TITLE:片头
#EXT-X-CHAPTER-TIME-OFFSET:0.0
#EXT-X-CHAPTER-DURATION:30.0

# Chapter 2: Main Feature Act 1 (Starts at 30s, lasts 120s)
#EXT-X-CHAPTER
#EXT-X-CHAPTER-ID:chapter2
#EXT-X-CHAPTER-TITLE:正片 - 第一幕
#EXT-X-CHAPTER-TIME-OFFSET:30.0
#EXT-X-CHAPTER-DURATION:120.0

# Chapter 3: Outro (Starts at 150s, lasts 20s)
#EXT-X-CHAPTER
#EXT-X-CHAPTER-ID:chapter3
#EXT-X-CHAPTER-TITLE:片尾
#EXT-X-CHAPTER-TIME-OFFSET:150.0
#EXT-X-CHAPTER-DURATION:20.0

# Main media stream segments (Covering the time range of all chapters)
#EXTINF:10.0,
segment_0.ts
#EXTINF:10.0,
segment_1.ts
#EXTINF:10.0,
segment_2.ts
#EXTINF:10.0,
segment_3.ts
#EXTINF:10.0,
segment_4.ts
#EXTINF:10.0,
segment_5.ts
#EXTINF:10.0,
segment_6.ts
#EXTINF:10.0,
segment_7.ts
#EXTINF:10.0,
segment_8.ts
#EXTINF:10.0,
segment_9.ts

#EXT-X-ENDLIST

Scenario 2: Chapters correspond to independent media streams (Less Common)

Chapters point to independent media fragment files via URI, suitable for scenarios where chapter content is separated (e.g., multi-chapters encoded separately).

#EXTM3U
#EXT-X-VERSION:8
#EXT-X-TARGETDURATION:10

# Chapter 1: Independent intro media stream
#EXT-X-CHAPTER
#EXT-X-CHAPTER-ID:intro
#EXT-X-CHAPTER-TITLE:片头
#EXT-X-CHAPTER-URI:chapters/intro.m3u8  # Points to the intro sub-M3U8
#EXT-X-CHAPTER-DURATION:30.0

# Chapter 2: Independent main feature media stream
#EXT-X-CHAPTER
#EXT-X-CHAPTER-ID:main
#EXT-X-CHAPTER-TITLE:正片
#EXT-X-CHAPTER-URI:chapters/main.m3u8   # Points to the main feature sub-M3U8
#EXT-X-CHAPTER-DURATION:600.0

# Chapter 3: Independent outro media stream
#EXT-X-CHAPTER
#EXT-X-CHAPTER-ID:outro
#EXT-X-CHAPTER-TITLE:片尾
#EXT-X-CHAPTER-URI:chapters/outro.m3u8  # Points to the outro sub-M3U8
#EXT-X-CHAPTER-DURATION:20.0

#EXT-X-ENDLIST

3. Key Notes

  1. Version Requirement: Must be used in EXT-X-VERSION:8 or higher; lower versions do not support chapter tags.
  2. Player Compatibility: Not all HLS players support chapter display (some older players may ignore chapter tags); mainstream players (like Safari, VLC, latest ExoPlayer) usually support it.
  3. Tag Order: Chapter tags need to be placed before the media segment list (before #EXTINF), ensuring the player parses chapter information first.
  4. Time Precision: TIME-OFFSET and DURATION support up to 9 decimal places, allowing precision down to the nanosecond level, adapting to high-frame-rate video.

Through chapter tags, “Chapter Navigation” functionality similar to local video players can be implemented, enhancing the interactive experience for long-form videos (such as movies, courses).

Ad Insertion Marker Configuration

The mapping of the ad insertion standard SCTE-35 in HLS. Their core function is to define the timing points for “Main Content Interruption (Insert Ad)” and “Ad End (Resume Main Content)”.

The following two tags originate from support for SCTE-35 signals (ad insertion control signals in the broadcasting field) and are mainly used for Dynamic Ad Insertion (DAI) in streaming. The specific logic is:

  • #EXT-X-CUE-OUT:<duration>: Marks the interruption of main content here and the start of ad insertion. duration is the total scheduled duration of the ad (in seconds).
  • #EXT-X-CUE-IN: Marks the end of ad insertion and the resumption of main content playback.

Example:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10

# Main content segments
#EXTINF:10.0,
main_0.ts
#EXTINF:10.0,
main_1.ts

# Mark main content interruption, insert 15 seconds of ads
#EXT-X-CUE-OUT:15.0
#EXTINF:5.0,
ad_0.ts  # Ad segment 1
#EXTINF:5.0,
ad_1.ts  # Ad segment 2
#EXTINF:5.0,
ad_2.ts  # Ad segment 3

# Mark ad end, resume main content
#EXT-X-CUE-IN
#EXTINF:10.0,
main_2.ts
#EXTINF:10.0,
main_3.ts

#EXT-X-ENDLIST

Live Stream vs. VOD Stream

A VOD Stream contains the #EXT-X-ENDLIST tag, indicating a complete playlist:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
...
#EXT-X-ENDLIST

A Live Stream does not contain the end tag, and the client needs to periodically refresh to fetch new segments:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:2680

#EXTINF:10.0,
segment2680.ts
#EXTINF:10.0,
segment2681.ts

Encryption and DRM

m3u8 supports media encryption, providing basic content protection:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-KEY:METHOD=AES-128,URI="key.php",IV=0x9c7db8778570d05c2a4d7d5a7f5c8d9c
#EXTINF:10.0,
segment0.ts

Encryption related tags:

  • METHOD: Encryption method (NONE, AES-128, SAMPLE-AES)
  • URI: Key retrieval address
  • IV: Initialization Vector (optional)

Advanced Features

Segment Byte Range Access

Allows a single file to contain multiple segments, saving request overhead:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-BYTERANGE:82112@0

#EXTINF:10.0,
video.ts
#EXT-X-BYTERANGE:83232@82112
#EXTINF:10.0,
video.ts

Practical Application: Generating an m3u8 file with subtitles and ads

Here is a simple Node.js example demonstrating how to generate an m3u8 file containing subtitle and ad information:

function generateMasterPlaylist(videoStreams, subtitles) {
  let m3u8 = '#EXTM3U\n';
  m3u8 += '#EXT-X-VERSION:6\n';
  
  // Add video streams
  videoStreams.forEach(stream => {
    m3u8 += `#EXT-X-STREAM-INF:BANDWIDTH=${stream.bandwidth},RESOLUTION=${stream.resolution}\n`;
    m3u8 += `${stream.uri}\n`;
  });
  
  // Add subtitle tracks
  subtitles.forEach(sub => {
    m3u8 += `#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="${sub.name}",DEFAULT=${sub.default ? 'YES' : 'NO'},LANGUAGE="${sub.language}",URI="${sub.uri}"\n`;
  });
  
  return m3u8;
}

function generateMediaPlaylistWithChapters(segments, chapters) {
  let m3u8 = '#EXTM3U\n';
  m3u8 += '#EXT-X-VERSION:6\n';
  m3u8 += `#EXT-X-TARGETDURATION:${segments[0].duration}\n`;
  m3u8 += `#EXT-X-MEDIA-SEQUENCE:0\n`;
  
  let currentTime = 0;
  let chapterIndex = 0;
  
  segments.forEach((segment, index) => {
    // Check if ad markers need to be added
    if (adIndex < ads.length && 
        currentTime >= ads[adIndex].startTime) {
      m3u8 += `#EXT-X-CUE-OUT:${ads[adIndex].duration}\n`;
      adIndex++;
    }
    
    m3u8 += `#EXTINF:${segment.duration},\n`;
    m3u8 += `${segment.uri}\n`;
    
    currentTime += segment.duration;
  });
  
  m3u8 += '#EXT-X-ENDLIST\n';
  return m3u8;
}

Debugging and Validation

Developers can use the following tools to validate m3u8 files:

  1. FFmpeg:

    ffmpeg -i input.m3u8 -c copy output.mp4
  2. hls.js: An HLS client library for the Web, suitable for debugging playback issues

  3. Apple’s mediastreamvalidator: Official validation tool

  4. VLC Media Player: Supports playing HLS streams and displaying subtitle and chapter information

Best Practices

  1. Segment duration is recommended to be set between 6-10 seconds
  2. Ensure #EXT-X-TARGETDURATION is equal to or slightly greater than the actual longest segment
  3. For live streams, keep the playlist length moderate (usually containing the 4-6 most recent segments)
  4. Use a CDN to accelerate segment file delivery
  5. Consider enabling Gzip compression to reduce m3u8 file size
  6. Provide multi-language support for subtitles and set appropriate DEFAULT tracks
  7. Chapter markers should align precisely with I-frames to avoid inaccurate player seeking

Troubleshooting Common Issues

  1. Playback Failure: Check m3u8 file paths and segment file accessibility
  2. Stuttering: Check if segment durations are consistent and if network bandwidth is sufficient
  3. Encryption Issues: Confirm the key server is accessible and returns keys in the correct format
  4. Subtitles Not Displaying: Check subtitle file format and MIME type settings
  5. Inaccurate Chapter Markers: Ensure chapter start times align with keyframes

Real-world Example Analysis

The following example uses the address: https://d2zihajmogu5jn.cloudfront.net/elephantsdream/hls/ed_hd.m3u8

Content is as follows:

#EXTM3U

#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE="en",CHARACTERISTICS="public.accessibility.transcribes-spoken-dialog,public.accessibility.describes-music-and-sound",URI="manifest9/captions.en.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Swedish",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="sv",URI="manifest10/captions.sv.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Russian",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="ru",URI="manifest11/captions.ru.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Japanese",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="ja",URI="manifest12/captions.ja.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Arabic",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE="ar",URI="manifest13/captions.ar.m3u8"

#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="ed_audio_64k",LANGUAGE="en",NAME="Main",CHANNELS="2",AUTOSELECT=YES,DEFAULT=YES,URI="manifest5/index.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="ed_audio_64k",LANGUAGE="en",NAME="Audio Described",CHANNELS="2",AUTOSELECT=YES,DEFAULT=NO,CHARACTERISTICS="public.accessibility.describes-video",URI="manifest6/index.m3u8"

#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="ed_audio_128k",LANGUAGE="en",NAME="Main",CHANNELS="2",AUTOSELECT=YES,DEFAULT=YES,URI="manifest7/index.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="ed_audio_128k",LANGUAGE="en",NAME="Audio Described",CHANNELS="2",AUTOSELECT=YES,DEFAULT=NO,CHARACTERISTICS="public.accessibility.describes-video",URI="manifest8/index.m3u8"


#EXT-X-STREAM-INF:BANDWIDTH=2100000,AVERAGE-BANDWIDTH=800000,CODECS="mp4a.40.2, avc1.4d001e",RESOLUTION=480x270,FRAME-RATE=24,AUDIO="ed_audio_64k",SUBTITLES="subs"
manifest0/index.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=3300000,AVERAGE-BANDWIDTH=1050000,CODECS="mp4a.40.2, avc1.4d001f",RESOLUTION=640x360,FRAME-RATE=24,AUDIO="ed_audio_64k",SUBTITLES="subs"
manifest1/index.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=6000000,AVERAGE-BANDWIDTH=2000000,CODECS="mp4a.40.2, avc1.4d0028",RESOLUTION=854x480,FRAME-RATE=24,AUDIO="ed_audio_64k",SUBTITLES="subs"
manifest2/index.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=10000000,AVERAGE-BANDWIDTH=3000000,CODECS="mp4a.40.2, avc1.640028",RESOLUTION=1280x720,FRAME-RATE=24,AUDIO="ed_audio_128k",SUBTITLES="subs"
manifest3/index.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=21000000,AVERAGE-BANDWIDTH=6000000,CODECS="mp4a.40.2, avc1.64002a",RESOLUTION=1920x1080,FRAME-RATE=24,AUDIO="ed_audio_128k",SUBTITLES="subs"
manifest4/index.m3u8

This is a very typical and functionally complete HLS Master Playlist. It defines a complex media presentation containing multi-bitrate video streams, multi-language subtitles, and multi-version audio tracks.

Below is a detailed breakdown of its content section by section:

File Type

  • #EXTM3U: Indicates this is an M3U playlist file.

Part 1: Subtitle Track Definitions (#EXT-X-MEDIA:TYPE=SUBTITLES)

This section defines 5 subtitle tracks in different languages, all belonging to the same group GROUP-ID="subs".

  1. English Subtitles

    • TYPE=SUBTITLES: Media type is subtitles.
    • GROUP-ID="subs": Group identifier, video streams will reference this ID to associate subtitles.
    • NAME="English": Display name shown to the user.
    • DEFAULT=YES: Default selected. The player will automatically load this subtitle track upon first load.
    • AUTOSELECT=YES: If the player’s settings match the user’s language preference, this track will be automatically selected.
    • FORCED=NO: This is not a forced subtitle (e.g., one containing only translations of background audio).
    • LANGUAGE="en": Language code.
    • CHARACTERISTICS="...": Describes the subtitle’s characteristics (transcribes spoken dialog, describes music and sound effects), which is an accessibility feature.
    • URI="manifest9/captions.en.m3u8": Points to the playlist containing actual subtitle segments (such as WebVTT files).
  2. Swedish, Russian, Japanese, Arabic Subtitles

    • Parameters are similar to the English subtitles, but DEFAULT=NO (not default), and they do not have the CHARACTERISTICS attribute.
    • Each has its corresponding language code and exclusive playlist URI.

Summary: Users can choose subtitles from 5 languages (English, Swedish, Russian, Japanese, Arabic) in the player, with English being the default option.


Part 2: Audio Track Definitions (#EXT-X-MEDIA:TYPE=AUDIO)

This section defines two sets of audio tracks with different bit rates. Each set contains two versions: a main audio track and an audio description track.

First Group: 64kbps Audio Group (GROUP-ID="ed_audio_64k")

  1. Main Audio Track

    • TYPE=AUDIO: Media type is audio.
    • GROUP-ID="ed_audio_64k": Group identifier.
    • LANGUAGE="en": English.
    • NAME="Main": Name is “Main Audio”.
    • CHANNELS="2": Dual-channel stereo.
    • DEFAULT=YES: Default selection in this group.
    • URI="manifest5/index.m3u8": Points to the playlist for the 64kbps main audio track.
  2. Audio Description Track

    • NAME="Audio Described": This is an Audio Description version provided for visually impaired users, describing scenes, actions, and expressions during gaps in video dialogue.
    • CHARACTERISTICS="public.accessibility.describes-video": Explicitly points out its accessibility feature.
    • DEFAULT=NO: Not the default option.
    • Other attributes are the same as the main audio track.

Second Group: 128kbps Audio Group (GROUP-ID="ed_audio_128k")

  • Structure is identical to the first group, but with a higher bitrate (theoretically better audio quality), and the corresponding playlist URIs are different (manifest7/ and manifest8/).

Summary: Provides two audio quality options (64kbps and 128kbps). Under each quality, users can choose to listen to the standard main audio track or an auxiliary track with visual descriptions.


Part 3: Video Stream Definitions (#EXT-X-STREAM-INF)

This section defines 5 video streams with different bitrates and resolutions. The player will automatically select the most suitable one for playback based on current network bandwidth. All video streams do not include audio (audio is associated via the subsequent AUDIO attribute).

  1. 270p Low Bitrate Stream

    • BANDWIDTH=2100000: Peak bandwidth is approximately 2.1 Mbps.
    • AVERAGE-BANDWIDTH=800000: Average bandwidth is approximately 0.8 Mbps.
    • CODECS="mp4a.40.2, avc1.4d001e": Specifies codecs.
      • mp4a.40.2: AAC-LC audio codec (although this video stream contains no audio, this codec info refers to the format of the associated audio stream).
      • avc1.4d001e: H.264 video codec profile and level, corresponding to standard definition resolution.
    • RESOLUTION=480x270: Resolution 480x270 (270p).
    • FRAME-RATE=24: Frame rate 24 fps.
    • AUDIO="ed_audio_64k": Associated audio group. When this video stream is selected, the player will load the audio from GROUP-ID="ed_audio_64k".
    • SUBTITLES="subs": Associated subtitle group. Indicates that the available subtitle tracks are those in the GROUP-ID="subs" group.
    • manifest0/index.m3u8: Points to the media playlist file corresponding to this bitrate stream.
  2. 360p, 480p, 720p, 1080p Streams

    • The subsequent four streams follow a similar parameter pattern: bitrate, resolution, and video codec level (avc1.4d001f -> avc1.64002a) gradually increase to provide higher quality video.
    • Key Difference: The first three lower bitrate streams (270p, 360p, 480p) are associated with the ed_audio_64k audio group, while the two higher bitrate streams (720p, 1080p) are associated with the ed_audio_128k audio group. This is an optimization strategy to pair higher quality audio with high definition video.

Workflow

  1. Player Load: The player first loads this Master Playlist file.
  2. Get Options: Parses the list to learn that there are 5 video bitrates, 2 audio qualities (2 versions each), and 5 subtitles available.
  3. Adaptive Selection:
    • The player selects the most suitable one from the 5 video streams based on current network bandwidth (e.g., if network is good, select the 1080p stream from manifest4/index.m3u8).
    • Selects the corresponding audio track (e.g., the “Main” track from the ed_audio_128k group) and subtitles (e.g., “English”) based on user settings or defaults.
  4. Parallel Load: The player simultaneously loads the selected video stream playlist, audio stream playlist, and subtitle playlist, then downloads the corresponding audio, video, and subtitle segments for synchronized playback.
  5. Dynamic Switching: If network conditions change, the player will automatically and seamlessly switch between different bitrate video streams.

This m3u8 file embodies a very professional and user-friendly streaming media configuration, fully considering the experience under different network conditions, multi-language users, and the accessibility needs of visually impaired people.

Conclusion

As the core of the HLS protocol, m3u8 provides powerful adaptive streaming capabilities, including rich subtitle and chapter support. Understanding its file format and the meaning of various tags is crucial for developing streaming media applications. With the continuous development of HLS technology, it is recommended that developers keep paying attention to new tags and functions to provide a better streaming media experience.

Through the introduction of this article, you should have a comprehensive understanding of the m3u8 file format and be able to create, parse, and debug HLS streaming media playlists containing subtitles and chapters.

The zwplayer player is one of the few players that supports m3u8 format multi-bitrate adaptive playback and embedded subtitle playback. You are welcome to use it 😀