Live TVP channels as ready-to-use M3U playlists. Two ways to consume them — pick one as your primary:
| Source | URL base | Refresh | Best for |
|---|---|---|---|
| Cloudflare Worker (recommended) | https://tvpi.travny.workers.dev |
request-time, self-healing | never serves a stale token |
| Raw GitHub file (backup mirror) | https://raw.githubusercontent.com/travino/tvpi/main/streams/ |
every 15 min via Actions | offline/no-Worker fallback |
Why two? TVP signs each HLS URL with a short (~15–30 min) token. The Worker resolves URLs when your player asks, so it can't hand out an expired one. The raw git file is a static snapshot refreshed on a timer — simpler, but a token can expire before the next refresh lands, which shows up as a channel that works then drops then recovers. Use the Worker if you can.
| Worker (recommended) | Raw mirror | |
|---|---|---|
| All channels | playlist.m3u |
playlist.m3u |
The Status badge pings the Worker endpoint live, so it reflects whether the service is currently responding for that channel.
The Worker links are .m3u8 endpoints: a 302 redirect to the freshly
tokenized HLS manifest. They are stable, saveable URLs — put them straight
into your own playlist and every play resolves a fresh token. (Plain .m3u
per-channel playlists still exist at the same paths for players that prefer
a nested playlist.)
| Logo | Channel | Worker | Raw mirror | Status |
|---|---|---|---|---|
| TVP 1 HD | m3u8 | m3u | ||
| TVP 2 HD | m3u8 | m3u | ||
| TVP Info | m3u8 | m3u | ||
| TVP Sport | m3u8 | m3u | ||
| TVP Dokument | m3u8 | m3u | ||
| TVP Nauka | m3u8 | m3u | ||
| TVP Rozrywka | m3u8 | m3u | ||
| TVP Historia | m3u8 | m3u |
Tip: the jsDelivr CDN mirror can be more reliable than raw.githubusercontent.com:
https://cdn.jsdelivr.net/gh/travino/tvpi@main/streams/playlist.m3uNote jsDelivr caches aggressively, which works against short-lived tokens — prefer the raw URL or the Worker if you see stale streams.
The raw-file path:
- GitHub Actions runs
generate.pyevery 15 minutes (cron schedule). - The script calls the TVP API for fresh signed HLS token URLs.
- On any transient failure it reuses that channel's last-known-good URL rather
than overwriting it with a placeholder, then writes/commits
streams/*.m3u. - Your player fetches the raw file.
GitHub Actions (every 15 min)
│
▼
vod.tvp.pl API ──► signed HLS token URL (TTL ~15–30 min)
│
▼
streams/*.m3u committed to repo
│
▼
raw.githubusercontent.com/…/streams/playlist.m3u
│
▼
Your IPTV player 🎬
The Worker path skips the commit entirely: it resolves the URL when your player requests it (cache → live fallback), caching each result for under TVP's token lifetime so it's always fresh.
- Fork or push this repo to your GitHub account.
- Actions run automatically — no secrets or extra config needed.
- After the first run (up to 15 min), grab a raw URL and add it to your player,
or deploy the Worker (
worker/, viawrangler deploy) and use the Worker URL.
- VLC
- MPC-HC (use the
.m3u8redirect URLs) - Kodi (PVR IPTV Simple Client)
- TiviMate
- Televizo
- GSE Smart IPTV
- Logos in the table are channel-site favicons fetched at render time; the Status badges ping the Worker live via shields.io and may take a moment to refresh due to badge caching.
- TVP token TTL is ~15–30 min; the 15-min refresh keeps the raw files mostly valid, but GitHub may delay scheduled runs under load — the Worker is the only path that's fully immune to token expiry.
- If
generate.pycan't get a fresh URL and has no cached one for a channel, it writes a placeholder stub so the rest of the playlist still builds.