# How to Regenerate the Combined IPTV Playlist After Making Changes

> Quickly regenerate your combined IPTV playlist after editing lists using the simple python3 make_playlist.py command. Keep your playlist current with minimal effort.

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

---

**Run `python3 make_playlist.py` after editing any Markdown file in the `lists/` directory to rebuild the combined `playlist.m3u8` and all per-country playlists.**

The Free-TV/IPTV repository generates its playlist dynamically rather than storing a static file. All channel data lives in human-readable Markdown files, and the [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) script processes these sources to produce the final M3U files. When you modify stream URLs, add channels, or update metadata, you must regenerate the playlist to compile those changes into the consumable format.

## How the Playlist Generator Works

The generation process follows a strict pipeline that parses source Markdown, filters for valid streams, and writes both combined and country-specific outputs.

### Parsing Channel Data from Markdown

The script scans every `.md` file in the **`lists/`** directory (e.g., [`lists/usa.md`](https://github.com/Free-TV/IPTV/blob/main/lists/usa.md), [`lists/uk.md`](https://github.com/Free-TV/IPTV/blob/main/lists/uk.md)). It extracts only table rows where the URL column begins with **`[>]`**, which marks a valid stream URL. The **`Channel`** class—implemented in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) at lines 94-122—handles the conversion of these rows into properly formatted M3U entries, including channel names, logos, and group titles.

### Building the M3U Header

Before processing channel data, the script loads **[`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt)** to construct the XMLTV EPG header. Lines 31-35 of [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) read this file and inject the EPG URLs into the `#EXTM3U` header line, ensuring guide data references are current in the generated output.

### Generating Combined and Per-Country Playlists

For each Markdown source processed, the script writes output to two locations simultaneously:
- **`playlist.m3u8`** – The master playlist aggregating all channels.
- **`playlists/playlist_<country>.m3u8`** – A country-specific playlist file.

The script automatically creates the `playlists/` directory if it does not exist (lines 24-30) and handles file writing at lines 38-45.

## Step-by-Step Regeneration Workflow

Follow this sequence to update the playlist after any edit to the source files.

1. **Edit the source Markdown** in `lists/<country>.md` to add, remove, or modify channels. Ensure valid stream URLs use the `[>]` prefix.

2. **Run the generator script** from the repository root:

   ```bash
   python3 make_playlist.py
   ```

   The script prints "Generating …" for each country and overwrites `playlist.m3u8` with fresh content.

3. **Verify the output** using standard Unix tools to confirm your changes:

   ```bash
   grep -i "BBC World" playlist.m3u8
   ```

   You should see an `#EXTINF` line containing the updated channel entry.

4. **Check per-country files** (optional):

   ```bash
   cat playlists/playlist_usa.m3u8
   ```

## Alternative Execution Methods

For automated environments or CI pipelines, use the shebang directly:

```bash
./make_playlist.py

```

This works because the script includes `#!/usr/bin/python3` at the top. Alternatively, execute explicitly with Python 3 on any platform:

```bash
python3 make_playlist.py && cat playlists/playlist_<country>.m3u8

```

## Key Files in the Generation Process

- **[`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py)** – Core generator script that parses Markdown, instantiates `Channel` objects, and writes M3U files.
- **`lists/*.md`** – Source data for each region; edit these files to change channel information.
- **[`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt)** – Plain-text list of EPG URLs injected into the M3U header.
- **`playlist.m3u8`** – Generated combined master playlist (do not edit manually).
- **`playlists/`** – Directory containing generated per-country playlists (`playlist_<country>.m3u8`).

## Summary

- The playlist is generated dynamically; **`playlist.m3u8`** is not stored permanently in the repository.
- Edit **`lists/<country>.md`** files to modify channel data, using the **`[>]`** marker to indicate valid stream URLs.
- Run **`python3 make_playlist.py`** to rebuild both the combined playlist and all country-specific files.
- The **`Channel`** class (lines 94-122) and **[`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt)** handle the conversion of raw Markdown into valid M3U format with EPG headers.

## Frequently Asked Questions

### Do I need to manually edit the playlist.m3u8 file?

No. Never edit `playlist.m3u8` directly. The file is overwritten every time you run [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py). Instead, modify the Markdown source files in `lists/` and regenerate the playlist to persist your changes.

### What does the [>] marker signify in the Markdown files?

The **`[>]`** string in the URL column marks a row as containing a valid stream URL. The [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) script filters for this marker at lines 94-122; rows without it are ignored during playlist generation, allowing maintainers to keep notes or disabled channels in the files without including them in the output.

### How do I add support for a new country to the playlist?

Create a new Markdown file in the `lists/` directory (e.g., [`lists/newcountry.md`](https://github.com/Free-TV/IPTV/blob/main/lists/newcountry.md)) following the existing table format with `[>]` markers. When you run [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py), the script automatically detects the new file and generates both an entry in the combined `playlist.m3u8` and a new file at `playlists/playlist_newcountry.m3u8`.

### Can I generate only a specific country's playlist without updating the combined file?

The current implementation of [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) always generates both the combined `playlist.m3u8` and all per-country playlists simultaneously (lines 38-45). There is no built-in flag to isolate a single country. However, you can run the full script and then access only the specific file you need from the `playlists/` directory.