# How to Update Existing Channel Information in the Free-TV IPTV Playlist

> Update Free-TV IPTV playlist channel info effortlessly. Edit the Markdown file, modify channel data, and run the script to regenerate playlist.m3u8.

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

---

**Edit the corresponding Markdown file in the `lists/` directory, modify the pipe-separated table row containing the channel data, and run `python3 make_playlist.py` to regenerate the `playlist.m3u8` file.**

The Free-TV/IPTV repository generates its streaming playlists from human-readable Markdown files rather than manual XML manipulation. To update existing channel information in the IPTV playlist, you modify the source table entries in the `lists/` directory and invoke the Python generator script to rebuild the consolidated output.

## Understanding the Playlist Architecture

The repository uses a **Markdown-to-M3U8** pipeline where channel data lives in country-specific files under `lists/`. The script **[`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py)** parses these files, instantiates `Channel` objects for each valid row, and writes the final `playlist.m3u8` file that IPTV clients consume.

Each channel entry follows a pipe-separated table format. The generator only processes rows containing the `[>]` marker—indicating an active stream—and skips rows marked with `[x]`.

## Locating and Editing Channel Entries

### File Structure

Country-specific channel lists reside 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)). Each file contains a Markdown table where every row represents a single channel.

### Table Format

The columns follow this structure:

| Column | Content | Required |
|--------|---------|----------|
| 1st | Channel number (optional) | No |
| 2nd | **Display name** (used for `tvg-name`) | Yes |
| 3rd | **Link** in format `[>](URL)` | Yes |
| 4th | **Logo** as `<img height="20" src="URL"/>` | Yes |
| 5th | **EPG ID** (used for `tvg-id`) | No |

Example entry from [`lists/usa.md`](https://github.com/Free-TV/IPTV/blob/main/lists/usa.md):

```markdown
| 1 | Buzzr Ⓖ | [>](https://buzzrota-ono.amagi.tv/playlist1080.m3u8) | <img height="20" src="https://upload.wikimedia.org/.../Buzzr_logo.svg"/> | Buzzr.us |

```

## Step-by-Step Update Process

Follow these steps to update existing channel information in the IPTV playlist:

1. **Locate the source file** – Identify the country file in `lists/` containing the channel (e.g., [`lists/usa.md`](https://github.com/Free-TV/IPTV/blob/main/lists/usa.md) for US channels).

2. **Find the channel row** – Search for the channel name in the table. Each row uses pipe characters (`|`) as delimiters.

3. **Modify the fields** – Update the URL inside the `[>](...)` parentheses, change the logo `src` attribute, or adjust the EPG ID in the final column.

4. **Preserve the marker** – Keep `[>]` to include the channel in the playlist. If the stream is broken, change it to `[x]` to exclude it from generation.

5. **Regenerate the playlist** – Run the generator script:

   ```bash
   python3 make_playlist.py
   ```

6. **Verify the output** – Check `playlist.m3u8` or the per-country files under `playlists/` to confirm the changes reflect correctly.

## Practical Update Examples

### Updating a Stream URL

If a channel moves to a new endpoint, edit the URL within the parentheses:

```diff
- | 1 | Buzzr Ⓖ | [>](https://buzzrota-ono.amagi.tv/playlist1080.m3u8) | <img height="20" src="https://upload.wikimedia.org/.../Buzzr_logo.svg"/> | Buzzr.us |
+ | 1 | Buzzr Ⓖ | [>](https://new-buzzr.example.com/playlist.m3u8) | <img height="20" src="https://upload.wikimedia.org/.../Buzzr_logo.svg"/> | Buzzr.us |

```

After saving, run `python3 make_playlist.py` to update the `playlist.m3u8`.

### Marking Channels as Invalid

When a stream goes offline, replace `[>]` with `[x]`:

```diff
- | 2 | Retro TV | [>](https://bcovlive-a.akamaihd.net/...) | <img height="20" src="https://i.imgur.com/PNTYOgg.png" /> | RetroTVEast.us |
+ | 2 | Retro TV | [x]() | <img height="20" src="https://i.imgur.com/PNTYOgg.png" /> | RetroTVEast.us |

```

The script skips `[x]` rows during generation, effectively removing them from the output.

### Adding EPG Identifiers

To add electronic program guide data, append the EPG ID as the sixth column:

```diff
- | 3 | Stadium | [>](https://bcovlive-a.akamaihd.net/...) | <img height="30" src="https://i.imgur.com/6ae9E8d.png"/> |
+ | 3 | Stadium | [>](https://bcovlive-a.akamaihd.net/...) | <img height="30" src="https://i.imgur.com/6ae9E8d.png"/> | StadiumEPG123 |

```

This populates the `tvg-id="StadiumEPG123"` attribute in the generated M3U.

## How the Generator Processes Changes

The **[`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py)** script implements the transformation logic. When you run the generator:

- **Parsing** – The `Channel` class `__init__` method (lines 94-104) splits each Markdown line on `|` characters and extracts fields.
- **URL extraction** – The script strips parentheses from the link column using `self.url = self.url[self.url.find("(")+1:self.url.rfind(")")]`.
- **M3U generation** – The `to_m3u_line()` method (lines 15-20) constructs the `#EXTINF` line with `tvg-name`, `tvg-id`, and `tvg-country` attributes.
- **Country codes** – The `COUNTRY_CODES` dictionary (lines 6-91) maps country names to ISO codes for the `tvg-country` attribute.
- **EPG headers** – The script references [`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt) (lines 31-35) to include EPG URLs in the M3U header.

The final output combines all active channels into `playlist.m3u8` (lines 36-59) while filtering out any entries marked with `[x]`.

## Summary

- **Source files** – Channel data lives in `lists/*.md` as Markdown tables.
- **Update method** – Edit the pipe-separated row in the appropriate country file, preserving the `[>]` marker for active streams.
- **Regeneration** – Run `python3 make_playlist.py` to parse changes and rebuild `playlist.m3u8`.
- **Invalid streams** – Use `[x]` instead of `[>]` to exclude broken channels without deleting data.
- **Implementation** – The `Channel` class in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) handles parsing and M3U line generation via `to_m3u_line()`.

## Frequently Asked Questions

### What happens if I remove the `[>]` marker entirely?

If you remove the `[>]` marker without replacing it with `[x]`, the row will likely fail validation or be skipped. The generator specifically looks for `[>]` to identify active streams. To disable a channel, use `[x]` as shown in the examples above.

### Can I update multiple channels before running the generator?

Yes. You can edit multiple rows across different `lists/*.md` files before running `python3 make_playlist.py`. The script processes all country files in a single execution, so batch updates are efficient and encouraged for maintaining the playlist.

### Do I need to restart IPTV clients after updating the playlist?

Most IPTV clients load the M3U8 file at startup or on a refresh interval. Simply updating `playlist.m3u8` on disk does not automatically push changes to active clients. You must either restart the client application or trigger a playlist refresh in the client's settings to see the updated channel information.

### Where is the EPG data configured in the repository?

The EPG URLs are defined in **[`epglist.txt`](https://github.com/Free-TV/IPTV/blob/main/epglist.txt)**, which the generator reads to populate the `url-tvg` attribute in the M3U header (lines 31-35 of [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py)). Individual channel EPG IDs are set in the fifth column of the Markdown table rows, which the `Channel` class maps to the `tvg-id` attribute in the output.