Registry / http-networking / m3u8
library6.0.0pypypi✓ verified 23d ago

m3u8 is a Python library designed to parse M3U8 HTTP Live Streaming (HLS) playlists. It allows loading playlists from URIs, file paths, or strings, and provides access to segments, streams, and other HLS tag information. The library is actively maintained, with its current version being 6.0.0, and receives regular updates to support new HLS specifications and bug fixes.

pip install m3u8
INSTALL
IMPORT
SIG · M3U8
M
m3u8
http-networkingpythonv6.0.0
Install
1.6s avg
Import
134ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v6.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.138s · 18.2MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.6s · import 0.130s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

load
from m3u8 import load
import m3u8

This quickstart demonstrates how to load an M3U8 playlist from a string using `m3u8.loads()` and access its basic properties like target duration and individual segments. An commented-out section shows how to load directly from a URL using `m3u8.load()` for live HLS streams.

import m3u8 import requests import os # Example: Load a remote M3U8 playlist # In a real scenario, use a specific, stable M3U8 URL. # For a runnable example, we'll use a placeholder or local file. # For demonstration, we'll simulate a playlist string. # --- Option 1: Load from a URL (requires internet access) --- # remote_m3u8_url = 'https://example.com/path/to/playlist.m3u8' # Replace with a real M3U8 URL if testing live # try: # playlist = m3u8.load(remote_m3u8_url) # print(f"Loaded playlist from URL: {remote_m3u8_url}") # if playlist.segments: # print(f"First segment URI: {playlist.segments[0].uri}") # else: # print("No segments found in remote playlist.") # except requests.exceptions.RequestException as e: # print(f"Error loading remote playlist: {e}") # --- Option 2: Load from a string (always runnable) --- local_m3u8_content = """ #EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:9.009, http://example.com/segment0.ts #EXTINF:10.000, http://example.com/segment1.ts #EXT-X-ENDLIST """ playlist_from_string = m3u8.loads(local_m3u8_content) print("\n--- Playlist from String ---") print(f"Target Duration: {playlist_from_string.target_duration}") print(f"Number of segments: {len(playlist_from_string.segments)}") if playlist_from_string.segments: print(f"First segment URI: {playlist_from_string.segments[0].uri}") # Iterate through segments print("\nSegments:") for i, segment in enumerate(playlist_from_string.segments): print(f" Segment {i}: Duration={segment.duration}, URI={segment.uri}")
Debug
Known issues
breakingIn version 6.0.0, the 'BITRATE' attribute within `StreamInfo` (e.g., `playlist.playlists[0].stream_info.bandwidth['BITRATE']`) is now parsed as an integer type instead of a string. Code expecting a string for bitrate values will need to be updated.
fix
Ensure your code handles `BITRATE` values as integers. If string representation is required, cast it explicitly: `str(playlist.playlists[0].stream_info.bandwidth['BITRATE'])`.
affects: 6.0.0 and later
breakingStarting from version 5.2.0, `target_duration` is consistently parsed as an integer. Previous versions might have returned it as a float or string, which could break code expecting those types.
fix
Adjust code to expect and handle `playlist.target_duration` as an integer. Cast if other types are explicitly needed: `float(playlist.target_duration)`.
affects: 5.2.0 and later
breakingVersion 4.0.0 dropped compatibility with Python 2.x and updated to require Python 3.7 or newer. Additionally, it now leverages built-in ISO 8601 parsing for Python 3.11+.
fix
Upgrade your Python environment to 3.7 or higher. Review and update any Python 2 specific code if migrating an older project.
affects: 4.0.0 and later
gotchaWhen parsing playlists, especially those loaded from a URI, segment URIs can be relative. Accessing `segment.uri` directly might yield a relative path. Use `segment.absolute_uri` to get the full, resolved URL if absolute paths are required for downloading or further processing.
fix
Always prefer `segment.absolute_uri` when constructing URLs for segments or keys to ensure correct resolution against the playlist's `base_uri`.
affects: All versions
gotchaThe library, by default, ignores non-standard M3U8 tags (i.e., tags not defined in the HLS specification). If you need to parse or extract information from custom tags (e.g., `#MOVIE-NAME:`), you must provide a custom parser function.
fix
Pass a `custom_tags_parser` function to `m3u8.load()` or `m3u8.loads()`. This function will be called for each line of the playlist, allowing you to process and store custom tag data.
affects: All versions
Upgrade
Version history
6.0.0latest on PyPI · released Aug 7, 2024
Audit
Dependencies
iso8601requiredUsed for parsing ISO 8601 date/time strings within M3U8 playlists.
Agent activity
5 hits · last 30 days
node
4
Resources
m3u8 — pip install m3u8 · libregistry