Skip to content

Player session API

In order to benefit from features such as viewing history, stream count, stream kicking and analytics, the client is required to periodically post player events.

📘 See Reference: Post player events for more details on how to post player events.

As you can see above, the play response returns a player event template to complete and to send to the player session service.

{
"playerEventRequest": {
"body": {
"client": {
"buildName": "${client_build_name}",
"buildVersion": "${client_build_version}",
"countryCode": "NO",
"deviceId": "1c09edd4-4f29-4777-812b-9ba795c0de28",
"deviceOS": "n/a",
"deviceType": "other",
"drm": "${client_drm}",
"envPlatform": "${client_env_platform}",
"envVersion": "${client_env_version}",
"pageUrl": "${client_page_url}",
"platform": "web",
"playerEvent": "${player_event}",
"playerState": "${player_state}",
"streamUrl": "${client_stream_url}",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36",
"videoFormat": "${video_mime_type}",
"videoProtocol": "${video_protocol}",
"viewingSession": "${viewing_session}"
},
"progress": {
"eventNumber": 1,
"assetId": "54321",
"categoryId": "98760",
"title": "San Jupinero final stop",
"assetType": "tvshow",
"playbackType": "vod",
"vod": {
"duration": 147.877,
"position": "${vod_stream_position}"
}
},
"eventName": "encrypted_player_log_event",
"originator": "${originator}",
"originatorId": "894c0efa-80b4-4f31-a7d9-6532b463babe",
"subProfileId": "709d0c6eea56d5f8a2cf3947964138f93c8b8960",
"versions": ["1.0"],
"tenant": "vimond",
"clientDate": "2015-04-07T11:33:37.383Z",
"logData": "8r394jf834hg743h394j3k9rr3j=",
"timestamp": "${client_date}"
},
"eventInterval": "10.0",
"uri": "https://{tenant}.player-session.{domain}/external/player-events/{uuid}"
},
}

Note that in the case of a live asset, the template will be slightly different.

"playerEventRequest": {
"body": {
"client": {
"buildName": "${client_build_name}",
"buildVersion": "${client_build_version}",
"countryCode": "NO",
"deviceId": "1c09edd4-4f29-4777-812b-9ba795c0de28",
"deviceOS": "n/a",
"deviceType": "other",
"drm": "${client_drm}",
"envPlatform": "${client_env_platform}",
"envVersion": "${client_env_version}",
"pageUrl": "${client_page_url}",
"platform": "web",
"playerEvent": "${player_event}",
"playerState": "${player_state}",
"streamUrl": "${client_stream_url}",
"videoFormat": "${video_mime_type}",
"videoProtocol": "${video_protocol}",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36",
"viewingSession": "${viewing_session}"
},
"progress": {
"eventNumber": 1,
"assetId": "54321",
"categoryId": "98760",
"title": "San Jupinero final stop",
"assetType": "tvshow",
"playbackType": "live",
"live": {
"onLiveEdge": "${is_on_live_edge}",
"liveResumePossible": "${live_resume_possible}",
"position": "${live_stream_position}",
"relativePosition": "${live_relative_position}",
"transmissionStartTime": "2018-08-10T14:18:31.000Z"
}
},
"eventName": "encrypted_player_log_event",
"originator": "${originator}",
"originatorId": "894c0efa-80b4-4f31-a7d9-6532b463babe",
"subProfileId": "709d0c6eea56d5f8a2cf3947964138f93c8b8960",
"versions": ["1.0"],
"tenant": "vimond",
"clientDate": "2015-04-07T11:33:37.383Z",
"logData": "8r394jf834hg743h394j3k9rr3j=",
"timestamp": "${client_date}"
},
"eventInterval": "10.0",
"uri": "https://{tenant}.player-session-service.{domain}/external/player-events/{uuid}"
}

This request template contains three main items of information:

  • uri : The Uri location to post the event. Note that uri is different for every new play call since the last part ({uuid}) is randomly generated at every new request
  • interval : The interval between two events in seconds
  • body : A template body for the request

The play service tries to complete as much as it can of the template, but to work properly the client has to fill the rest of the body template and replace (if possible) the values between curly brackets.

[block:parameters] { “data”: { “h-0”: “Template”, “h-1”: “Path”, “h-2”: “Description”, “0-0”: ”${client_date} \n \n\Required”, “0-1”: “body.timestamp”, “0-2”: “Client date when the play event is sent \n \nExample: \n2015-04-07T11:33:37.383Z”, “1-0”: ”${originator} \n \n_Optional_ ”, “1-1”: “body.originator”, “1-2”: “Originator, this is the name/type of the client or player making the request. \n \nExample: \nplayer-android”, “2-0”: ”${client_build_name} \n \n\Optional”, “2-1”: “body.client.buildName”, “2-2”: “Player’s build name \n \nExample: \nVimond.Player.TV2Sumo”, “3-0”: ”${client_build_version} \n \n\Optional”, “3-1”: “body.client.buildVersion”, “3-2”: “Player’s version \n \nExample: \n1.0.125.3316”, “4-0”: ”${device_id} \n \n\Optional”, “4-1”: “body.client.deviceId”, “4-2”: “End-user’s device id \n \nExample: \n6f3293e9-77c0-42c6-850c-dee25b6ac581”, “5-0”: ”${client_drm} \n \n\Optional”, “5-1”: “body.client.drm”, “5-2”: “Data right management type \n \nExample: \nplayready”, “6-0”: ”${client_env_platform} \n \n\Optional”, “6-1”: “body.client.envPlatform”, “6-2”: “Example: \nsilverlight”, “7-0”: ”${client_env_version} \n \n\Optional”, “7-1”: “body.client.envVersion”, “7-2”: “Example: \n5.1.30514.0”, “8-0”: ”${client_page_url} \n \n\Optional”, “8-1”: “body.client.pageUrl”, “8-2”: “Page url on which the client played this asset \n \nExample: \nhttps://sushi.tvto.no/programmer/serier/frikjent/frikjent-1-episode-7-507317.html”, “9-0”: ”${player_event} \n \n\Optional ”, “9-1”: “body.client.playerEvent”, “9-2”: “This indicates the event during a playback/streaming session. \nThe following are the established values/labels for this field, but custom values can be introduced if needed: \n”period” (periodic update), “str-start” (start of the session), “str-failover” (start of a fallback stream in the same session), “end” (the playback session has ended), and “error” (the playback session has been interrupted by an error). \n \nNote that str-start, end do not necessarily correspond directly with the stream position (start of stream, end of stream). \n \nExample \nstr-start”, “10-0”: ”${player_state} \n \n\Optional”, “10-1”: “body.client.playerState”, “10-2”: “The established values for this field are “playing”, and “pause” \n \nExample: \nplaying”, “11-0”: ”${client_stream_url} \n \n\Optional”, “11-1”: “body.client.streamUrl”, “11-2”: “Stream url played by the client \n \nExample: \nhttp://tvto-stream-od.online.no/coraid_ism_2/2017-04-01/D01234(5678_R221ISMH).ism/Manifest”, “12-0”: ”${video_mime_type} \n \n\Optional”, “12-1”: “body.client.videoFormat”, “12-2”: “Mime type of the stream played by the client \n \nExample: \napplication/x-mpegurl”, “13-0”: ”${video_protocol} \n \n\Optional”, “13-1”: “body.client.videoProtocol”, “13-2”: “Network protocol to CDN \n \nExample: \nhttps”, “14-0”: ”${viewing_session} \n \n\Required”, “14-1”: “body.client.viewingSession”, “14-2”: “End-user’s viewing session, which is used to uniquely identify ongoing sessions for the user \n \nExample: \n6f3293e9-77c0-42c6-850c-dee25b6ac581”, “15-0”: ”${vod_stream_position} \n \n\Required (if VOD playback)”, “15-1”: “body.progress.vod.position”, “15-2”: “Position of the player in the stream (in seconds). Note that value can not have more than 5 decimals. \n \nExample: \n45.987”, “16-0”: ”${live_stream_position}”, “16-1”: “body.progress.live.position”, “16-2”: “Position of the player in the live stream (UTC time) \n \nExample: \n2018-02-06T19:41:00.000Z”, “17-0”: ”${live_relative_position}”, “17-1”: “body.progress.live.relativePosition”, “17-2”: “Relative position of the player in the live stream in period. \nExample: \nPT124S”, “18-0”: ”${is_on_live_edge} \n \n\Required (if live playback)”, “18-1”: “body.progress.live \n.isOnLiveEdge”, “18-2”: “True if the user is on the live edge \n \nExample: \ntrue”, “19-0”: ”${live_resume_possible} \n \n\Optional”, “19-1”: “body.progress.live.liveResumePossible”, “19-2”: “Optional field that defaults to false and is not implemented yet. \n \nExample: \nfalse” }, “cols”: 3, “rows”: 20, “align”: [ “left”, “left”, “left” ] } [/block]

When sending events for a live stream, the player position can be expressed in two ways by using two different field: as an ISO8601 timestamp by setting the field body.progress.live.position or as a relative position in period by setting the field body.progress.live.relativePosition

🚧 Position of the player for live

One of these must be set. If both are provided, the timestamp will take priority.

The template also contains an event number, by default it is set to 1. This number represents the number of event that the client posted for a specific stream. Therefore, after sending the first event the client must increment this number for each event.

🚧 Event number

Incrementing the eventNumber field is particularly for the Vimond player session service in order to generate accurate metrics. If this field is not incremented, it can lead to errors in the view count service.

The log data is an encrypted block of information containing non alterable information about the play request. This information is decrypted then compared with the player event and the end user JWT token. This is a security measure to verify that the player events are not shared between users, not used for a different asset and that important information is not altered.

🚧 The log data expires

The log data has an expiration period, once reached the player session service will return 403. In that case the end user has to make a new call to the play service.

This expiration period can be configured via the Vimond team.

As described in the reference documentation, the player event can be passed either via a query parameter, or through the body request. We recommend that you post the player event in the body template.

curl --request POST \
--url 'https://{tenant}.player-session-service.{domain}\
/external/player-events/{uuid}' \
--header 'authorization: Bearer eyJ....' \
--header 'content-type: application/json'
--data '
{
"eventName": "encrypted_player_log_event",
"originator": "12345",
"originatorId": "894c0efa-80b4-4f31-a7d9-6532b463babe",
"subProfileId": "709d0c6eea56d5f8a2cf3947964138f93c8b8960",
"versions": [
"1.0"
],
"tenant": "vimond",
"logData": "ferjfe8uf3940u3kfjf3jf49f==",
"client": {
"buildName": "${client_build_name}",
"buildVersion": "${client_build_version}",
"deviceId": "12345-abcde-67890-fghij",
"drm": "${client_drm}",
"envPlatform": "${client_env_platform}",
"envVersion": "${client_env_version}",
"pageUrl": "${client_page_url}",
"platform": "web",
"playerEvent": "${player_event}",
"playerState": "${player_state}",
"streamUrl": "${client_stream_url}",
"videoFormat": "${video_mime_type}",
"videoProtocol": "${video_protocol}",
"viewingSession": "${viewing_session}"
},
"progress": {
"eventNumber": 1,
"assetId": "62873",
"categoryId": "11491",
"title": "Monday night, still writing docs...",
"playbackType": "vod",
"vod": {
"duration": 147.877,
"position": "${vod_stream_position}"
}
},
"timestamp": "2018-02-16T13:01:49.379Z"
}
'

If the event is posted successfully, the player session service will return a 200 or 204 HTTP code.

In some cases different codes can be returned:

HTTP codeDescription
200The event was posted successfully and the player can keep playing the stream, but the body contains a kick event for another stream for the same user.
204The event was posted successfully and the player can keep playing the stream. There are no kick events registered.
400The request was malformed
401The request was incorrectly authenticated
403- The post event was successful but the stream session was kicked out. More information can be found in the response body. - The log data have expired, the user needs to make a new play call - The log data is invalid due to guarded values being tampered with

Viewing session identifier and kick event.

Section titled “Viewing session identifier and kick event.”

The viewing session identifier is to be set by the client. A session can be a single stream, a set of stream from the same device, or others. It is totally up to the client.

If end-users have too many open viewing sessions, it may break the stream count rule associated to the category and they will receive a kick event.

When a user session is kicked out, a kick event description for the related session will be sent to all of the user sessions. However, only the client with the kicked stream session will received a 403 HTTP code. You can find an example of kick event below:

{
"1234-abcd-5678-efgh": {
"eventName": "kick-event",
"originator": "chuck-norris",
"tenant": "vimond",
"originatorId": "894c0efa-80b4-4f31-a7d9-6532b463babe",
"versions": [
"1.0"
],
"timestamp": "2018-02-16T13:01:49.379Z",
"guid": "84aafbda-31a7-4d57-a35a-ce36515674c9",
"viewingSessionIdentifier": "1234-abcd-5678-efgh",
"viewingSession": "1234-abcd-5678-efgh",
"client": {
"viewingSession": "1234-abcd-5678-efgh"
},
"kickReason": {
"errorCode": "CATEGORY_ERROR",
"errorMessage": "Max number (3) active streams for this category is reached"
}
}
}

If the log data is expired, you will receive this error message:

{
"errors": [
{
"title": "EXPIRED_LOGDATA",
"detail": "The log data has expired",
"code": "7004"
}
]
}

When a user pauses or ends watching a stream during playback you might want to send the player-event immediately in order to capture the viewing history to make the resume playback functionality as accurate as possible. There is no need to follow the defined periodic intervals in these cases.

A pause event should have the client.playerEvent value period and the client.playerState value pause.

An event for when the stream was exited during playback should have the client.playerEvent value end and the client.playerState value pause.

If you want to send an event when a stream has reached its end, you can do that as well. In that case the client.playerEvent value should be end, and the client.playerState field can be removed.