How Free-TV/IPTV Loads EPG URLs from epglist.txt into M3U8 Headers

The Free-TV/IPTV generator reads EPG URLs from epglist.txt, aggregates them into a comma-separated string, and injects them into the x-tvg-url attribute of the #EXTM3U header in every generated playlist.

The Free-TV/IPTV repository automatically builds IPTV playlists by aggregating channel streams and Electronic Program Guide (EPG) metadata. Understanding how EPG URLs are loaded from epglist.txt and added to M3U8 headers reveals the mechanism that ensures media players can retrieve program data for all channels.

The EPG Loading Pipeline in make_playlist.py

According to the Free-TV/IPTV source code, the entire workflow is implemented in [make_playlist.py](https://github.com/Free-TV/IPTV/blob/master/make_playlist.py), where the script transforms raw EPG URLs into properly formatted M3U8 headers through a four-step sanitization and injection process.

Step 1: Reading and Sanitizing epglist.txt (Lines 31-33)

First, the script opens epglist.txt with UTF-8 encoding and creates a list containing each non-empty line with surrounding whitespace removed. This ensures clean URL processing while filtering out blank lines.

with open(os.path.join(base_dir, "epglist.txt"), encoding='utf-8') as epg_file:
    epg_urls = [line.strip() for line in epg_file if line.strip()]

Step 2: Aggregating URLs into a Comma-Separated String (Line 34)

The cleaned list of URLs is joined into a single string using ", " as the delimiter. This produces a comma-separated value format required by the M3U8 specification for multiple EPG sources.

processed_epg_list = ", ".join(epg_urls)

Step 3: Constructing the M3U8 Header (Lines 34-35)

The aggregated string is embedded into the x-tvg-url attribute of the #EXTM3U directive using an f-string. This attribute tells media players where to fetch EPG data for the channels in the playlist.

head_playlist = f'#EXTM3U x-tvg-url="{processed_epg_list}"\n'

Step 4: Writing to the Master Playlist (Lines 36-38)

Finally, the complete header is written to playlist.m3u8 before any channel entries are appended. This ensures the EPG metadata appears at the top of the file where media players expect to find it.

with open(os.path.join(base_dir, "playlist.m3u8"), "w", encoding='utf-8') as playlist:
    playlist.write(head_playlist)

Complete Implementation Example

Here is the complete workflow for generating the master playlist with EPG headers, as implemented in the repository:

import os

base_dir = os.path.abspath(os.path.dirname(__file__))
epg_path = os.path.join(base_dir, "epglist.txt")

# Load and clean EPG URLs from epglist.txt

with open(epg_path, encoding="utf-8") as f:
    epg_urls = [line.strip() for line in f if line.strip()]

# Build the M3U8 header with x-tvg-url attribute

header = f'#EXTM3U x-tvg-url="{", ".join(epg_urls)}"\n'

# Write the header to the final playlist

with open(os.path.join(base_dir, "playlist.m3u8"), "w", encoding="utf-8") as out:
    out.write(header)
    # Channel entries would be appended here...

Resulting M3U8 Header Format

The generated playlist.m3u8 file begins with a single header line containing all EPG sources. The output follows this exact structure:


#EXTM3U x-tvg-url="https://epgshare01.online/epgshare01/epg_ripper_AL1.xml.gz, https://epgshare01.online/epgshare01/epg_ripper_ALJAZEERA1.xml.gz, https://epgshare01.online/epgshare01/epg_ripper_ALL_SOURCES1.xml.gz, ..."

All subsequent #EXTINF channel entries and stream URLs are appended after this header, ensuring media players parse the EPG metadata before processing individual channels.

Summary

  • epglist.txt serves as the canonical source for all Electronic Program Guide URLs in the Free-TV/IPTV ecosystem.
  • The make_playlist.py script processes this file at lines 31-33, stripping whitespace and filtering empty lines to create a clean URL list.
  • URLs are aggregated into a comma-separated string at line 34, then injected into the x-tvg-url attribute of the #EXTM3U header.
  • Every generated playlist file begins with this EPG-enriched header, ensuring compatibility with media players that support XMLTV program guides.

Frequently Asked Questions

What is the purpose of the x-tvg-url attribute in M3U8 files?

The x-tvg-url attribute is a non-standard but widely supported extension that specifies the location of XMLTV-formatted EPG data. Media players like VLC, Kodi, and IPTV apps read this attribute to download program schedules and display TV guide information alongside live channels.

How does the script handle empty lines or whitespace in epglist.txt?

The list comprehension [line.strip() for line in epg_file if line.strip()] first checks if a line contains non-whitespace characters with if line.strip(), then removes leading and trailing whitespace with line.strip(). This ensures no empty entries or malformed URLs reach the final playlist header.

Can I use multiple EPG sources in a single playlist?

Yes. The script explicitly supports multiple EPG sources by joining all URLs with ", " (comma-space) into a single string. According to the M3U8 specification used by most IPTV players, multiple XMLTV sources can be listed in the x-tvg-url attribute as comma-separated values, allowing the player to fetch program data from multiple repositories.

Where is the generated playlist.m3u8 file saved?

The script writes playlist.m3u8 to the repository's root directory, specifically at os.path.join(base_dir, "playlist.m3u8"), where base_dir is the directory containing make_playlist.py. This master playlist contains all aggregated channels from the repository's country-specific subdirectories.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →