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.InfoThe device info object should be sent once per playback session, no later than the Playback.Started event.Playback.CreatedThis event is sent when the player is instantiated, or invoked for the first time during the playback session.Playback.HandshakeStartedIf 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.DRMThis 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 serverPlayback.PlayerReadySignals that the player is readyPlayback.StartedSignals that the player has successfully started playback of the asset/channel.Playback.PausedPlayback 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.ResumedPlayer has resumed playing the asset that was paused.Playback.ScrubbedToPlayback position has jumped. This event should be sent after a successful seek/scrub in the video stream.Playback.BufferingStartedPlayback 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.BufferingEndedBuffering has stopped. Does not imply that the video has resumed playing, in that case, send Playback.Resumed.Playback.BitrateChangedPlayback switched to a different bitratePlayback.HeartbeatSent 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.CompletedPlayback 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.AbortedPlayback 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.ErrorPlayback 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.StartCastingThe end-user invoked Casting functionality Playback.StopCastingThe end-user stopped Casting and the session continues on the device that initiated Casting.Playback.StartAirplayThe end-user invoked AirPlay functionality.-
Playback.StopAirplayThe end-user stopped AirPlay -
Playback.AdStarted Playback.AdCompleted-
Playback.AdFailed -
Playback.ProgramChangedPlaying 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¶
- Player is created, sends events for
Device.Info,Playback.CreatedandPlayback.HandshakeStarted - The player might fetch DRM, sends
Playback.DRM - 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 - When the player has started to play, we send
Playback.Started - We then act on applicable events for pause, resume, buffering, scrubbing etc. If no such event appears, we will send a
Playback.Heartbeatevent within the interval specified in/playresponseanalytics.postInterval. - If the playback is completed, we'll send
Playback.Completed, though if the user closes the player we should rather sendPlayback.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.