Skip to content

Analytics

In all our sdk's we have the integration against the analytics platform within Red Bee Managed OTT Platform already in place without further action. I.e. all measurements regarding consumption, quality of service and errors will be sampled and browsable within the Insights section in the Customer Portal.

If you have scenarios where you won't use our sdk, for whatever reason, you can still build your own integration against our Analytics platform, sending in data thru the api.

Event Names

Each event is specified by name within its payload, sent to the same endpoint and possibly in a batch together with other events.

  • Device.Info The device info object should be sent once per playback session, no later than the Playback.Started event.
  • Playback.Created This event is sent when the player is instantiated, or invoked for the first time during the playback session.
  • Playback.HandshakeStarted If the player was created but not supposed to automatically play the asset as soon as possible, the HandshakeStarted event indicates that the player is preparing for playback now.
  • Playback.DRM This event is send when the device tries to obtain a DRM license (send the request to the DRM license server), receives a license from the DRM license server or receives an error report from the DRM license server
  • Playback.PlayerReady Signals that the player is ready
  • Playback.Started Signals that the player has successfully started playback of the asset/channel.
  • Playback.Paused Playback has temporarily stopped, but the playback session is still active. It is assumed that the video was paused due to user intervention. If the pausing was caused by a buffer underrun, the Playback.BufferingStarted event should be used instead.
  • Playback.Resumed Player has resumed playing the asset that was paused.
  • Playback.ScrubbedTo Playback position has jumped. This event should be sent after a successful seek/scrub in the video stream.
  • Playback.BufferingStarted Playback paused temporarily as the player ran out of data to show. When the buffer has been filled, the player should issue a Playback.BufferingStopped event.
  • Playback.BufferingEnded Buffering has stopped. Does not imply that the video has resumed playing, in that case, send Playback.Resumed.
  • Playback.BitrateChanged Playback switched to a different bitrate
  • Playback.Heartbeat Sent to tell the server that the client is still around, and the playback session is active. Heartbeats are sent during playback of vod and live. If there are other recent events sent by the player, there is no need to send the heartbeat in addition to them.
  • Playback.Completed Playback stopped because it reached the end of the asset. If playback stopped due to user intervention or errors, a Playback.Aborted should be sent instead. This is considered being a terminal state, and no further heartbeats or other events are expected in this playback session.
  • Playback.Aborted Playback stopped because of user intervention or error. This is considered being a terminal state, and no further heartbeats or other events are expected in this playback session.
  • Playback.Error Playback stopped because of user intervention or error. This is considered being a terminal state, and no further heartbeats or other events are expected in this playback session.

  • Playback.StartCasting The end-user invoked Casting functionality

  • Playback.StopCasting The end-user stopped Casting and the session continues on the device that initiated Casting.
  • Playback.StartAirplay The end-user invoked AirPlay functionality.
  • Playback.StopAirplayThe end-user stopped AirPlay

  • Playback.AdStarted

  • Playback.AdCompleted
  • Playback.AdFailed

  • Playback.ProgramChanged Playing a channel, when program is changed

Post Event Logic

Each event, or event batch, sent to server needs to be authorized for us to be able to connect it to a session - whether it is a registered user's session or an anonymous session.

Such batch should be triggered at least with the interval of the variable postInterval received in the analytics object in the /play response. See documentation for that request and response.

Each event should be sent as a POST, having an authorization bearer token applied and a json object as body. The request can be sent and forgotten. There is no need to wait for a response.

Payload

The structure of each POST body should be set as follows

{
  "Customer": "",
  "BusinessUnit": "",
  "SessionId": "", // received as playSessionId in the /play response
  "DispatchTime": 0, // epoch time
  "Payload": [], // one or more payload object
}

where the standard payload object contains the following parameters

{
  "EventType": "", // according to the event names mentioned in the start of this document, e.g. Playback.Started
  "OffsetTime": 0, // position in the content in milliseconds
  "SequenceNumber": 0, // iterated per event, from zero +1 for each event
  "Timestamp": 0, // epoch time
  "AnalyticsTag": "", // received from the /play response, analytics.tag
  "AnalyticsPostInterval": 60, // received from the /play response, analytics.postInterval
  "AnalyticsBucket": 0, // received from the /play response, analytics.bucket
  "StreamingTechnology": "" // DASH, HLS or SMOOTHSTREAMING
}

some of these events may then be enriched with even further parameters.

Enriched Payloads

This parameters should be applied in addition to the already existing parameters on the payload object for each event.

Device Info

{
  "CDNVendor": "", // received from the /play response, cdn.provider
  "DeviceId": "", // this should be the same as used when fetching the session
  "DeviceModel": "", // TV/TABLET/PHONE/DESKTOP
  "AppType": "", // ios/tvos/android/android_tv/samsung_tv/lg_tv/browser
  "AppName": "", // the official name of the app
  "PageUrl": "", // web only, including query string
  "Referrer": "", // web only
  "OS": "",
  "OSVersion": "",
  "Player": "", // a player name which we can track down in analytics if we would want to differ on that dimension
  "Version": "", // your versioning of your player component
  "Technology": "", // underlaying player technology, i.e. Shaka, hls.js, ExoPlayer or AvPlayer etc
  "TechVersion": "",
  "UserAgent": ""  
}

Created

In addition to Device Info object above

{
  "AssetId": "", // the asset id in the platform
  "ProgramId": "", // if a channel is being played, i.e. used as asset id, you might send along the program id as well, for the ongoing program
  "AutoPlay": true // whether the player was able to auto play or not, either by setting or blocked by the browser
}

BitrateChanged

{
  "Bitrate": 0 // New bitrate, in kilobit/s. Integer
}

Error

In addition to Device Info object above

{
  "Code": "",
  "Message": "",
  "Info": "",
  "Details": ""
}

ProgramChanged

{
  "ProgramId": "" // new program id in the EPG which the playback is changing to
}

AdStarted, AdCompleted & AdFailed

{
  "AdMediaId": "" // the played ad's id
}

Example Payloads

Device.Info

{
  "EventType": "Device.Info",
  "OffsetTime": 0,
  "SequenceNumber": 1,
  "Timestamp": 1631172466,
  "AnalyticsTag": "default", // received from the /play response, analytics.tag
  "AnalyticsPostInterval": 60, // received from the /play response, analytics.postInterval
  "AnalyticsBucket": 1, // received from the /play response, analytics.bucket
  "StreamingTechnology": "HLS",
  "CDNVendor": "CTL", // received from the /play response, cdn.provider
  "DeviceId": "ec50ebb0-9807-11e9-a69b-fbee1ea15e80", 
  "DeviceModel": "Desktop",
  "AppType": "browser", 
  "AppName": "RedBee TV", 
  "PageUrl": "https://internal.redbee.live/play/12345678?key1=value1&key2=value2", 
  "Referrer": "https://www.google.com/search?q=red+bee+mott", 
  "OS": "macOS",
  "OSVersion": "11.5.1",
  "Player": "javascript-player",
  "Version": "0.31.4",
  "Technology": "Shaka",
  "TechVersion": "3.2.0",
  "UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"    
}

Common Playback events

{
  "EventType": "Playback.Paused",
  "OffsetTime": 17000,
  "SequenceNumber": 5,
  "Timestamp": 16311723289, 
  "AnalyticsTag": "default", 
  "AnalyticsPostInterval": 60,
  "AnalyticsBucket": 1, 
  "StreamingTechnology": "HLS"
}

Error Event

{
  "EventType": "Playback.Error",
  "OffsetTime": 27000,
  "SequenceNumber": 19,
  "Timestamp": 1631193267,
  "AnalyticsTag": "default",
  "AnalyticsPostInterval": 60,
  "AnalyticsBucket": 1, 
  "StreamingTechnology": "HLS",
  "CDNVendor": "CTL", 
  "DeviceId": "ec50ebb0-9807-11e9-a69b-fbee1ea15e80", 
  "DeviceModel": "Desktop",
  "AppType": "browser", 
  "OS": "macOS",
  "OSVersion": "11.5.1",
  "Player": "javascript-player",
  "Version": "0.31.4",
  "Technology": "Shaka",
  "TechVersion": "3.2.0",
  "UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36",      
  "Code": "500",
  "Message": "",
  "Info": "",
  "Details": ""
}

Example Flow

  1. Player is created, sends events for Device.Info, Playback.Created and Playback.HandshakeStarted
  2. The player might fetch DRM, sends Playback.DRM
  3. When the player is ready to start playback, i.e. all data is fetched as well as DRM license if needed, we signal Playback.PlayerReady
  4. When the player has started to play, we send Playback.Started
  5. We then act on applicable events for pause, resume, buffering, scrubbing etc. If no such event appears, we will send a Playback.Heartbeat event within the interval specified in /play response analytics.postInterval.
  6. If the playback is completed, we'll send Playback.Completed, though if the user closes the player we should rather send Playback.Aborted.

This interval mentioned in step #5 may as well be used to send the batches to the server - i.e. we don't have to send these events one by one but rather with the payload objects in the array specified in the payload section.