Playlist and XMLTV¶
Not every subscriber watches in the storefront: some prefer their own player on a computer, a set-top box or a phone. For them Catena serves the same thing as two files — the channel list as M3U and the programme guide as XMLTV.
Both files contain exactly the channels this subscriber may watch, by the access formula. A channel with no stream assigned is left out: there is nothing to play in it.
Addresses¶
| What | Address |
|---|---|
| Channel list | /playback/tv/playlist.m3u8?token=<token> |
| Programme guide | /playback/tv/xmltv.xml?token=<token> |
The addresses are relative to the root of the installation: if the storefront opens at https://tv.example.com/tv/, the playlist is at https://tv.example.com/playback/tv/playlist.m3u8.
Either token works:
- the subscriber's playback token — the one the operator sees on the subscriber's card, field Playback token;
- a device token obtained by signing in to the storefront.
The only difference is revocation: revoking a device kills its link as well, while the playback token lives with the subscriber.
What is inside the playlist¶
A channel line looks like this:
#EXTINF:-1 tvg-id="ch_992YXaVtjYS" tvg-chno="1",News 24
/playback/tv/channels/ch_992YXaVtjYS/play?token=<token>
tvg-idis the channel's id in Catena. The same id identifies the channel in XMLTV, so the player matches the schedule to the channel on its own.tvg-chnois the channel number: the player builds the order the subscriber is used to from it.
The address is written relative to the root of the server, and the player resolves it against the address it downloaded the playlist from.
That address is a link to an issuer, not a ready stream URL. Opening it, the player is redirected to playback with a fresh permit. This is about lifetimes: a downloaded file lives with the subscriber for weeks while a playback permit lives for hours, and a playlist with a permit baked in would stop playing the same evening.
One consequence: the player has to follow redirects. Every common one does.
What is inside the XMLTV¶
The file holds channel declarations and their programmes. The default window is one day back and six forward: the past day is what catch-up needs, and six days ahead is the guide's own limit.
The window can be set explicitly with the from and to parameters — RFC 3339 moments, for example ?from=2026-08-20T00:00:00Z&to=2026-08-22T00:00:00Z.
Programme times are always converted to UTC and written in the XMLTV form YYYYMMDDHHMMSS +0000. A programme whose bounds cannot be parsed is skipped: one broken date makes a player draw the whole file as an empty guide, not just that one row.
The schedule comes from the programme guide. If it is empty, the XMLTV arrives with channel declarations and no programmes — and that is fixed at the source, not in the export.
Limits¶
- The screen limit applies here too. A view from a third-party player occupies a screen exactly like a view in the storefront; at the limit the player is refused (How many screens at once).
- Catch-up is built by the player itself, from the programme bounds in the XMLTV. What is recorded is decided by the stream's archive: beyond it there is nothing to play.
- The file does not refresh itself. A new channel in the subscription means the subscriber downloads the playlist again.
Scenario: give a subscriber a playlist link¶
- Open the subscriber's card and copy the Playback token field.
- Build the address:
https://<installation address>/playback/tv/playlist.m3u8?token=<token>. - Check it in a browser: a text file starting with
#EXTM3Ushould be downloaded. - Build the XMLTV address from the same pair and hand the subscriber both links — a player needs both.
If the file comes back empty (only #EXTM3U), the subscriber has no channel with a stream assigned: look at the Available channels block on their card.
What's next¶
- Storefront — the same thing inside the viewer's app.
- Programme guide — where the schedule in the XMLTV comes from.
- Subscribers — the playback token and the available channels.