# What Is the group-title Attribute in M3U8 for Channel Categorization?

> Learn how the M3U8 group-title attribute categorizes IPTV channels for better organization. Improve your channel navigation with this essential guide.

- Repository: [Free TV/IPTV](https://github.com/Free-TV/IPTV)
- Tags: deep-dive
- Published: 2026-06-17

---

**The `group-title` attribute in M3U8 playlists is a metadata tag within `#EXTINF` lines that instructs IPTV players to organize channels into navigable categories like "Portugal" or "Poland".**

In the **Free-TV/IPTV** repository, this attribute powers the automatic categorization of thousands of channels. The `group-title` attribute appears inside the `#EXTINF` directive of each channel entry, allowing compliant players to render hierarchical tree views that make large playlists manageable.

## How group-title Works in M3U8 Playlists

### The #EXTINF Line Structure

Every channel entry in an M3U8 file begins with an `#EXTINF` line that contains metadata attributes before the channel name. The `group-title` attribute assigns a categorical label that groups related channels under a common heading in the user interface.

### Player Behavior

When an IPTV player parses the playlist, it reads the `group-title` value to create a collapsible tree view. For example, channels tagged with `group-title="Portugal"` appear under a "Portugal" folder, while those with `group-title="Poland"` populate a separate branch.

## How Free-TV/IPTV Generates group-title Automatically

### Source Extraction from Markdown

The repository derives `group-title` values from the Markdown files in the `lists/` directory. According to the [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) source code, the script extracts the text between `<h1>` tags from each Markdown file to determine the group name. If no header is present, it falls back to the filename formatted as a title.

### The Channel.to_m3u_line Method

Inside [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py), the `Channel.to_m3u_line` method constructs the final M3U8 output. It inserts the `group` property into the formatted string via `group-title="{self.group}"`.

```python

# make_playlist.py – Channel.to_m3u_line method

def to_m3u_line(self):
    country = f' tvg-country="{self.country_code}"' if self.country_code else ""
    chno = f' tvg-chno="{self.chno}"' if self.chno else ""
    return (f'#EXTINF:-1 tvg-name="{self.name}" tvg-logo="{self.logo}"'
            f'{chno}{country} group-title="{self.group}",{self.name}\n{self.url}')

```

### Header Parsing Logic

The script uses regex to strip HTML tags from the `<h1>` element:

```python

# make_playlist.py – extracting group from Markdown

if "<h1>" in line.lower() and "</h1>" in line.lower():
    group = re.sub('<[^<>]+>', '', line.strip())

# fallback from filename

group = country_key.replace("_", " ").title()

```

## Practical Examples

### Raw M3U8 Syntax

A complete `#EXTINF` line in the generated playlist looks like this:

```text
#EXTINF:-1 tvg-name="RTP1" tvg-logo="https://upload.wikimedia.org/…/RTP1_-_Logo_2016.svg.png" tvg-id="RTP1.pt" tvg-chno="1" tvg-country="PT" group-title="Portugal",RTP1
https://streaming-live.rtp.pt/liverepeater/smil:rtp1HD.smil/playlist.m3u8

```

### Adding a Custom Category

To create a new group, add a Markdown file in `lists/` with a descriptive header:

```markdown
<h1>My Custom Category</h1>

| 1 | My Channel | ([>](https://example.com/stream.m3u8)) | <img src="logo.png" /> |

```

Running [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) automatically assigns `group-title="My Custom Category"` to every channel in that file.

## Summary

- The `group-title` attribute appears in `#EXTINF` lines and defines the category folder displayed in IPTV players.
- In the Free-TV/IPTV repository, [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) automatically generates this attribute from `<h1>` headers in Markdown files located in `lists/`.
- The `Channel.to_m3u_line` method formats the final string as `group-title="{self.group}"` alongside other metadata like `tvg-name` and `tvg-country`.
- Players use this attribute to render hierarchical navigation trees, making large channel lists browsable by country or category.

## Frequently Asked Questions

### What format does the group-title attribute use in M3U8?

The attribute follows the syntax `group-title="Category Name"` and appears inside the `#EXTINF` directive before the comma that separates metadata from the channel name. It accepts any string value, though the Free-TV/IPTV project uses country names or descriptive titles derived from Markdown headers.

### How does Free-TV/IPTV determine the value of group-title?

The repository extracts the text between `<h1>` tags in Markdown files stored in the `lists/` directory. If no header exists, it converts the filename to title case. This value is passed to the `Channel` class and injected into the M3U8 output via the `to_m3u_line` method in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py).

### Can I manually edit group-title in the generated playlists?

While you can manually edit the `playlists/*.m3u8` files, changes will be overwritten when [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) runs. To make permanent changes, modify the source Markdown files in `lists/` or update the parsing logic in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) to handle custom grouping rules.

### Which IPTV players support the group-title attribute?

Most modern IPTV applications including VLC, Kodi, TiviMate, and IPTV Smarters recognize the `group-title` attribute. These players parse the M3U8 file and automatically organize channels into folders based on the attribute's value, creating a hierarchical navigation structure.