# How to Organize IPTV Channels by Source Type (ATSC, DVB-S, Pluto) in Free-TV/IPTV

> Learn to organize IPTV channels by source type like ATSC, DVB-S, or Pluto within the Free-TV/IPTV repository. Discover how the script generates playlists from categorized lists.

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

---

**The Free-TV/IPTV repository organizes channels by source type using HTML `<h2>` headings within Markdown files in the `lists/` directory, where the [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) script filters for rows containing the `[>]` marker to generate M3U playlists regardless of the heading structure.**

Organizing IPTV channels by source type—such as **ATSC**, **DVB-S**, or **Pluto**—ensures clean separation of broadcast origins in the Free-TV/IPTV repository. This open-source project stores channel data as Markdown tables within country-specific files, using simple HTML heading tags to denote source categories. Understanding how the playlist generator interprets these files allows contributors to structure content correctly without breaking the automated build process.

## How Channel Organization Works in Free-TV/IPTV

The repository maintains channel data in the **`lists/`** directory as individual Markdown files (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 represents a country and contains one or more tables listing available streams.

Source type organization relies on **HTML `<h2>` headings** inserted above table sections. Common headings include `<h2>ATSC</h2>`, `<h2>DVB-S</h2>`, and `<h2>Pluto</h2>`. These headings serve as visual separators for human editors; the generator script does not parse them programmatically but treats all valid rows uniformly.

The **[`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py)** script scans every `.md` file in `lists/` and generates M3U playlists by looking for the `[>]` marker in table rows. Only rows containing this marker are converted to playlist entries, while the surrounding HTML headings are ignored during processing.

## Step-by-Step Guide to Organizing Channels by Source Type

### Locate and Open the Country File

Navigate to the `lists/` directory and open the relevant country file. For United States channels, edit [`lists/usa.md`](https://github.com/Free-TV/IPTV/blob/main/lists/usa.md). The file should contain an `<h1>` heading with the country name, followed by sections demarcated by `<h2>` tags.

### Insert Source Type Headings

Add or locate the appropriate `<h2>` heading for your source type. If adding ATSC channels, ensure the section begins with `<h2>ATSC</h2>`. For satellite streams, use `<h2>DVB-S</h2>`, and for Pluto TV streams, use `<h2>Pluto</h2>`. You can create new source type headings arbitrarily; the generator will include any valid rows beneath them.

### Add Channel Rows with the Stream Marker

Insert a Markdown table row under the appropriate heading, ensuring it contains the `[>]` marker in the Link column. This marker is required for the channel to be included in the output.

**Example: Adding an ATSC channel to [`lists/usa.md`](https://github.com/Free-TV/IPTV/blob/main/lists/usa.md)**

```markdown
<h2>ATSC</h2>

| # | Channel          | Link                               | Logo                                 | EPG id |

|---|------------------|------------------------------------|--------------------------------------|--------|
| 1 | Example TV Ⓨ    | [>](https://example.com/stream.m3u8) | <img height="20" src="https://i.imgur.com/xyz.png"/> | ExampleTV.us |

```

**Example: Adding a Pluto TV channel**

```markdown
<h2>Pluto</h2>

| # | Channel          | Link                                                                 | Logo                                 | EPG id |

|---|------------------|----------------------------------------------------------------------|--------------------------------------|--------|
| 1 | Pluto Sports     | [>](https://service-stitcher.pluto.tv/v1/stitch/embed/hls/channel/abcd1234/master.m3u8) | <img height="20" src="https://i.imgur.com/abcd.png"/> | PlutoSports.us |

```

## Understanding the Playlist Generation Logic

The **[`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py)** script handles the conversion from Markdown tables to M3U format. Located in the repository root, it performs the following operations:

1. **Directory Scanning**: Iterates through `lists/` for all `*.md` files using `for filename in sorted(os.listdir(lists_dir)):`.
2. **Group Extraction**: Identifies the country group by detecting the first `<h1>` tag in the file.
3. **Row Filtering**: Skips any line that does not contain `[>]`, effectively ignoring header rows, empty lines, and section headings.
4. **Channel Construction**: For valid rows, it instantiates a `Channel` object: `channel = Channel(group, line, country_code)`.
5. **M3U Output**: Converts the channel to M3U format via `channel.to_m3u_line()` and writes to the master playlist and per-country files in `playlists/`.

Because the script uses `if "[>]" not in line: continue` to filter rows, the `<h2>` source type headings are never processed as data—they exist solely to help contributors maintain logical groupings within the Markdown source.

## Extending Source Types Beyond ATSC, DVB-S, and Pluto

The architecture supports arbitrary source type classifications. If you need to add a new category—such as "Satellite-IP" or "Local-FM"—simply insert a new `<h2>` heading with your desired label:

```markdown
<h2>Satellite-IP</h2>

```

The generator will automatically include any table rows with `[>]` found beneath this heading. This extensibility ensures the repository can adapt to emerging broadcast technologies without requiring modifications to [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py).

## Summary

- **File Location**: Channel data resides in `lists/*.md` as Markdown tables.
- **Source Separation**: Use `<h2>` HTML headings (e.g., `<h2>ATSC</h2>`) to visually separate source types.
- **Inclusion Marker**: Every stream row must contain `[>]` in the Link column to be processed.
- **Generator Behavior**: The [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) script ignores headings and filters exclusively for the `[>]` marker, writing valid entries to `playlists/`.
- **Flexibility**: New source types can be added by creating new `<h2>` sections without changing the build logic.

## Frequently Asked Questions

### What happens if I add a custom source type heading?

The generator will treat it like any other section. Since [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) only checks for the `[>]` marker and ignores HTML tags, channels placed under a custom `<h2>` heading (e.g., `<h2>CustomSource</h2>`) will be included in the playlist automatically. The heading serves purely as an organizational aid for editors.

### Why does the script require the `[>]` marker in table rows?

The `[>]` marker acts as a validation filter. According to the logic in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py), the line `if "[>]" not in line: continue` ensures that only intentional stream entries are processed, skipping header rows, placeholder text, or incomplete entries. This prevents malformed URLs from entering the generated M3U files.

### Can I move channels between source type sections without breaking the build?

Yes. Since the generator does not parse `<h2>` headings when assigning groups, moving a channel row from `<h2>ATSC</h2>` to `<h2>Pluto</h2>` only affects the visual organization of the Markdown file. The channel will still be written to the same country playlist (e.g., `playlist_usa.m3u8`) as long as the row retains the `[>]` marker and remains within the same country file.

### How does the generator handle the country group name?

The script extracts the country name from the first `<h1>` tag encountered in the file (e.g., `<h1>USA</h1>`). This value becomes the `group` parameter passed to the `Channel` class constructor. All valid channels within that file inherit this group identifier, ensuring proper categorization in the output M3U regardless of the `<h2>` source type headings used within the file.