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 serverPlayback.PlayerReady
Signals that the player is readyPlayback.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 bitratePlayback.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.StopAirplay
The 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¶
- Player is created, sends events for
Device.Info
,Playback.Created
andPlayback.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.Heartbeat
event within the interval specified in/play
responseanalytics.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.