Skip to main content

Metrics

FLAnalytics is an add-on library that serves as a framework for recording comprehensive data metrics related to application, video playback, and user events. The library can also be used to collect custom events and metadata. The library's data model is based on the Data Dictionary which is the standard schema used to normalize every piece of data captured in order to generate many popular video streaming quality of experience metrics.

QP Analytics offers extensions for the following analytics tools, enabling client applications to seamlessly interact with them through simplified public APIs:

  1. Datazoom
  2. Conviva

Below are the steps for setting up and integrating each tool.

Setup

Quickplay's Player QOE metrics module with Conviva SDK, a real-time analytics platform designed to optimize video streaming experiences. Conviva provides detailed insights into viewer engagement, streaming quality, ad performance metrics and audience behavior helping content providers enhance performance and maximize user satisfaction. Through data-driven metrics, it enables better decision-making for live and on-demand video services.

Supported SDK version

  • Conviva JS Core SDK 4.7.12

Install

// Install via NPM dependency
npm install --save fl-analytics

// Install via Immediately Invoked Function Expression -IIFE-
<script src="./fl-analytics.iife.js"></script>

Application Session

Application session provides the entry point to the library analytics protocols. It also serves as factory containing APIs to create other analytic sessions (PlaybackSession, UserSession). Besides this ApplicationSession also provides APIs for reporting app start and report fatal and non-fatal errors.

Create an application session by providing the appropriate configuration, which is discussed in detail in the following section.

NameTypeRequiredDescription
configurationAnalyticsReporterConfiguration
AnalyticsReporterConfiguration[]
trueAn object containing the settings for the analytics tools. If more than one analytics tool is required then provide an array of configurations.

Playback Session

Playback session provides APIs to report playback related events. Create a playback session by providing the following information.

NameTypeRequiredDescription
contentContenttrueAn object with the playback content metadata.
playbackSourcestringfalseA string indicating the playback source.
appContainerApplicationContainerfalseAn object with the application container information.
platformPlatformAuthorizerfalseA reference to the platform authorizer used to authorize cost optimization API calls.

User Session

User session provides APIs to report user events. Create a user session by providing the following information.

NameTypeRequiredDescription
userUsertrueAn object containing the settings for the analytics tools.

Create sessions


// API to create application session
const appSession = flAnalytics.getApplicationSession();

// API to initialize application session
const initResponse = await appSession.initialize(config);

// API to create playback session
const playbackSession = appSession.createPlaybackSession(content, playbackSource, appContainer, platform);

// API to create user session
const userSession = appSession.createUserSession(user);

note

Since application session is a singleton class, appSession.initialize(...) should be called before creating sessions and reporting events. The library client can start reporting events only if successful connectivity has been established to analytics system. The initialize method will return an object indicating the initialization status of each analytics tool.

Also note that application session acts as a factory to create the remaining analytic session instances (playback session and user session).

The library supports connection to multiple analytics provider (supports Datazoom and Conviva at present) by creating a configuration object for the specific analytics provider. Follow the steps below to create a configuration.

Create Analytics Configuration

Create a new configuration object containing the following metadata.

NameTypeRequiredDescription
applicationApplicationtrueThe application information.
deviceDevicefalseThe device information.
userUserfalseUser information.
customEventsConfigUrlstringfalseCustom events configuration URL.
loggerLoggerfalseCustom logger.

Depending on which Conviva or Datazoom analytics tool is required, the following metadata must also be provided.

Create configuration to initialize Conviva.

NameTypeRequiredDescription
customerKeystringtrueThe Conviva customer key.
debugbooleanfalseFlag indicating if a production session or a debug session should be created.
gatewayUrlstringfalseGateway URL used to initialize development/debugging Conviva session.
adMetadataAdMetadatafalseAd metadata.
costOptimizationUrlstringfalseCost optimization endpoint URL.
costOptimizationParams{[key:string]:any}falseA map with the cost optimization request data.
costOptimizationRefreshIntervalnumberfalseCost optimization refresh time in minutes. Default value is 10 minutes.

Create Conviva Analytics Configuration

const convivaConfig = {
application: appMetadata,
device: deviceMetadata,
user: userMetadata,
customEventsConfigUrl: "<blacklist-events-url>",
logger: appLogger,
customerKey: "<conviva-key>",
debug: true,
gatewayUrl: "<gateway-url>",
adMetadata: adMetadata,
costOptimizationUrl: "<cost-optimization-url>",
costOptimizationParams: {
deviceName: "<device-name>",
deviceId: "<device-id>",
custom: {
segmentName: "cohort1",
customerSegment: "residentialnova",
userStatus: "subscribed"
}
},
costOptimizationRefreshInterval: 5

}

Initialize Application Session

// Configure Conviva only
appSession.initialize(convivaConfig);

// Configure Datazoom only
appSession.initialize(datazoomConfig);

// Configure both, Conviva and Datazoom
appSession.initialize([ convivaConfig, datazoomConfig ]);

Common Reporting Data

The Metadata that is expected to remain constant for the entire duration of a session should be provided using common reporting data. It encapsulates all relevant optional and mandatory metadata regarding different aspects of the analytics session.

Application

NameTypeRequiredDescription
namestringtrueApplication name.
versionstringtrueApplication version.
buildstringtrueApplication build version.
productstringfalseApplication product.

User

NameTypeRequiredDescription
idstringfalseUnique user identifier of the user.
typeUserTypefalseUser type according to their subscription state.
subscriptionSubscriptionfalseUser's subscription information.
profileIdstringfalseUnique identifier for the user's profile.
profileTypestringfalseUser's profile type.

Device

NameTypeRequiredDescription
brandstringtrueBrand of the device.
categoryDeviceCategorytrueCategory of the device.
modelstringtrueModel of the device.
osNamestringtrueOperating system name.
osVersionstringtrueOperating system version.
screenResolutionHeightnumberfalseScreen resolution height.
screenResolutionWidthnumberfalseScreen resolution width.
screenResolutionScaleFactorstringfalseScreen resolution scale factor.
typeDeviceTypetrueDevice type.
versionstringtrueDevice version.

Initialization Response

When using the appSession.initialize(...) API, the callback will contain a Promise<InitializationResponse[]>.

The InitializationResponse structure contains:

NameTypeDescription
analyticProviderProviderIdentifies the specific analytics tool being initialized (possible values: Datazoom, Conviva).
resultboolean or ErrorA boolean or Error indicating the outcome of the initialization process. true indicates successful initialization, while Error provides details about why the initialization failed.

Sample Integration

const appInfo = {
name: "sample-application",
version: "1.0.0",
build: "7.51.5",
}

const userInfo = {
type: flAnalytics.UserType.ANONYMOUS,
}

const deviceInfo = {
brand: 'Asus',
category: flAnalytics.DeviceCategory.WEB,
model: 'GL704GW',
osName: 'Microsoft Windows 11 Pro',
osVersion: '10.0.22631',
screenResolutionHeight: 768,
screenResolutionWidth: 1024,
screenResolutionScaleFactor: '3:4',
type: flAnalytics.DeviceType.DESKTOP,
version: 'test-version'
}

const adMetadata = {
adTechnology: flAnalytics.AdTechnology.SERVER_SIDE,
isSlate: 'false',
adMediaFileApiFramework: 'NA',
adStitcher: 'ad-stitcher',
adMediaUrl: 'ad-media-url'
}

const convivaConfig = {
customerKey: "<conviva-key>",
application: appInfo,
user: userInfo,
device: deviceInfo,
adMetadata: adMetadata,
}

const appSession = flAnalytics.getApplicationSession();

appSession.initialize(convivaConfig).then((initResponse) => {
if (initResponse.find(
(response) =>
response.analyticProvider === flAnalytics.Provider.CONVIVA).result
) {
// Conviva sensor successfully initialized
// appSession is ready to use
}
});

Multiple Analytic Tools

appSession.initialize([ convivaConfig, datazoomConfig ]).then((initResponse) => {
if (initResponse.find(
(response) =>
response.analyticProvider === flAnalytics.Provider.CONVIVA).result
) {
// Conviva sensor successfully initialized
}

if (initResponse.find(
(response) =>
response.analyticProvider === flAnalytics.Provider.DATAZOOM).result
) {
// Datazoom collector successfully initialized
}

// appSession is safe for use if any of Conviva sensor or Datazoom collector
// is successfully initialized
});

Playback Events and Metrics

Create playback session to report player related events. To create a playback session the below information must be provided.

let playbackSession = null;

appSession.createPlaybackSession(
content,
playbackSource,
applicationContainer,
platform,
).then(playbackSession => {
// playbackSession is ready to use
});

Attach Player

The playback session provides an API called attachPlayer which takes Player instance as parameter. This API enables the underlying analytics tool to access platform native player instance, therefore auto-reporting most of the playback related events.

playbackSession.attachPlayer(player);

Auto-Collected Playback Events

Playback events that are auto-captured by library itself.

NameDescription
pauseThis event is reported when the player is paused.
resumeThis event is reported when the user begins playing after pausing the video.
buffer_startBuffer Start identifies anytime the player has to wait for the video buffer to fill with video segments.
buffer_endEvent is reported when video starts playing again after a buffer is completed.
player errorThrown if an error occurs during content playback or retrieval of the video.
playingThe media is no longer blocked from playback, and has started playing. Reported when playback resumes from Stall, Buffering or Seek.

Value Added Events and Metrics

Application Events

Application Start

Application session provides an API to report the application start event. This is expected to be called on application load.

appSession.start({ startupTime: 16 });

Interrupt Start

Must be called to mark the start of the session's lifecycle interruption in order to pause normal session workflow.

Optionally it accepts a CustomEvent object as a parameter to provide detailed information on the event that caused the interrupt.

appSession.interruptStart();

Interrupt End

Must be called to mark the end of the session's lifecycle interruption in order to resume normal session workflow.

Optionally it accepts a CustomEvent object as a parameter to provide detailed information on the event that caused the interrupt.

appSession.interruptEnd();

Application Stop

Must be called to terminate analytics session lifecycle.

appSession.stop();

Playback Events

Playback Start

Must be called to initiate playback session lifecycle.

playbackSession.start();

Interrupt Start

Must be called to mark the start of the session's lifecycle interruption in order to pause normal session workflow.

Optionally it accepts a CustomEvent object as a parameter to provide detailed information on the event that caused the interrupt.

playbackSession.interruptStart();

Interrupt End

Must be called to mark the end of the session's lifecycle interruption in order to resume normal session workflow.

Optionally it accepts a CustomEvent object as a parameter to provide detailed information on the event that caused the interrupt.

playbackSession.interruptEnd();

Stop

Must be called to terminate the playback session.

playbackSession.stop();

User Events

UserSession provides the following API to report user action based events.

// Called when [User] executes "signup" flow.
userSession.signup(userInfo)

// Called when [User] executes "login" flow.
userSession.login(userInfo)

// Called when [User] executes "logout" flow.
userSession.logout(userInfo)

// Called when [User] executes "create profile" flow.
userSession.createProfile(userInfo)

// Called when [User] executes "update profile" flow.
userSession.updateProfile(userInfo)

// Called when [User] executes "start subscription" flow.
userSession.startSubscription(userInfo)

// Called when [User] executes "purchase subscription" flow.
userSession.purchaseSubscription(userInfo)

// Called when [User] executes "change subscription" flow.
userSession.changeSubscription(userInfo)

// Called when [User] executes "complete payment" flow.
userSession.completePayment(userInfo)
note

It is client application responsibility to ensure that each user action is triggered in the correct sequence.

Report Custom Events

ApplicationSession provides an API to report custom events.

const customEvent = {
event: 'sample_event',
data: {
'key1': 'value1',
'key2': 'value2'
}
}

appSession.addEvent(customEvent);
note
  1. In order to conform to the existing reporting scheme the event name should be provided in the lower case format and words should be separated by the underscore character e.g."playback_request"
  2. In Datazoom, any custom event will be reported as event name with custom_ prefix. (eg: playback_start as custom_playback_start)
caution

When trying to report a custom event with a name that is already reserved (the list of reserved event names is captured by QP_ANALYTICS_EVENTS), library will throw an error.

Configure Application Metadata

Set Application custom metadata

Additional metadata that is to be added or updated to all application / playback / user events can be done using the below API. All subsequent events will report this additional data once it is defined.

appSession.setMetadata({
'key1': 'value1',
'key2': 'value2'
});

Application Errors

ApplicationSession provides APIs to report both fatal and non-fatal errors.

Report Fatal errors

Any application fatal error can be reported using below API. Send Error as a parameter(optional) to report playback stop on any error.

applicationSession.stop(error)

Report Non-fatal errors

Any application non-fatal error can be reported using below API. Send Error to report playback stop on any error.

applicationSession.addErrorEvent(error)

User Action Errors

Any User error can be reported using below API. Create UserError reporting data payload in case where one of user's action fails and User attribute along with it.

Create User Error

NameTypeRequiredDescription
codeStringtrueThe unique error code.
messageStringtrueThe message describing the error.
descriptionStringfalseThe contextual description of the error.
const userError = {
code: '745',
message: 'user action failure',
description: 'user action failure details'
}

Cost Optimization

Reporting events for the entire duration of a content playback can be costly. For this reason, analytics reporting to Conviva can be controlled by determining how much time the analytics reporter will be active.

To configure cost optimization, the following parameters should be passed to the Conviva configuration object provided during the application session initialization.

NameTypeRequiredDescription
costOptimizationUrlstringfalseThe URL to the cost optimization endpoint.
costOptimizationParamsObjectfalseAn object containing cost optimization request parameters.
costOptimizationRefreshIntervalObjectfalseThe amount of time in seconds to request for cost optimization time thresholds.

Cost Optimization Parameters

In order to make a successful HTTP request to the cost optimization endpoint URL, the following parameters should be passed to the Conviva configuration object.

const params = {
deviceName: "test-device-name",
deviceId: "test-device-id",
custom: {
segmentName: "cohort1",
customerSegment: "residentialnova",
userStatus: "subscribed"
}
}
NameTypeRequiredDescription
deviceNamestringtrueDevice name.
deviceIdstringtrueDevice unique identifier (eg: androidmobile, androidtablet, huaweimobile, huaweitablet, androidtv, androidstb, androidstbv2, iosmobile, iostablet, web, mobileweb, samsungtizentv, lgwebostv).
segmentNamestringtrueSegment name (eg: cohort1, cohort2, cohort3, cohort4, cohort5).
customerSegmentstringtrueCustomer segment (eg: residentialnova, sme, hotel hosp, hotel basic).
userStatusstringtrueUser status (eg: anonymous, registered, subscribed).

Authorize Cost Optimization HTTP Request

Each HTTP request to the cost optimization endpoint must be authorized. To authorize the HTTP request a platform authorizer object must be provided when creating a new playback request as follows:

const playbackSession = await appSession.createPlaybackSession(content, playbackSource, applicationContainer, platformAuthorizer);

Out-of-box Player Metrics

The Quickplay Player provides number of key metrics to analyse the playback performance. Please refer the bundled sample app to understand the corresponding metrics API.

Key Player Metrics

  • Load Latency - This is the number of seconds it took for the video element to have enough data to begin playback. This is measured from the time load() is called to the time the 'loadeddata' event is fired by then media element.

  • Buffer Range - Indicates how much is buffered ahead of the playhead and how much is buffered behind the playhead (in seconds).

  • Decoded Frames - The total number of frames decoded by the Player.

  • Framerate - Provides number of Frames being displayed (per second).

  • Dropped Frames - The total number of frames dropped by the Player.

  • Corrupted Frames - The total number of corrupted frames dropped by the browser.

  • Play Time - The total time spent in a playing state in seconds.

  • Pause Time - The total time spent in a paused state in seconds.

  • License Time - The time spent on license requests during this session in seconds, or NaN.

  • Buffering Time - The total time spent in a buffering state in seconds.

  • Required Bandwidth - The bandwidth required for the current streams (total, in bit/sec).

  • Estimated Bandwidth - The current estimated network bandwidth (in bit/sec).

  • Variant Bitrate - The bandwidth required to play active variant track, in bits/sec.

  • Video Bitrate - The total time spent in a buffering state in seconds.

  • Audio Bitrate - The bandwidth required for the current streams (total, in bit/sec).

  • Width - The width of the current video track.

  • Height - The height of the current video track.

The Quickplay Player's PlaybackStatistics provides all metric info required. For more information please refer sample app.

player.subscribe('progressupdate', function () {
console.log(player.playbackStatistics);
});

Enumerations

AdTechnology

enum AdTechnology {
CLIENT_SIDE = 'Client Side',
SERVER_SIDE = 'Server Side',
}

DeviceCategory

enum DeviceCategory {
ANDROID_DEVICE = 'AND',
APPLE_DEVICE = 'APL',
CHROMECAST = 'CHR',
DESKTOP_APP = 'DSKAPP',
DEVICE_SIMULATOR = 'SIMULATOR',
KAIOS_DEVICE = 'KAIOS',
LG_TV = 'LGTV',
NINTENDO = 'NINTENDO',
PLAYSTATION = 'PS',
ROKU = 'RK',
SAMSUNG_TV = 'SAMSUNGTV',
SET_TOP_BOX = 'STB',
SMART_TV = 'TV',
TIVO = 'TIVO',
WEB = 'WEB',
WINDOWS_DEVICE = "WIN'",
XBOX = 'XB',
LINUX = 'LNX',
}

DeviceType

enum DeviceType {
CONSOLE = 'Console',
DESKTOP = 'DESKTOP',
MOBILE = 'Mobile',
SETTOP = 'Settop',
SMARTTV = 'SmartTV',
TABLET = 'Tablet',
VEHICLE = 'Vehicle',
OTHER = 'Other',
}

PlatformName

enum PlatformName {
IOS = 'iOS',
ANDROID_MOBILE = 'Android Mobile',
TV_OS = 'tvOS',
ANDROID_TV = 'Android TV',
FIRE_TV = 'FireTV',
LG = 'LG',
CHROMECAST = 'Chromecast',
WEB_DESKTOP = 'Web Desktop',
WEB_MOBILE = 'Web Mobile',
TIZEN = 'Tizen',
VIZIO = 'Vizio',
ROKU = 'Roku',
}

PlatformType

enum PlatformType {
APP = 'app',
WEB = 'web',
}

Provider

enum Provider {
DATAZOOM = 'Datazoom',
CONVIVA = 'Conviva',
UNKNOWN = 'Unknown',
}

SubscriptionStatus

enum SubscriptionStatus {
ACTIVE = 'active',
FREE = 'free',
GRACE = 'grace',
CANCELLED = 'cancelled',
EXPIRED = 'expired',
}

UserType

enum UserType {
ANONYMOUS = 'anonymous',
FREE_TRIAL = 'free_trial',
REGISTERED = 'registered',
SUBSCRIBED = 'subscribed',
}

Types

AdMetadata

NameTypeRequiredDescription
adTechnologyAdTechnologyfalseAd technology (server side or client side)
isSlatestringfalseIs slate.
adMediaFileApiFrameworkstringfalseAd media file API framework.
adStitcherstringfalseAd stitcher.
adMediaUrlstringfalseAd media URL.

Content

NameTypeRequiredDescription
idstringfalseUnique identifier for content item.
channelstringfalseChannel.
typestringfalseContent type.
namestringfalseContent name from CMS to ensure accurate title if different from the player title.
providerIdstringfalseUnique identifier for the content provider.
genrestringfalseGenre of the content.
licenseWindowStartDatestringfalseThe license window start date.
isLiveStreamTypefalseStream type VOD, live or unknown. Required for Conviva.
durationnumberfalseTotal stream duration. Required for Conviva.
playerNamestringfalseName of the content player. Required for Conviva.
streamUrlstringfalseURL the content. Required for Conviva.
encodedFrameratenumberfalseEncoded framerate. Required for Conviva.
viewerIdstringfalseUnique identifier for the viewer. Required for Conviva.
defaultResourcestringfalseDefault resource. Required for Conviva.

SportContent (extends Content)

NameTypeRequiredDescription
sportNamestringfalseName of the sport.
leagueIDstringfalseUnique identifier for league.
leagueExternalIDstringfalseExternal identifier for league.
leagueNamestringfalseName of the league.
leagueShortNamestringfalseShort name of the league.
gameIDstringfalseGame unique identifier.
gameExternalIDstringfalseGame external identifier.
team1IDstringfalseUnique identifier for team 1.
team1ExternalIDstringfalseExternal identifier for team 1.
team1NamestringfalseName of team 1.
team1ShortNamestringfalseShort name for team 1.
team2IDstringfalseUnique identifier for team 2.
team2ExternalIDstringfalseExternal identifier for team 2.
team2NamestringfalseName of team 2.
team2ShortNamestringfalseShort name for team 2.
venueSportVenuefalseSport venue.

SportVenue

NameTypeRequiredDescription
venueNamestringfalseName of the venue.
venueCitystringfalseCity of the venue.
venueCountrystringfalseCountry of the venue.

TVShow (extends Content)

NameTypeRequiredDescription
seriesIdstringfalseSeries identifier.
seriesNamestringfalseName of the series.
seasonNumberstringfalseSeason number.
episodeNumberstringfalseEpisode number.

Application Container

NameTypeRequiredDescription
idstringtrueCarousel ID where the content or link to collection is located.
namestringtrueCarousel where the content or link to collection is located.

Subscription

NameTypeRequiredDescription
idstringtrueUnique identifier of the user's subscription.
statusSubscriptionStatusfalseStatus of the user's subscription state.
planstringfalseSubscription plan type name.
planIdstringfalseSubscription plan type id.

Custom Event

NameTypeRequiredDescription
eventstringtrueThe name of the custom event.
data{ [p: string]: any }trueThe reporting data payload.

Application Error

NameTypeRequiredDescription
codestringtrueApplication error code.
messagestringtrueApplication error message.
descriptionstringfalseApplication error description.
internalErroranyfalseApplication internal error.

Playback Error

NameTypeRequiredDescription
playbackSourcestringfalsePlayback source for the content related to this error.
contentContenttrueContent related to this error.
containerApplicationContainerfalseApplication container related to this error.
codestringtrueApplication error code.
messagestringtrueApplication error message.
descriptionstringfalseApplication error description.
internalErroranyfalseApplication internal error.