EPG for OTT middleware

The programme schedule held in the EPG database is delivered to external systems (set-top boxes, applications and OTT middleware) in two ways: as a complete XMLTV document served by the dedicated EPG server, and as a single-day channel schedule in JSON served by the HTTP API of the node.

XMLTV delivery

XMLTV is distributed by a separate built-in EPG server. It is enabled on the “EPG server” screen (EPG server): “Enable EPG server”, the HTTP port (43973 by default), optionally HTTPS with a certificate (port 43983 by default) and the “Host name”. Enabling and disabling take effect at once, without restarting the service; a disabled server opens neither the HTTP nor the HTTPS port.

Access is granted per account (the “Accounts” tab of the “EPG Settings” screen, EPG Settings): login and password, “Channel set”, “Expiry date”, “Allowed IP” and the “Paused” flag. The contents of the delivery are determined by the channel set:

  • sets are created on the “Channel sets” tab;

  • channels are added to sets in the EPG database (EPG Database); a channel may belong to several sets;

  • one set is assigned to an account — without it the delivery is empty;

  • a set assigned to an account cannot be deleted; deleting a set also deletes its contents.

The document is available at /xmltv (and /xmltv.gz — the compressed file); authorisation is HTTP Digest or via request parameters. Programme times are emitted with the channel time zone; only current and future events are included in the document. If the same channel identifier arrived from different sources, the channel is emitted once and the skip is reported in the log. Since version 2.0.2.418, the channel’s programmes are skipped along with it; previously they ended up in the document under the identifier of the emitted channel, next to its own programmes, and a programme could be repeated.

Full export with mapping data

Since version 2.0.2.418, the EPG server also serves a full XMLTV export for mapping on-air channels to the programme schedule: the path /xmltv-src (and /xmltv-src.gz — the compressed file). Unlike /xmltv, it includes the channels of all sources (or of the selected ones), with the data by which a channel is linked to its source:

  • the channel identifier in the export is <source>:<channel>; it is unique even if the same channel exists in several sources;

  • each channel carries the source number and name (src-id, src-name), the channel’s own identifier in the feed (channel-id, the mapping key), the additional identifier (channel-id2) if one is set, the time zone (time-zone) and the end time of the last programme (last-stop);

  • all the channel’s names and icons; a channel is emitted even if it has no programmes, and a channel without a name gets a name equal to its identifier;

  • programme times are in UTC (+0000): the channel time zone is not applied and is passed as an attribute; each programme carries all its titles, descriptions, genres and age ratings. Since version 2.0.2.419, the programme sub-title (for example, the episode name) is emitted as a separate <sub-title> element, and <title> comes without it; which sub-title is split out is described below, in Single-day schedule in JSON.

Request parameters:

  • src — all (default) or comma-separated source numbers; 0 is the built-in “stream-import” source. Disabled sources and unknown numbers are skipped;

  • programmes — 1 (default) returns channels and programmes, 0 only the channel catalogue;

  • days-back — 0 (default) returns current and future programmes, like /xmltv; N starts from midnight UTC N days back, but no further back than the history retention period (“Keep history, days”, Source configuration).

An invalid parameter value is rejected with code 400. Access is by EPG server accounts, as for /xmltv: an account with the all-channels flag (in the settings file or via the API; since version 2.0.2.419, the “All channels on /xmltv-src” switch, EPG Settings) gets all channels of the selected sources, the others only the channels of their set. A request from the node itself (from a local address) gets all channels without an account — on this path only.

The export is built on the server and cached until the data of its sources or the settings change, but for no longer than 5 minutes. A repeated request for the same content with the If-None-Match header gets a 304 response. A large export with past days takes minutes to build; only one export with programmes is built at a time, the others wait. If the export cannot be built right now (the service is stopping, a source is being deleted, the queue is busy), the server responds with 503 and the Retry-After: 30 header. The /xmltv format does not change.

Single-day schedule in JSON

For middleware interfaces the node returns the schedule of a channel for one day in JSON with a single HTTP API request (authorisation is the same as for the other API requests):

GET /data/epg/channel?src=<source>&ch=<channel>&lang=<language>&t=<time>

The response is the list of events of the day (in UTC) that contains the time t: start, end, title and description of each programme in the requested language; if no translation exists, the default language is used, then any available one. Since version 2.0.2.418, a programme with an age rating carries it too, as the rating object: age (the age in years, 16 for a 16+ rating, 0 for 0+) and system (the rating system from the XMLTV feed or the DVB country code, if known). The rating is taken from the <rating> element of the XMLTV feed or from the DVB EIT parental rating; if a programme has several, the highest age is returned. A programme without a rating has no such object.

Since version 2.0.2.419, the programme sub-title (the <sub-title> element of the XMLTV feed, for example the episode name) is returned as a separate sub field in the language of the title, and title no longer includes the sub-title. Up to and including version 2.0.2.418, the sub-title was appended to the title: News. Episode 1. A programme without a sub-title has no sub field.

Only a sub-title in the language of the title or with no language given is returned separately. A sub-title in another language (for example, an English one under a Russian title) is still appended to the title and has no separate field. If a programme has two sub-titles — one in the title’s language followed by a foreign one — the separate field holds both, joined by a full stop: A. B.

The regular /xmltv delivery, the output EIT and the web interface still show the title together with the sub-title. After the node is updated, the EPG database is extended in place and no data is lost; sub-titles appear after the next update of each source.

An empty day is a valid empty list. Responses are cached by the server and refreshed automatically when new EPG data arrives.

The built-in cache is designed for approximately one thousand concurrent clients; for larger installations both the XMLTV and the JSON delivery should be fronted by a caching reverse proxy or a CDN.

Playback of the DVR archive by a programme-schedule event (the epg parameter in the playback URL) is described in Archive playback (VOD).