# How the Free-TV IPTV Playlist Generator Handles EPG Integration with External Providers

> Learn how the Free-TV IPTV playlist generator integrates external EPG providers by reading URLs and embedding them into M3U playlists for seamless TV guide functionality.

- Repository: [Free TV/IPTV](https://github.com/Free-TV/IPTV)
- Tags: how-to-guide
- Published: 2026-06-16

---

**The Free-TV/IPTV playlist generator integrates external EPG providers by reading URLs from [`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt), concatenating them into a comma-separated string, and embedding them in the `x-tvg-url` attribute of every generated M3U playlist header, while optionally mapping individual channels to specific EPG IDs via the sixth column in source Markdown files.**

The Free-TV/IPTV repository automates the creation of standards-compliant M3U playlists from Markdown source files, with robust support for Electronic Program Guide (EPG) data from external providers. By leveraging the `x-tvg-url` extension and per-channel `tvg-id` attributes, this IPTV playlist generator EPG integration ensures that compatible players like Kodi, VLC, and Plex can automatically retrieve and display program scheduling information. Understanding the exact mechanism—from configuration files to generated output—allows operators to maintain accurate television guides across their streaming infrastructure.

## Loading External EPG URLs from epglist.txt

In [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py), the script initiates EPG integration by reading the [`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt) file located in the repository root. Lines 31-34 load each URL, strip whitespace, and concatenate them into a single comma-separated string:

```python
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()]
processed_epg_list = ", ".join(epg_urls)

```

Each line in [`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt) must contain a full URL to a gzipped XML EPG file (typically `.xml.gz`). The `processed_epg_list` variable becomes the value for the `x-tvg-url` attribute in every generated playlist.

## Embedding EPG Data in M3U Headers

The generator injects the processed EPG list into the `#EXTM3U` header that precedes every playlist file. Lines 36-38 of [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) construct the header string:

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

```

This header is written to both the global `playlist.m3u8` and all country-specific playlists (e.g., `playlists/playlist_uk.m3u8`) at lines 49-50. IPTV clients that support the `x-tvg-url` extension automatically fetch and parse the referenced EPG feeds, eliminating the need for manual guide configuration in the player.

## Mapping Per-Channel EPG IDs

Beyond global EPG feeds, the system supports granular channel-to-guide mapping through the `Channel` class. When parsing Markdown source files from the `lists/` directory, the script expects an optional sixth column containing the EPG identifier:

```markdown
| 1 | BBC World Service | [>](http://stream.example.com/bbc) | <img src="logo.png"> | BBCWorldService.uk |

```

In `Channel.__init__` (lines 109-112), the code extracts this value:

```python
if len(parts) > 6:
    self.epg = parts[5].strip()
else:
    self.epg = None

```

The `Channel.to_m3u_line` method (lines 117-122) then renders this as the `tvg-id` attribute in the `#EXTINF` directive. For example:

```text
#EXTINF:-1 tvg-name="BBC World Service" tvg-logo="https://example.com/bbc.png" tvg-id="BBCWorldService.uk" tvg-chno="1" tvg-country="GB" group-title="UK",BBC World Service
http://stream.example.com/bbc_world

```

This `tvg-id` enables precise matching between streams and program guide entries from the external EPG sources listed in the header.

## Configuring EPG Sources

To modify external EPG providers, edit [`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt) and regenerate the playlists:

```bash

# Append a new provider to the EPG list

echo "https://epgshare01.online/epgshare01/epg_ripper_AL1.xml.gz" >> epglist.txt

# Regenerate all playlists with updated headers

python3 make_playlist.py

```

The script applies the same global EPG list to all generated playlists, regardless of country. This design simplifies the architecture while ensuring consistent data availability across the entire service.

## Summary

- **External EPG loading**: The script reads [`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt) and concatenates URLs into a comma-separated list at lines 31-34 of [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py).
- **Header injection**: Every generated playlist includes the `#EXTM3U x-tvg-url="..."` header, written at lines 36-38 and 49-50.
- **Channel-specific mapping**: Optional sixth columns in Markdown source files populate the `tvg-id` attribute via the `Channel` class (lines 109-122).
- **Standards compliance**: The `x-tvg-url` attribute follows IPTV-M3U extensions supported by major players including Kodi, VLC, and Plex.

## Frequently Asked Questions

### How do I add a new EPG provider to the Free-TV/IPTV generator?

Append the full URL of the gzipped XML EPG file to [`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt) in the repository root, then run `python3 make_playlist.py`. The script automatically includes the new URL in the `x-tvg-url` header of all generated playlists. Ensure the URL points to a valid `.xml.gz` file containing XMLTV-formatted program data.

### What file format should EPG URLs point to?

According to the source code implementation in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py), EPG URLs should reference gzipped XML files (typically `.xml.gz` extensions). The script passes these URLs directly to the playlist header without validation or decompression, so the endpoints must return valid compressed XMLTV data that IPTV clients can parse.

### How does the generator handle EPG IDs for individual channels?

When parsing Markdown files in the `lists/` directory, the `Channel` class constructor checks for a sixth column (index 5) in the pipe-delimited table format. If present, this value becomes the `tvg-id` attribute in the `#EXTINF` line, allowing IPTV clients to match specific channels against program guide entries from the external EPG feeds listed in the header.

### Why does the generator use x-tvg-url instead of embedding EPG data directly?

The `x-tvg-url` approach maintains separation between playlist metadata and program schedule data. By referencing external gzipped XML files rather than embedding television listings, the M3U playlists remain lightweight text files while clients fetch and cache EPG data independently according to their own update policies and bandwidth constraints.