How the IPTV Stream Data Model Works in iptv-org/iptv
The IPTV stream data model in iptv-org/iptv wraps every HLS/M3U8 link in a TypeScript Stream class that parses metadata from M3U playlists, handles geographic broadcast data, and serializes back to standard M3U format.
The iptv-org/iptv repository manages thousands of live TV streams using a structured IPTV stream data model that transforms raw M3U playlist entries into typed, queryable objects. Understanding this architecture is essential for contributors working with playlist generation, API integrations, or stream validation tools.
Class Hierarchy and Core Architecture
Extending the SDK Base Model
The repository's Stream class extends sdk.Models.Stream from the external @iptv-org/sdk package. This inheritance provides foundational fields like channel, feed, url, and title, while the local implementation adds repository-specific helpers, lazy-filled properties, and serialization logic that understands the local playlist format.
File Location and Structure
The core implementation resides in scripts/models/stream.ts, which imports the base SDK model and the iptv-playlist-parser package to handle raw M3U data. This file defines the Stream class, its static factory methods, and instance methods for normalization and geographic lookups.
Constructing Streams from Playlist Data
The fromPlaylistItem Factory Method
When the iptv-playlist-parser processes a raw M3U file, it generates parser.PlaylistItem objects. The static Stream.fromPlaylistItem method transforms these into fully-fledged Stream instances by parsing the tvg-id, extracting quality markers from the name field, and capturing HTTP headers.
// source: scripts/models/stream.ts – lines 34-74
static fromPlaylistItem(data: parser.PlaylistItem): Stream {
// …parse the human‑readable name to extract title, label and quality…
const [channelId, feedId] = data.tvg.id.split('@')
const { title, label, quality } = parseName(data.name)
const stream = new Stream({
channel: channelId || null,
feed: feedId || null,
title,
quality: quality || null,
url: data.url,
referrer: data.http.referrer || null,
user_agent: data.http['user-agent'] || null
})
stream.tvgId = data.tvg.id // keep the original tvg‑id
stream.line = data.line // line number in the source file
stream.label = label || null
return stream
}
This factory method splits the tvg-id (formatted as channel@feed) into separate channel and feed identifiers, enabling precise linkage to the channel database. It also strips quality indicators like [720p] from the stream name while preserving them in the quality property.
Core Properties and Metadata
The Stream class maintains a rich set of properties that bridge raw playlist data with the structured channel database:
channelandfeed: Identifiers extracted from thetvg-idthat link to specific channel entries in the database repository.tvgId: The complete "channel@feed" string required by most IPTV players for electronic program guide (EPG) matching.url: The direct stream URL, normalized vianormalizeURL()to handle encoding inconsistencies.title,label, andquality: Human-readable descriptors parsed from the#EXTINFname field, with quality strings like "720p" extracted into structured data.groupTitle: Playlist grouping category, defaulting to "Undefined" unless overridden by API configuration.referreranduser_agent: Optional HTTP headers captured from#EXTVLCOPTmetadata lines, required by some geo-restricted streams.filepath: The target playlist file (e.g.,us.m3u) determined lazily byupdateFilepath()based on the channel's broadcast countries.line: The original line number in the source playlist, enabling precise error reporting and debugging.
Normalization and Helper Methods
The Stream class provides several utility methods to ensure data consistency and enable efficient processing:
URL Normalization: The normalizeURL() method delegates to the shared utility in scripts/utils.ts to resolve whitespace, percent-encoding, and protocol quirks before storage.
Uniqueness Keys: getUniqKey() generates a deterministic identifier combining filepath, tvgId, and url to prevent duplicate entries across playlist files.
Resolution Extraction: getVerticalResolution() parses quality strings (e.g., "720p") to extract numeric height values for filtering and sorting operations.
Geographic and Categorical Lookups
Because each stream maintains a reference to its parent feed, it can traverse the broadcast hierarchy to determine geographic availability:
// Example: get all countries a stream reaches
const countries = stream.getBroadcastCountries()
countries.forEach(c => console.log(`${c.name} (${c.code})`))
The getBroadcastCountries() method iterates over the feed's broadcast area, mapping each location type (country, subdivision, or city) back to Country models loaded from the database repository (data.countriesKeyByCode). Similar helpers exist for subdivisions (getBroadcastSubdivisions), cities (getBroadcastCities), and regions (getBroadcastRegions), enabling complex filtering logic for playlist generation.
Serialization to M3U Format
The toString() method handles conversion back to standard M3U playlist format, supporting both internal and public output modes:
// source: scripts/models/stream.ts – lines 91-122
toString(options: { public?: boolean } = {}) {
const public = options.public ?? false
let output = `#EXTINF:-1 tvg-id="${this.getTvgId()}"`
if (public) {
output += ` tvg-logo="${this.getTvgLogo()}"`
if (this.referrer) output += ` http-referrer="${this.referrer}"`
if (this.user_agent) output += ` http-user-agent="${this.user_agent}"`
output += ` group-title="${this.groupTitle}"`
}
output += `,${this.getFullTitle()}`
if (this.referrer) output += `\r\n#EXTVLCOPT:http-referrer=${this.referrer}`
if (this.user_agent) output += `\r\n#EXTVLCOPT:http-user-agent=${this.user_agent}`
output += `\r\n${this.url}`
return output
}
In public mode, the method exposes additional attributes including tvg-logo, HTTP referrer headers, and user-agent strings required by certain players. The output always includes the canonical tvg-id and preserves #EXTVLCOPT lines for VLC-specific options before appending the final URL.
Summary
- The IPTV stream data model centers on the
Streamclass inscripts/models/stream.ts, which extends the base SDK model to add repository-specific functionality. - Streams are constructed from raw M3U data via
Stream.fromPlaylistItem(), parsingtvg-idvalues and quality markers into structured properties. - The model maintains rich metadata including geographic broadcast areas, HTTP headers, and normalization utilities for deduplication.
- Serialization via
toString()generates standard M3U output compatible with VLC, Kodi, and other IPTV players, supporting both internal processing and public distribution formats.
Frequently Asked Questions
What is the relationship between the Stream class and the @iptv-org/sdk package?
The repository's Stream class extends sdk.Models.Stream from the external @iptv-org/sdk package. This inheritance provides foundational fields like channel, feed, and url, while the local implementation in scripts/models/stream.ts adds playlist-specific parsing, geographic lookups, and M3U serialization logic that handles the repository's unique data format.
How does the IPTV stream data model handle quality indicators like "720p" or "HD"?
When constructing a Stream instance via fromPlaylistItem(), the class parses the human-readable name field using a helper function called parseName(). This extracts quality strings (e.g., "720p", "1080p") into the quality property, while labels like "[HD]" or "[SD]" populate the label property. The cleaned title is stored separately, allowing players to display stream information without raw formatting artifacts.
Can the Stream model determine which countries a stream is available in?
Yes, through the getBroadcastCountries() method. Because each stream maintains a reference to its parent feed, it can traverse the broadcast hierarchy defined in the database repository. The method maps location codes (countries, subdivisions, or cities) back to Country models loaded from data.countriesKeyByCode, returning an array of country objects that represent the geographic availability of that specific stream.
How does the Stream class generate the final M3U playlist output?
The toString() method handles serialization, accepting an optional public flag. It constructs the standard #EXTINF line with the tvg-id, and when in public mode, appends additional attributes like tvg-logo, http-referrer, http-user-agent, and group-title. The method also inserts #EXTVLCOPT lines for VLC-specific HTTP headers before appending the final stream URL, producing output compatible with most IPTV players including VLC, Kodi, and Perfect Player.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →