How the make_playlist.py Script Generates M3U8 Files for IPTV
The make_playlist.py script converts Markdown channel listings from the lists/ directory into standards-compliant M3U8 playlists by parsing pipe-delimited entries and constructing EXTINF metadata lines for each channel.
The Free-TV/IPTV repository maintains curated television channel data as human-readable Markdown files. To transform these text-based listings into machine-readable playlists that modern IPTV clients can consume, the repository relies on make_playlist.py, a Python utility that orchestrates the generation of M3U8 files. This script bridges the gap between editable markdown syntax and the structured EXTINF format required by streaming applications.
Mapping Countries to ISO Codes
Before processing channels, the script establishes a geographic reference system. The COUNTRY_CODES dictionary (defined in lines 6-91 of make_playlist.py) maps folder names like usa or france to two-letter ISO country codes. These codes populate the tvg-country attribute in each EXTINF line, enabling IPTV clients to filter channels by region.
Parsing Markdown with the Channel Class
At the heart of the conversion logic sits the Channel class (lines 94-114). This class transforms a raw markdown line into a structured Python object capable of emitting M3U8-compliant output.
The constructor accepts three parameters: the current group title, the raw markdown line, and an optional country code. It splits the line on the pipe (|) delimiter to extract:
- The channel number
- The channel name
- The stream URL (wrapped in parentheses)
- The logo URL (extracted from an
<img src="...">tag) - An optional EPG identifier
If an EPG ID is present, the script stores it for later inclusion in the tvg-id attribute.
Building EXTINF Lines
Each Channel instance generates its M3U8 representation through the to_m3u_line() method (lines 114-120). This method constructs a string following the exact M3U8 specification:
#EXTINF:-1 tvg-name="..." tvg-logo="..." tvg-id="..." tvg-chno="..." tvg-country="..." group-title="...",ChannelName
URL
The method dynamically includes optional attributes only when data is present, ensuring clean output without empty parameters.
Orchestrating Playlist Creation
The main() function (lines 123-161) serves as the execution coordinator, handling file system operations and iteration logic.
Path and Directory Setup
The script first determines repository paths (lines 123-130):
base_dir: The repository rootlists/: The source directory containing markdown filesplaylists/: The output directory (created if missing)
EPG Header Construction
The script reads epglist.txt to build the master playlist header (lines 131-135). This produces the line:
#EXTM3U x-tvg-url="url1, url2, ..."
This header precedes every generated playlist, informing clients where to fetch electronic program guide data.
Processing Country Files
For each *.md file in lists/ (excluding README.md), the script:
- Derives a country key from the filename (e.g.,
usa.md→usa) - Looks up the corresponding ISO code via
COUNTRY_CODES - Opens a matching output file at
playlists/playlist_<country>.m3u8(lines 136-145)
Converting Channel Entries
Within each markdown file, the script processes lines sequentially (lines 150-158):
- Group detection: Lines containing
<h1>tags establish newgroup-titlevalues for subsequent channels - Channel markers: Only lines containing
"[>]"are treated as channel entries - Dual output: Each channel appends to both the per-country playlist and the master
playlist.m3u8
Running the Generator
Execute the script from the repository root:
python3 make_playlist.py
The script produces two categories of output:
playlist.m3u8: The global playlist aggregating every channelplaylists/playlist_<country>.m3u8: Individual files for each country code (e.g.,playlist_usa.m3u8,playlist_uk.m3u8)
A generated EXTINF entry appears as:
#EXTINF:-1 tvg-name="BBC One" tvg-logo="https://example.com/logo.png" tvg-id="bbc_one" tvg-chno="101" tvg-country="GB" group-title="United Kingdom",BBC One
http://stream.example.com/bbc_one.m3u8
Summary
- The
COUNTRY_CODESdictionary (lines 6-91) maps regions to ISO codes for thetvg-countryattribute - The
Channelclass (lines 94-114) parses pipe-delimited markdown and extracts logos from HTML tags - The
to_m3u_line()method (lines 114-120) generates compliant EXTINF metadata strings - The
main()function (lines 123-161) coordinates file I/O, EPG header injection, and dual playlist output - Input markdown files reside in
lists/; output M3U8 files write toplaylists/and the repository root
Frequently Asked Questions
What is the M3U8 format used for in IPTV?
M3U8 is a UTF-8 encoded playlist format that streaming applications use to organize media URLs. IPTV clients read these files to populate channel lists, display electronic program guide (EPG) data, and handle stream switching. The Free-TV/IPTV repository generates M3U8 files specifically to ensure compatibility with popular players like VLC, Kodi, and dedicated IPTV applications.
How does the script handle EPG data?
The script reads epglist.txt to construct the x-tvg-url header attribute (lines 131-135), which points clients to XMLTV program guide sources. Individual channels may specify tvg-id attributes in their markdown definitions, allowing the generated playlists to link specific streams to their corresponding EPG entries for program scheduling and metadata.
What determines the group-title attribute in the generated playlists?
The group-title attribute derives from <h1> headings within the source markdown files. When make_playlist.py encounters an HTML header tag while iterating through a country file (lines 150-153), it updates the current group context. All subsequent channels inherit this group title until the script encounters a new <h1> tag, creating logical channel groupings like "News" or "Sports" in the final M3U8 output.
Can I run make_playlist.py without the full repository?
No, the script depends on the repository structure present in Free-TV/IPTV. It specifically requires the lists/ directory containing markdown channel definitions and the epglist.txt file for EPG URL generation. Attempting to run the script outside this context will fail when the code attempts to locate these resources (lines 123-130).
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 →