How to Integrate EPG (Electronic Program Guide) with IPTV Channels in Free-TV/IPTV
Integrating EPG with IPTV channels in the Free-TV/IPTV repository requires configuring global EPG sources in epglist.txt and adding EPG IDs to channel entries in the Markdown list files, which make_playlist.py automatically converts into M3U playlist attributes.
The Free-TV/IPTV project generates M3U playlists from Markdown-based channel lists. EPG integration is handled automatically by the make_playlist.py script, which embeds global EPG URLs in the playlist header and injects tvg-id attributes into individual channel entries based on the sixth column of the source tables.
How EPG Integration Works in Free-TV/IPTV
The repository implements a two-layer EPG integration strategy that separates global source configuration from per-channel identifier assignment.
Global EPG Sources via epglist.txt
The epglist.txt file contains URLs of publicly available EPG XML files. During playlist generation, the main() function in make_playlist.py (lines 31-34) reads this file, joins the URLs with commas, and injects them into the M3U header using the x-tvg-url attribute:
processed_epg_list = ", ".join(epg_urls)
head_playlist = f'#EXTM3U x-tvg-url="{processed_epg_list}"\n'
Channel-Level EPG IDs
Individual channels specify their EPG mappings through the Channel class defined in make_playlist.py. The __init__() method (lines 94-112) parses Markdown table rows and extracts the sixth column (index 5) as the EPG identifier:
if len(parts) > 6:
self.epg = parts[5].strip() # Extract EPG ID from sixth column
else:
self.epg = None
The to_m3u_line() method (lines 115-121) conditionally adds the tvg-id attribute when rendering the EXTINF line:
if self.epg is None:
return f'#EXTINF:-1 tvg-name="{self.name}" tvg-logo="{self.logo}"...'
else:
return f'#EXTINF:-1 tvg-name="{self.name}" tvg-logo="{self.logo}" tvg-id="{self.epg}"...'
Step-by-Step Implementation Guide
Configure Global EPG Sources
Edit epglist.txt in the repository root to add or update EPG XML URLs. Append one URL per line:
https://epgshare01.online/epgshare01/epg_ripper_US1.xml.gz
https://epgshare01.online/epgshare01/epg_ripper_US2.xml.gz
These URLs populate the x-tvg-url header attribute in generated playlists, enabling EPG-aware players like Kodi, Plex, or VLC to retrieve program data.
Assign EPG IDs to Individual Channels
Open the appropriate Markdown file in the lists/ directory (e.g., lists/usa.md). Add the EPG identifier as the sixth column in the pipe-delimited table:
| 12 | News Channel | (http://stream.example.com/news.m3u8) | <img src="logo.png"> | epg_news_01 |
The column order is: channel number, name, stream URL, logo, EPG ID. If the EPG ID is present, the make_playlist.py script extracts it and assigns it to the channel's tvg-id attribute.
Regenerate the Playlists
Execute the playlist generator to apply your changes:
python3 make_playlist.py
The script outputs:
playlist.m3u8– the master playlist containing all channelsplaylists/playlist_*.m3u8– per-country playlists
Each generated file includes the global EPG header and individual tvg-id attributes for channels that have EPG mappings defined.
Code Implementation Details
The complete transformation from Markdown entry to M3U line follows this execution path in make_playlist.py:
class Channel:
def __init__(self, group, md_line, country_code=""):
parts = md_line.split('|')
# ... parsing logic for name, url, logo ...
if len(parts) > 6:
self.epg = parts[5].strip() # EPG ID extraction
else:
self.epg = None
def to_m3u_line(self):
chno = f' tvg-chno="{self.chno}"' if self.chno else ""
country = f' tvg-country="{self.country}"' if self.country else ""
if self.epg is None:
return f'#EXTINF:-1 tvg-name="{self.name}" tvg-logo="{self.logo}"{chno}{country} group-title="{self.group}",{self.name}\n{self.url}'
else:
# Include tvg-id when EPG is defined
return f'#EXTINF:-1 tvg-name="{self.name}" tvg-logo="{self.logo}" tvg-id="{self.epg}"{chno}{country} group-title="{self.group}",{self.name}\n{self.url}'
This produces playlist entries like:
#EXTM3U x-tvg-url="https://epgshare01.online/epgshare01/epg_ripper_US1.xml.gz"
#EXTINF:-1 tvg-name="News Channel" tvg-logo="logo.png" tvg-id="epg_news_01" group-title="USA",News Channel
http://stream.example.com/news.m3u8
Summary
- Global EPG configuration happens in
epglist.txt, whichmake_playlist.pyreads to populate thex-tvg-urlplaylist header. - Per-channel EPG mapping uses the sixth column in Markdown list files, parsed by the
Channelclass as thetvg-idattribute. - Automatic generation occurs when running
python3 make_playlist.py, producing M3U files ready for EPG-compatible players. - The implementation supports multiple EPG sources through comma-separated URLs and selective channel mapping via optional EPG ID columns.
Frequently Asked Questions
What file format does Free-TV/IPTV use for EPG data?
The repository references standard XMLTV format files (typically .xml or .xml.gz) through the epglist.txt configuration. The make_playlist.py script does not parse the EPG content itself; it only embeds the source URLs in the M3U header using the x-tvg-url attribute, leaving XML parsing to the IPTV player.
Where exactly do I add the EPG ID in the channel list?
Add the EPG ID as the sixth column (fifth pipe-delimited field) in the Markdown table files located in lists/. The Channel.__init__() method in make_playlist.py extracts parts[5] (zero-indexed) when parsing each line, assigning it to self.epg only if the column exists and contains data.
Can I use multiple EPG sources simultaneously?
Yes. The make_playlist.py script concatenates all URLs from epglist.txt into a single comma-separated string for the x-tvg-url attribute. This allows players to query multiple EPG repositories to resolve program data for different channel sets or regions.
How do I verify that EPG integration is working correctly?
After running python3 make_playlist.py, inspect the generated playlist.m3u8 file. Verify that the header contains #EXTM3U x-tvg-url="..." with your EPG URLs, and that specific channels include tvg-id="your_epg_id" attributes. Load the playlist in an EPG-aware player like Kodi or VLC to confirm program guide data appears alongside the channels.
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 →