For most requests HTTP GET is used:
GET ${TVIPAPI_BASE_URL}/tvipapi/json/<command>.json
For some requests HTTP POST is used:
POST ${TVIPAPI_BASE_URL}/tvipapi/json/<command>.json
tvipapi/json subfolder allows implementing API inside of existing web site (not dedicated domain).
Here:
${TVIPAPI_BASE_URL} is HTTP/HTTPS base URL of Middleware server. For example, http://server.com/iptv/.
<command> is an API command.
All responses have general form:
{ "method" : "methodname", "status" : 0, "text" : "Status text", "response" : { } }
Client should first check that method name equals original requested method.
Then client should check status integer value for error code.
If status==0 || status==200 (no error), client can parse response object for the requested data.
If status>0, error text could be provided.
Code | Commands | Description |
---|---|---|
0/200 | All | Request success. No errors |
400 | All | Wrong request syntax. |
404 | All | Method is not supported or data not available (for EPG). |
403 | All, ex serverinfo,auth,register | Authentication required. Client should call auth command to require authentication. |
401 | auth | Registration required. Client should call register with appropriate credential information. |
402 | auth | This device is blocked. Client can periodically call auth, to wait until blocking is over. |
401 | register | Incorrect credentials. User supplied wrong login/password, MAC address or other information. |
403 | register | Can not register this STB. User message is provided. |
500 | All | Other server-side errors |
To simplify “static” server implementations, content requests can response with HTTP error codes, instead of JSON errors.
server_info command should not response with HTTP error codes as it will be treated as protocol error.
HTTP code | Commands |
---|---|
403 | All, except serverinfo,auth,register |
404 | All |
All other API requests should respond HTTP/200, even on error. Error code should be provided in “status” field of JSON responce object!
Header | Description |
---|---|
User-Agent | Standard web client identifier. |
Mac-Address | Unique MAC address of client. |
Accept-Language | Language code of client's user interface (for ex. “en”). |
Device-Type | Client device type (model) name. |
Device-Firmware | Device specific firmware version. |
Device-Os | Device specific Operating system name. |
Udpxy-Address | Address of UDP-proxy if any. |
Device-Use-Nat | If device can detect NAT state, this header has value “yes” or “no”. Otherwise, header is not present. |
Server information request. This request is peformed by client on protocol initializtion.
If a server fails to provide Server Info data, client will not access any server features.
Request:
GET ${TVIPAPI_BASE_URL}/tvipapi/json/server_info.json
Response:
{ "method" : "server_info", "status" : 0, "response" : { "proto_version": 1, "server": "middleware_server", "service_provider":"MegaGiga", "server_time": 1234567946, "remote_addr": "192.168.10.5", "tz_offset": 10800, "auth":true, "channel_list_update_interval":3600, "poll": { "interval": 300, "timeslot": 0.1, }, "cas_configs": [ { "id": 1, "type": "tvipcas", "options" : { "key": "value", } } ] } }
Option | Type | Req. | Description | Def.val |
---|---|---|---|---|
proto_version | Integer | Yes | Protocol version, implemented by the server. Client should check that protocol version is not higher then supported. | |
server | String | No | Identification string of middleware server. | undef. |
service_provider | String | No | Name of Service provider to display to user. | undef. |
server_time | Integer | No | Server's current time. STB could sync with it. | undef. |
remote_addr | String | No | Client's IP address as seen by the server. Used to detect NAT. | undef. |
tz_offset | Integer | No | Server's current time offset from GMT in seconds. | 0 |
auth | Bool | No | Whether “auth.json” call is required before accessing middleware. | false |
cas_configs | Array | No | CAS/DRM protocols, that should be initialized for this middleware with specific options options. | undef. |
channel_list_update_interval | Integer | No | Interval in seconds to check server for channel list (or EPG) updates. If not set, client default value is used. | 86400 |
poll/interval | Integer | No | Interval in seconds to poll server for incoming messages. If not set, message system is disabled. | undef. |
poll/timeslot | Float | No | Timeslot inside poll interval (see messages). | undef. |
If authentication is enabled by server info, client should authenticate on the server. It should provide any tokens/cookies, that it currently has in this request.
Request:
GET ${TVIPAPI_BASE_URL}/tvipapi/json/auth.json
Response:
{ "method" : "auth", "status" : 0, "response" : { "registered" : true, "register_type": "login", "session_type": "token", "token": "AAAAAAAA", "header": "Auth-Data", "param": "session" } }
Server should not response with HTTP 403, even if auth failed.
Server should always have response block with register_type option.
registered reports current register status of client. If true - client device was already registered on the server; false - device can be registered, if register_type is defined.
register_type defines type of user authentication logic, implemented by the server. Possible values are:
mac - server uses only MAC address of the device to authenticate it. No Login/Password is used.
login - user should provide login and password to register the device.
session_type defines which kind of session information server will provide to client in order to keep it's registered session. Each successful auth request should correctly update session information (i.e. provide the same or different token). Possible values are:
mac - no token is used. Client just sends it's MAC address in *Mac-Address* HTTP header.
token - a simple string token is provided in the token field of the response. Client Should use HTTP Header “Auth-Token” in each content request too keep session.
cookie - client will keep cookies provided in the current response and apply them to any content request.
header - client will keep the value of token and provide it as custom HTTP-header header.
param - client will keep the value of token attribute and will provide it as GET param on each content request.
If authentication was failed, STB should call Register command, providing credentials according to the register_type (see auth command). Also, all session data, that client may have, should be provided to the call.
If register type is mac, client can immidiately call register command after failed auth.
If register type is login, client should display a message to user with login and password fields. Then call register method.
{ "login": "login_name", "password": "passssss" }
Request:
GET/POST ${TVIPAPI_BASE_URL}/tvipapi/json/register.json
Response:
{ "method" : "register", "status" : 0, "response" : { "token": "xxxxxxxxxxxxxxxxxx" } }
If registration is OK, no additional data is provided. Client can repeat auth command.
User can try to unregister device. Session information should be provided.
Request:
GET ${TVIPAPI_BASE_URL}/tvipapi/json/unregister.json
Response:
{ "method" : "unregister", "status" : 0, "response" : null }
If unregister is OK (or user is not registered), no additional data is provided. Client can repeat auth command.
Get information about registred user.
Request:
GET ${TVIPAPI_BASE_URL}/tvipapi/json/user_info.json
Response:
{ "method" : "user_info", "status" : 0, "response" : { "fullname":"Ivan Smith", "enabled":true, "contract":"13279 от: 23.06.2014" } }
User structure:
Field: | Type | Req. | Description |
---|---|---|---|
fullname | String | Yes | User fullname. |
enabled | Boolean | Yes | True if subscribrictions are active. |
contract | String | No | Contract information |
The following commands should only be called by client after successfull authentication.
This command loads channel list from the server. Channel list is always loaded full (all channels).
Request:
GET ${TVIPAPI_BASE_URL}/tvipapi/json/channels.json
Response:
{ "method": "channels", "status": 0, "response": { "channels_version" : 1, "channels_hash": "d41d8cd98f00b204e9800998ecf8427e", "epg_version": 1, "channels": [{ "id": 1, "title": "ОРТ", "number": 666, "logo": "http://megaprov.ru/images/logos/ort1.png", "url": "udp://@1.1.1.1:1234", "age_group_id": 1, "tshift_proto":"flussonic", "tshift_depth": 3586954, "tshift_base_url": "http://2.2.2.2:4321", "tshift_cas_config_id": null, "media": { "aspect": "4:3", }, "cas_config_id": null }], "groups": [ { "id": 1, "title": "ProPutina", "items": [1, 2, 3, 4] } ], "age_groups":[ { "id":1, "age":18, "caption":"18+" } ] } }
channels_version defines version or timestamp or current channel list. If this value is the same as on previous request, playlist will be updated on the device.
channels_hash unique hash of available channels, used in short epg
epg_version defines version or timestamp or current EPG data. If this value is the same as on previous request, EPG will be considered the same.
Channel structure:
Field: | Type | Req. | Description |
---|---|---|---|
id | Integer | Yes | Unique id of the channel in the middleware. |
title | String | Yes | Name of the channel to be displayed to the end user. Should be localized. |
number | Integer | Yes | Unique channel number, that is displayed to user and used to switch channels. |
logo | String | No | URL of an image file (PNG), that represents channel logo.If path contains ${h} and ${w} variables client can replace these variables with required height and width in pixels. |
url | String | Yes | URL of the Live stream. |
age_group_id | Int | Yes | Age group ID, may be null |
tshift_proto | String | No | Timeshift server type. Auto detect by default. |
tshift_base_url | String | No | Base URL of timeshifted stream. Syntax depends on timeshift type. |
tshift_depth | Integer | No | Enables server achive/timeshift for the channel and sets number of seconds back from live. |
tshift_cas_config_id | String | No | CAS/DRM config id, that should be used to play timeshifted stream. |
cas_config_id | Integer or null | No | CAS/DRM config id, that should be used to play this stream. |
media | Object | No | Various media options for the stream (aspect, def. audio track, def. subtitle, etc. |
Age group structure:
Field: | Type | Req. | Description |
---|---|---|---|
id | Integer | Yes | Id |
age | Integer | Yes | Age rating |
caption | String | Yes | Age rating caption |
Media structure:
Field: | Type | Req. | Description |
---|---|---|---|
aspect | String | No | Override aspect ratio (allowed values: “4:3”, “16:9”, “16:10”, may be null (no override) |
TODO: Some MWs support dynamic links. So, real URL should be async requested by the Player at the moment that user changes channel.
EPG is supposed to be segmented as one file per one day per channel. Day is supposed to be an inteval from 00:00 to 23:59:59 UTC time (*not* local time). The *start* time of event is used.
GET ${TVIPAPI_BASE_URL}/tvipapi/json/epg/<channel_id>/YYYY-MM-DD.json
Here, channel_id is supposed to be the id of channel from the playlist.
YYYY-MM-DD is the date of the requested day (like 2015-01-25). Day borders (begin-end) are defined by server's timezone specified by tz_offset in server info.
Response:
{ "method" : "epg", "status" : 0, "response" : { "version": 2, "channel_id" : 1, "date" : "2015-01-25", "events" : [ { "start": 1447285765, "end" : 1447256765, "title" : "News", "description:" "Today's news program.", "age_group_id": 1, } ], "age_groups":[ { "id":1, "age":18, "caption":"18+" } ] } }
Event structure:
Field: | Type | Req. | Description |
---|---|---|---|
version | Integer | Yes | Version of EPG. Should be changed each time EPG database is updated on server. |
channel_id | Integer | Yes | Id of the channel for which EPG is provided. |
date | String | Yes | Date of the current EPG block 2015-01-25. Borders (00:00:00 - 23:59:59 should be in UTC timezone). |
start | Integer | Yes | Unix timestamp of program start. It should be within borders of the date. |
end | Integer | Yes | Unix timestamp of the program end. it should be equal or later then start. And no later, then start of the next program. |
title | String | Yes | Title of the programm. |
description | String | No | Description of the program. |
age_group_id | Integer | Yes | Override channel age_group option, must be null if override not needed |
GET ${TVIPAPI_BASE_URL}/tvipapi/json/short_epg/<hash>.json
Here, hash is channel hash.
Filter short EPG by channel:
GET ${TVIPAPI_BASE_URL}/tvipapi/json/short_epg/<channel>/epg.json
Here, channel is supposed to be the id of channel from the playlist.
Response:
{ "method":"short_epg", "status":200, "text":null, "response":{ "version":"70", "channels":[ { "channel_id":3, "events":[ { "start":1463131800, "end":1463134800, "title":"News", "description":"", "age_group_id":1 }, { "start":1463134800, "end":1463138100, "title":"Politics", "description":"", "age_group_id":1 }, { "start":1463138100, "end":1463143500, "title":"Just another soap", "description":"", "age_group_id":null } ] } ], "age_groups":[ { "id":1, "age":18, "caption":"18+" } ] } }
version - EPG version
channels structure
Field: | Type | Req. | Description |
---|---|---|---|
channel_id | Integer | Yes | Channel id |
events | Array | Yes | EPG event objects |
Client polls server periodically according to poll settings for incoming messages.
Each client uses its own timeslot to poll server for messages. Each day (starting from UTC 00:00) is splitted into poll intervals.
ceil( ( current_unixtime - (floor(current_unixtime / 86400) * 86400) - floor(poll_timeslot * poll_interval) ) / poll_interval ) * poll_interval + (floor(current_unixtime / 86400) * 86400) + floor(poll_timeslot * poll_interval)
Request:
GET/POST ${TVIPAPI_BASE_URL}/tvipapi/json/messages.json
GET is for message polling (receiving).
POST is pushing message (sending).\\
POST request example:
{ "messages": [ { "id": 1, "command": "channel_view_stat", "args": { "channel_id": 1, "content_begin": 111111111, "content_end": 22222222, "session_begin": 111110000, "session_end": 222220000 } } ] }
POST server response example:
{ "method" : "messages", "status" : 0, }
GET server response example:
{ "method" : "messages", "status" : 0, "response" : { "poll": { "interval": 300, "timeslot": 0.1, }, "messages": [ { "id" : 1, "command": "command_name", "ttl": 1447285765, "args": { "arg1": "test1", "arg2": "test2" } }, ] } }
Field: | Type | Req. | Description | Default |
---|---|---|---|---|
id | Int64 | Yes | Unique message ID on the server | |
command | String | Yes | Command code name, see table of supported commands below. | |
ttl | Integer | No | Unix timestamp of time, until which this message is valid. If 0, then valid forever. | |
confirm | Boolean | No | True if message needs confirmation over message_confirm command. | |
args | Object | No | Arguments, depending on executed command. | |
poll/interval | Integer | No | Interval in seconds to poll server for incoming messages. If not set, message system is disabled. | undef. |
poll/timeslot | Float | No | Timeslot inside poll interval (see messages). | undef. |
Supported message types:
Message Type | Source | Description |
---|---|---|
user_message | server | Display text messages to user screen, available types: notify, confirm. |
reinit | server | Ask client to refresh server_info. |
refresh_channel_list | server | Telling device to update channel list. |
restart | server | Depending on the platform restarts app or OS. |
open_url | server | Display data from given url to user screen. |
force_update | server | Telling device to update app/firmware. |
send_crash_report | server | Telling device to send crash reports to provider. |
channel_view_stat | client | Send channel view statistics to server. |
channel_quality_stat | client | Send stream view statistics to server. |
Alert type | Description |
---|---|
confirm | Text window with confirm button. Device freezes waiting for user response |
notify | Simple text notification. No user reaction expected. Time of presentation controls with “ttl” argument |
ticker | Ticker string that rolling over the screen |
Field | Type | Req. | Description |
---|---|---|---|
type | Enum | Yes | Available types: confirm, notify, ticker |
title | String | No | Title for confirm type |
text | String | Yes | Message text |
delay | Integer | No | Message exposure time |
Channel view statistics:
Field | Type | Req. | Description |
---|---|---|---|
channel_id | Integer | Yes | Viewed channel id. |
content_begin | Integer | Yes | Timestamp, when content was started. |
content_end | Integer | Yes | Timestamp, when content was ended. |
session_begin | Integer | Yes | Timestamp, when playback session was started. |
session_end | Integer | Yes | Timestamp, when playback session was ended. |