How Country Codes Are Mapped and Applied to Channels in IPTV Playlist Generation

The Free-TV/IPTV repository uses a static dictionary in make_playlist.py to map Markdown filenames to ISO-3166-1 alpha-2 codes, then injects these codes as tvg-country attributes into generated M3U playlists.

When generating IPTV playlists from the Free-TV/IPTV repository, each channel must carry proper geographic metadata to enable client-side filtering and organization. The project achieves this by mapping country-specific Markdown files to standardized ISO codes and embedding them directly into the M3U output. Understanding how country codes are mapped and applied to channels in IPTV playlist generation is essential for contributors adding new regional channels or debugging playlist metadata.

The Country Code Mapping Dictionary

At the core of the mapping system lies a static dictionary named COUNTRY_CODES defined in make_playlist.py (lines 6–91). This structure manually associates lowercase country keys with their official two-letter ISO-3166-1 alpha-2 codes.

The dictionary handles non-obvious mappings where filenames differ from standard ISO abbreviations. For example, the United Kingdom uses the filename key uk, but the dictionary maps this to the official "GB" code:

COUNTRY_CODES = {
    "uk": "GB",
    "spain": "ES",
    "france": "FR",
    # ... additional mappings through line 91

}

This approach ensures that common naming conventions in the lists/ directory align with international standards required by IPTV clients.

Deriving Country Codes from Markdown Filenames

The playlist generation script processes each Markdown file in the lists/ directory, using the filename (minus the .md extension) as the lookup key. In the main() function around lines 44–46, the script extracts the country key and resolves the ISO code:

country_key = filename[:-3]  # Strips '.md' extension (e.g., "uk")

country_code = COUNTRY_CODES.get(country_key, "")  # Returns "GB" or empty string

If a Markdown file exists without a corresponding entry in COUNTRY_CODES, the script defaults to an empty string, resulting in no tvg-country attribute for those channels.

Embedding Codes into Channel Objects

Once the ISO code is resolved, the script propagates it to every channel defined in that country's Markdown file. Around line 55 of make_playlist.py, the Channel constructor receives the country code as a parameter:

channel = Channel(group, line, country_code)

This design ensures that all channels originating from the same source file inherit the same geographic identifier, maintaining consistency across the playlist.

Generating the tvg-country Attribute in M3U Output

The final embedding occurs within the Channel.to_m3u_line() method (lines 15–16), which formats the #EXTINF metadata line. The method conditionally includes the tvg-country attribute only when a valid code exists:

country = f' tvg-country="{self.country_code}"' if self.country_code else ""

This produces output lines following the industry-standard format:


#EXTINF:-1 tvg-name="BBC One" tvg-logo="logo.png" tvg-chno="1" tvg-country="GB" group-title="Uk",BBC One
http://stream.url/...

Practical Example: Generating a UK Playlist

To observe the country code mapping in action, run the playlist generator from the repository root:

python3 make_playlist.py

The script reads lists/uk.md, resolves the "uk" key to "GB" via COUNTRY_CODES, and produces playlists/playlist_uk.m3u8 where every entry contains tvg-country="GB".

You can verify the mapping programmatically:

from make_playlist import Channel

# Simulate a channel line from uk.md

raw_line = "|1|BBC One|http://example.com/stream.m3u8|<img src=\"logo.png\">|BBC"
channel = Channel(group="Uk", md_line=raw_line, country_code="GB")
print(channel.to_m3u_line())

Output:


#EXTINF:-1 tvg-name="BBC One" tvg-logo="logo.png" tvg-chno="1" tvg-country="GB" group-title="Uk",BBC One
http://example.com/stream.m3u8

Summary

  • Static mapping: The COUNTRY_CODES dictionary in make_playlist.py (lines 6–91) maps filename keys like "uk" to ISO codes like "GB".
  • Filename extraction: The script derives country keys by stripping the .md extension from files in the lists/ directory.
  • Object inheritance: Each Channel instance receives the resolved country code during instantiation (line 55).
  • M3U output: The to_m3u_line() method injects the code as a tvg-country attribute in the final playlist.
  • Fallback handling: Missing mappings default to empty strings, omitting the attribute rather than generating invalid codes.

Frequently Asked Questions

What happens if a country code is missing from the COUNTRY_CODES dictionary?

If a Markdown file exists in lists/ without a corresponding entry in the COUNTRY_CODES dictionary, the get() method returns an empty string. The resulting channels will not include the tvg-country attribute in the generated M3U playlist, but the playlist will still generate successfully.

Can I use country codes other than ISO-3166-1 alpha-2?

The current implementation in make_playlist.py specifically uses ISO-3166-1 alpha-2 codes as values in the COUNTRY_CODES dictionary. While you could technically modify the dictionary to include non-standard codes, IPTV clients typically expect standard ISO codes for proper filtering and flag display.

How do I add a new country to the playlist generation?

Create a new Markdown file in lists/ using a lowercase descriptive name (e.g., brazil.md), then add the filename root and corresponding ISO-3166-1 alpha-2 code to the COUNTRY_CODES dictionary in make_playlist.py (e.g., "brazil": "BR"). The generator will automatically process the new file and apply the code to all channels within it.

Where does the tvg-country attribute appear in the M3U format?

The attribute appears within the #EXTINF metadata line before the channel name, formatted as tvg-country="XX" where XX is the ISO code. This occurs in the to_m3u_line() method of the Channel class (lines 15–16 of make_playlist.py), allowing client applications to parse and filter channels by their geographic origin.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →