IPTV Playlist Aggregator is a .NET console application that downloads playlists from multiple providers and merges them into a single curated M3U file.
It is designed for users who want one stable playlist, with their own channel metadata and grouping rules, even when source playlists are noisy or inconsistent.
- Downloads M3U playlists from multiple providers.
- Matches provider channels against your channel definitions (including aliases).
- Keeps one playable stream per configured channel.
- Writes a final unified M3U playlist to a configurable path.
- Optionally includes unmatched channels under an unknown grouping.
- Supports provider/date-based playlist URLs.
- Caches downloaded and parsed data to reduce repeated work.
- Load groups, channel definitions, and providers from XML files.
- Fetch enabled providers and parse their playlists.
- Remove duplicate stream URLs.
- Match each configured channel against provider channel names (and optional country context).
- Keep the first playable media source for each matched channel.
- Optionally append unmatched playable channels.
- Generate a single output M3U file.
IptvPlaylistAggregator/: main appIptvPlaylistAggregator/Data/: sample data files (channels.xml,groups.xml,providers.xml)IptvPlaylistAggregator/Service/: aggregation, matching, fetch, and M3U build logicIptvPlaylistAggregator.UnitTests/: unit tests
- .NET SDK 10.0+
- Internet access (required at runtime to fetch source playlists)
From the repository root:
dotnet restore
dotnet build IptvPlaylistAggregator.sln
dotnet run --project IptvPlaylistAggregator/IptvPlaylistAggregator.csprojBy default, the output playlist is written to result.m3u (configured in appsettings.json).
dotnet publish IptvPlaylistAggregator/IptvPlaylistAggregator.csproj -c Releasedotnet publish IptvPlaylistAggregator/IptvPlaylistAggregator.csproj -c Release -r <RID>Example RIDs: linux-x64, linux-arm64, win-x64.
Runtime settings are loaded from IptvPlaylistAggregator/appsettings.json.
outputPlaylistPath: where the merged M3U file is writtendaysToCheck: number of days to look back for dated provider URLscanIncludeUnmatchedChannels: include channels not matched to your definitionsareTvGuideTagsEnabled: include TV guide tags in#EXTINFarePlaylistDetailsTagsEnabled: include source playlist metadata tags
cacheDirectoryPath: cache folder pathhostCacheTimeout: cache timeout for host checksstreamAliveStatusCacheTimeout: timeout for alive stream status cachestreamDeadStatusCacheTimeout: timeout for dead stream status cachestreamUnauthorisedStatusCacheTimeout: timeout for unauthorized stream status cachestreamNotFoundStatusCacheTimeout: timeout for not-found stream status cache
channelStorePath: XML path for channel definitionsgroupStorePath: XML path for groupsplaylistProviderStorePath: XML path for providers
All data stores are XML arrays of entities.
Entity: ChannelDefinitionEntity
Id(string): channel identifier, also used as TVG ID in outputIsEnabled(bool): include/exclude channelName(string): final display nameCountry(string, optional): country metadata and matching hintGroupId(string): group referenceLogoUrl(string, optional): logo URLAliases(string list): accepted source name variants for matching
Entity: GroupEntity
Id(string): group identifierIsEnabled(bool): include/exclude groupName(string): display namePriority(int): sort order (lower appears first)
Entity: PlaylistProviderEntity
Id(string): provider identifierIsEnabled(bool): enable/disable providerPriority(int): provider processing order (lower is earlier)AllowCaching(bool): enable playlist caching for this providerName(string): provider display nameUrlFormat(string): provider URL, optionally with date placeholderCountry(string, optional): provider country hintChannelNameOverride(string, optional): force all channels from provider to this name
Date placeholder example in UrlFormat:
https://example.com/playlists/{0:yyyy-MM-dd}.m3u
The app is a console executable, so it can be scheduled with a systemd timer.
Create /etc/systemd/system/iptv-playlist-aggregator.service:
[Unit]
Description=IPTV Playlist Aggregator
[Service]
WorkingDirectory=/absolute/path/to/IptvPlaylistAggregator
ExecStart=/absolute/path/to/IptvPlaylistAggregator/IptvPlaylistAggregator
User=your-userCreate /etc/systemd/system/iptv-playlist-aggregator.timer:
[Unit]
Description=Periodically aggregate IPTV playlists
[Timer]
OnBootSec=5min
OnUnitActiveSec=50min
[Install]
WantedBy=timers.targetEnable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now iptv-playlist-aggregator.timerRun tests:
dotnet test IptvPlaylistAggregator.UnitTests/IptvPlaylistAggregator.UnitTests.csprojThe project currently targets .NET 10.0.
Contributions are welcome. Please keep changes cross-platform and consistent with existing C# coding style.
This software aggregates playlist sources. You are responsible for ensuring your usage complies with local laws and content licensing requirements.
This project is licensed under the GNU General Public License v3.0 or later. See LICENSE for details.