Skip to main content

Overview

The m3u_parser module provides functionality to parse M3U/M3U8 playlist files and extract channel information including metadata, streaming URLs, DRM configuration, and HTTP headers.

Classes

PlaylistItem

Represents a single channel entry from an M3U playlist with all associated metadata and streaming configuration.
class PlaylistItem:
    def __init__(self)

Attributes

title
str
default:""
Channel display name (extracted from #EXTINF line)
url
str
default:""
Streaming URL (HLS, DASH, or direct stream)
Channel logo URL (from tvg-logo attribute)
group_title
str
default:""
Channel category/group (from group-title attribute)
user_agent
str
default:""
Custom User-Agent header for HTTP requests
Cookie string for authentication
referer
str
default:""
Referer header value
license_string
str
default:""
DRM license key or license server URL
headers
dict
default:"{}"
Additional HTTP headers as key-value pairs
is_drm
bool
default:"False"
Whether this channel requires DRM (set to True when license_string is present)

Methods

to_json()
Serializes the PlaylistItem to a JSON string.
def to_json(self) -> str
Returns:
json_string
str
JSON string representation of the object’s __dict__
Example:
item = PlaylistItem()
item.title = "Sports Channel"
item.url = "https://example.com/stream.m3u8"
json_str = item.to_json()
print(json_str)  # {"title": "Sports Channel", "url": "https://...", ...}
to_dict()
Converts the PlaylistItem to a dictionary.
def to_dict(self) -> dict
Returns:
dict
dict
Dictionary representation of the object’s attributes
from_dict()
Static method to create a PlaylistItem from a dictionary.
@staticmethod
def from_dict(data)
data
dict
required
Dictionary containing PlaylistItem attributes
Returns:
item
PlaylistItem
New PlaylistItem instance with attributes populated from the dictionary
Example:
data = {
    "title": "News Channel",
    "url": "https://example.com/news.m3u8",
    "tvg_logo": "https://example.com/logo.png"
}
item = PlaylistItem.from_dict(data)
print(item.title)  # "News Channel"

Functions

parse_m3u()

Parses M3U playlist content and extracts channel information.
def parse_m3u(content: str)
content
str
required
The raw M3U playlist content as a string
Returns:
items
list[PlaylistItem]
List of parsed PlaylistItem objects, one for each channel in the playlist
Supported M3U Directives:
DirectivePurposeExample
#EXTINFChannel metadata#EXTINF:-1 tvg-logo="logo.png" group-title="Sports",ESPN
#EXTVLCOPTVLC-specific options#EXTVLCOPT:http-user-agent=Mozilla/5.0
#EXTHTTPCustom HTTP headers (JSON)#EXTHTTP:{"cookie":"session=abc","user-agent":"Custom"}
#KODIPROPKodi properties (DRM)#KODIPROP:inputstream.adaptive.license_key=https://license.url
Parsing Logic:
The parser uses a buffering system to collect metadata lines before encountering the URL line:
  1. Reads #EXTINF to extract tvg-logo, group-title, and channel title
  2. Reads #EXTVLCOPT to extract user-agent and referer
  3. Reads #EXTHTTP to parse JSON headers for cookie and user-agent
  4. Reads #KODIPROP to extract DRM license configuration
  5. When a non-comment line (URL) is found, creates PlaylistItem with buffered data
  6. Handles pipe-separated parameters: url|User-Agent=...&Referer=...
M3U Format Example:
#EXTM3U
#EXTINF:-1 tvg-logo="https://example.com/logo.png" group-title="Sports",Cricket Live
#EXTVLCOPT:http-user-agent=Mozilla/5.0
#EXTVLCOPT:http-referrer=https://example.com
#KODIPROP:inputstream.adaptive.license_key=a1b2c3d4:e5f6g7h8
https://stream.example.com/cricket.m3u8

#EXTINF:-1 tvg-logo="https://example.com/news.png" group-title="News",World News
#EXTHTTP:{"cookie":"session=xyz","user-agent":"CustomAgent/1.0"}
https://stream.example.com/news.m3u8|Referer=https://example.com
Example:
from lib.m3u_parser import parse_m3u

m3u_content = """
#EXTM3U
#EXTINF:-1 tvg-logo="logo.png" group-title="Sports",ESPN
https://example.com/espn.m3u8
#EXTINF:-1 group-title="News",CNN
https://example.com/cnn.m3u8|User-Agent=Mozilla/5.0
"""

channels = parse_m3u(m3u_content)
for channel in channels:
    print(f"Title: {channel.title}")
    print(f"URL: {channel.url}")
    print(f"Group: {channel.group_title}")
    print(f"Logo: {channel.tvg_logo}")
    print(f"User-Agent: {channel.user_agent}")
    print("---")
Output:
Title: ESPN
URL: https://example.com/espn.m3u8
Group: Sports
Logo: logo.png
User-Agent: 
---
Title: CNN
URL: https://example.com/cnn.m3u8
Group: News
Logo: 
User-Agent: Mozilla/5.0
---

Special Handling

Pipe-Separated Parameters

The parser supports URL lines with pipe-separated parameters:
http://example.com/stream.m3u8|User-Agent=Custom&Referer=http://site.com&Cookie=abc=123
  • Parameters before the pipe are treated as the URL
  • Parameters after the pipe are parsed as key=value pairs separated by &
  • Standard headers (User-Agent, Referer, Cookie) are mapped to specific attributes
  • Non-standard headers are stored in the headers dictionary

DRM Detection

When a #KODIPROP:inputstream.adaptive.license_key directive is found:
  • The license_string attribute is set to the license key/URL
  • The is_drm flag is set to True
  • This enables DRM-protected stream playback in Kodi

Build docs developers (and LLMs) love