Skip to main content

Metrics

qp-rn-analytics is an add-on library that serves as a framework for recording comprehensive data metrics related to application, video playback, video downloads, and user events. The library can also be used to collect custom events and metadata. The 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
  3. NPAW
  4. Newrelic

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

Android Setup

Gradle Dependency:

Add the following to your build.gradle:

dependencies {
implementation "io.datazoom.sdk:media3:<latest-version>"
}

iOS Setup

Podfile Integration:

Add the following environment variable in your application's Podfile before the podspec is evaluated (i.e., before config = use_native_modules! line):

ENV['USE_DATAZOOM'] = '1'

Configuration

let datazoomConfiguration = {
config_id: '<unique identifier>',
config_url: '<Datazoom server endpoint URL>' // Only needed for Android
}

CommonReportingData

let application = {
app_name: string,
app_version: string,
app_build: string
}
let device = {
platformType: 'app' | 'web',
customDeviceManufacturer?: string,
customDeviceName?: string
}
let user = {
userType: UserType,
userId?: string,
subscription?: Subscription
}
let abTesting = {
experiment_id: string,
variant_id: string
}
let commonReportingData = {
application,
user,
device,
abTesting
}

Initialization

import { analyticsReporter } from '@quickplay/qp-rn-analytics';
await analyticsReporter.initWithConfig({ datazoomConfiguration }, commonReportingData, configEndPoint?);

Events & Usage

See Application Events, User Events, Download Events, Playback Events below for usage. All APIs are available as described in the general usage section.


Application Events

// Report Application start
let startUpTimeMs = 123;
analyticsReporter.start(startUpTimeMs);

// Report Application end
analyticsReporter.stop();

User Events

// Create UserSession
await analyticsReporter.createUserSession();

// User actions
userSession.signup(user);
userSession.login(user);
userSession.logout(user);
userSession.createProfile(user);
userSession.updateProfile(user);
userSession.deleteProfile(user);
userSession.startSubscription(user);
userSession.purchaseSubscription(user);
userSession.purchaseSubscriptionCancel(user);
userSession.purchaseSubscriptionFailure(user);
userSession.changeSubscription(user);
userSession.completePayment(user);
userSession.forgotPassword(user);

Download Events

// Create DownloadSession
let downloadSessionID = await analyticsReporter.createDownloadSession();

// Report Download Start
downloadSession.start(downloadSessionID, downloadRequest);

Custom Events

let customEvent = { event: string, attributes?: { [key: string]: string } };
analyticsReporter.addEvent(customEvent);

Application Metadata

// Add custom metadata (Android only)
analyticsReporter.addMetadata({ key: 'Value' });
// Update custom metadata (Android only)
analyticsReporter.updateMetadata({ key: 'Value' });

Playback Events

// Create PlaybackSession
let playbackSessionID = await analyticsReporter.createPlaybackSession();

// Attach Player
let player = await createPlayer(playerConfig);
let playerID = player.getNativeID();
playbackSession.attachPlayer(playbackSessionID, playerID);

// Report Playback Start
playbackSession.start(playbackSessionID, playbackRequest);

// Handle interruptions
playbackSession.interruptStart(playbackSessionID, customEvent);
playbackSession.interruptEnd(playbackSessionID, customEvent);

// Add/Update Playback Metadata (Android only)
playbackSession.addMetadata(playbackSessionID, { key: 'value' });
playbackSession.updateMetadata(playbackSessionID, { key: 'value' });
// Update program info
playbackSession.updateMetadata(playbackSessionID, { programId: string, programName: string });

// Report Playback Error
playbackSession.stop(playbackSessionID, error);

Error Reporting

// Application Errors
analyticsReporter.addErrorEvent(error);

// Download Errors
downloadSession.stop(downloadSessionID, error);

// User Action Errors
userSession.addErrorEvent(userError, user);

Enable Cost optmization flow for conviva

To enable Cost optmization feature for conviva, app has to send analyticsThrottlerServiceUrl in AnalyticsThrottlerConfiguration.

NameTypeRequiredDescription
analyticsThrottlerServiceUrlStringTrueThe URL to fetch details related to analytics data stream throttling, such as enabling/disabling analytics reporting.
platformClientPlatformClientFalseThe PlatformClient instance representing platform-specific device identification.
analyticsThrottlerSyncIntervalNumberFalseThe time interval (in minutes) to periodically fetch throttler details.
customParametersMap<String, String>FalseA list of custom key-value parameters.

To configure throttled analytics reporting, pass analyticsThrottlerServiceUrl, platformClient, analyticsThrottlerSyncInterval, and customParameters to analyticsThrottlerConfig

let platformClient: PlatformClient = {
id: "123",
// Possible values for type are: androidmobile, androidtablet, androidtv, androidstb, iosmobile, iostablet, iostv.
type: Platform.OS === 'ios' ? 'iosmobile' : 'androidmobile'
}

let analyticsThrottlerConfig: AnalyticsThrottlerConfiguration = {
analyticsThrottlerServiceUrl: <url to fetch details related to analytics data stream throttling such as enabling or disabling analytics reporting>,
platformClient?: platformClient,
analyticsThrottlerSyncInterval?: 30,
customParameters?: {[key: string]: string}
}

To enable the Cost Optimization feature for Conviva, pass analyticsThrottlingConfig to the initializeAnalyticsThrottling API.

initializeAnalyticsThrottling should be called immediately after ensureAuthorization, once the platformAuthorizer instance is available

let authToken: AuthorizationToken
authToken = await platformAuthorizer.ensureAuthorization();
// Call initializeAnalyticsThrottling after authorization is ensured
await analyticsReporter.initializeAnalyticsThrottling(analyticsThrottlingConfig: AnalyticsThrottlerConfiguration)

Report Events and Metadata

Application Events

Report Application start

analyticsReporter provides an API to report app_start event along with app start time.


// The time, in milliseconds, it takes to start the application.
let startUpTimeMs = 123
analyticsReporter.start(startUpTimeMs)

Report Application End

analyticsReporter provides an API to report app_end event.

    analyticsReporter.stop()

User Events

Create UserSession to report user related events.


import { analyticsReporter } from '@quickplay/qp-rn-analytics';

// to create userSession object
await analyticsReporter.createUserSession()

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


import { analyticsReporter, userSession } from '@quickplay/qp-rn-analytics';

// to create userSession object
await analyticsReporter.createUserSession()

let user : User = {
type: UserType,
id?: string,
profileID?: string,
subscription?: Subscription,
data?: { [key: string]: string },
profileType?: string | undefined,
}

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

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

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

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

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

// Called when [User] executes "delete profile" flow.
userSession.deleteProfile(user: User)

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

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

// Called when [User] executes "purchase subscription cancel" flow.
userSession.purchaseSubscriptionCancel(user: User)

// Called when [User] executes "purchase subscription failure" flow.
userSession.purchaseSubscriptionFailure(user: User)

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

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

// Called when [User] executes "forgot password" flow.
userSession.forgotPassword(user: User)

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

Download Events

Create DownloadSession to report download related events.

    import { analyticsReporter } from '@quickplay/qp-rn-analytics';


// the unique id created for a particular download for identification
let downloadSessionID = await analyticsReporter.createDownloadSession()

Report Download Start


import { downloadSession, DownloadRequest } from '@quickplay/qp-rn-analytics';


let applicationContainer:ApplicationContainer= {
applicationContainerId: string
applicationContainerName: string
}

let streamType = 'live' | 'vod'

let content: Content = {
id: string,
type: string,
name: string,
providerID: string,
genre?: string,
licenseWindowStartDate?: string,
data: { [key: string]: string },
channel?: string,
streamType: streamType,
brand?: string,
affiliate?: string,
assetProviderName?: string,
cdnName?: string,
external_content_id?: string,
enrichment_content_id?: string,
program_id?: string,
program_name?: string,
channel_id?: string,
channel_name?: string,
is_free_preview?: boolean,
auto_preview?: boolean,
playback_mode?: string,
is_downloadable?: boolean
}

let playbackSource = 'carousel' | 'suggested next' | 'recommendation' | 'search' | 'content details' | 'channels' | 'continue watching' | 'my list' | 'home autoplay' | 'details autoplay' | 'deeplink' | 'referral' ;

let contentType = 'tvshow' | 'sportContent' | '' ;

let userJourney: UserJourney = {
page_id?: string,
storefront_id?: string,
storefront_name?: string,
tab_id?: string,
tab_name?: string,
collection_id?: string,
collection_name?: string,
current_screen?: string,
search_item_position?: number,
pref_download_on_wifi_only?: boolean,
}

let downloadRequest: DownloadRequest = {
event: string
applicationContainer: ApplicationContainer
content: Content | TVShow | SportContent
playbackSource: playbackSource
contentType: contentType,
userJourney: userJourney
}

downloadSession.start(downloadSessionID, downloadRequest)

Report Custom Events

analyticsReporter provides an API to report custom events. The library provides MiscellaneousEvent names for the client application to reuse.

    import { analyticsReporter, CustomEvent } from '@quickplay/qp-rn-analytics';

let customEvent: CustomEvent = {
event: string
attributes?: { [key: string]: string }
}

analyticsReporter.addEvent(customEvent)

Configure Application Metadata

Add Application custom metadata

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

    import { analyticsReporter } from '@quickplay/qp-rn-analytics';

analyticsReporter.addMetadata({"key":"Value"})

NOTE: This api is present only for Android OS

Update Application custom metadata

analyticsReporter provides an API if the application wants to change any application level attribute at any point of time during the application session.

    import { analyticsReporter } from '@quickplay/qp-rn-analytics';

analyticsReporter.updateMetadata(({"key":"Value"}))

Report Playback Events

Create PlaybackSession to report player related events.

    import { analyticsReporter } from '@quickplay/qp-rn-analytics';

// the unique id created for a particular playback for identification
let playbackSessionID = await analyticsReporter.createPlaybackSession()

Attach Player

playbackSession provides and API called attachPlayer which takes PlayerID as parameter. This API enables the underlying analytics collection tool to access platform native player instance, therefore auto-reporting most of the playback related events.

    import { playbackSession } from '@quickplay/qp-rn-analytics';
import { createPlayer, PlayerConfig } from 'rn-qp-nxg-player';

// the unique id created earlier for a particular playback for identification
let playbackSessionID = await analyticsReporter.createPlaybackSession()

let player = await createPlayer(playerConfig)
let playerID= player.getNativeID()

playbackSession.attachPlayer(playbackSessionID, playerID)

Report Custom Playback Events

Report Playback Start

playbackSession provides API to report playback_request event.

    import { playbackSession, PlaybackRequest, analyticsReporter } from '@quickplay/qp-rn-analytics';

// the unique id created earlier for a particular playback for identification
let playbackSessionID = await analyticsReporter.createPlaybackSession()

let applicationContainer: ApplicationContainer= {
applicationContainerId: string
applicationContainerName: string
}

let streamType = 'live' | 'vod'

let content: Content = {
id: string,
type: string,
name: string,
providerID: string,
genre?: string,
licenseWindowStartDate?: string,
data: { [key: string]: string },
channel?: string,
streamType: streamType,
brand?: string,
affiliate?: string,
assetProviderName?: string,
cdnName?: string,
external_content_id?: string,
enrichment_content_id?: string,
program_id?: string,
program_name?: string,
channel_id?: string,
channel_name?: string,
is_free_preview?: boolean,
auto_preview?: boolean,
playback_mode?: string,
is_downloadable?: boolean
}

let playbackSource = 'carousel' | 'suggested next' | 'recommendation' | 'search' | 'content details' | 'channels' | 'continue watching' | 'my list' | 'home autoplay' | 'details autoplay' | 'deeplink' | 'referral' ;

let contentType = 'tvshow' | 'sportContent' | '' ;

let userJourney: UserJourney = {
page_id?: string,
storefront_id?: string,
storefront_name?: string,
tab_id?: string,
tab_name?: string,
collection_id?: string,
collection_name?: string,
current_screen?: string,
search_item_position?: number,
pref_download_on_wifi_only?: boolean,
}

let playbackRequest: PlaybackRequest = {
playbackEvent: string,
applicationContainer: applicationContainer,
content: content,
playbackSource: playbackSource,
contentType: contentType,
userJourney: userJourney
}

playbackSession.start(playbackSessionID, playbackRequest)

Handling Playback Request Interruptions

Any interruptions prior to starting the playback (before creating a player) can be reported using playbackSession API. Example: Checks related to content authorization (content authentication, parental controls etc)

    import { playbackSession, analyticsReporter, CustomEvent } from '@quickplay/qp-rn-analytics';


// the unique id created earlier for a particular playback for identification
let playbackSessionID = await analyticsReporter.createPlaybackSession()


let customEvent: CustomEvent = {
event: string
attributes?: { [key: string]: string }
}

// Report Interruption start
playbackSession.interruptStart(playbackSessionID, customEvent)

// Report Interruption end
playbackSession.interruptEnd(playbackSessionID, customEvent)


Configure Playback Metadata

Add Playback custom metadata

playbackSession provides an API that inserts common metadata to be reported across all playback related events.

    import { playbackSession, analyticsReporter } from '@quickplay/qp-rn-analytics';

// the unique id created earlier for a particular playback for identification
let playbackSessionID = await analyticsReporter.createPlaybackSession()

playbackSession.addMetadata(playbackSessionID, {"key":"value"})

NOTE: This api is present only for Android OS

Update Playback custom metadata

playbackSession provides an API to update common metadata to be reported across all playback related events.

    import { playbackSession, analyticsReporter } from '@quickplay/qp-rn-analytics';

// the unique id created earlier for a particular playback for identification
let playbackSessionID = await analyticsReporter.createPlaybackSession()

playbackSession.updateMetadata(playbackSessionID, {"key": "value"})

NOTE: Whenever the program changes, make sure to update the programId and programName keys by calling:

 playbackSession.updateMetadata(playbackSessionID, {"programId": string, "programName": string})

Report Playback Error

To report any error caused like content-auth failure, concurrent streams max limit reached (failure from server but not from player layer as fl-analytics auto-reports player errors) can be reported using stop API in PlaybackSession. Send Error as a parameter(optional) to report playback stop on any error.

    import { playbackSession, analyticsReporter, Error } from '@quickplay/qp-rn-analytics';

// the unique id created earlier for a particular playback for identification
let playbackSessionID = await analyticsReporter.createPlaybackSession()

let error: Error {
errorCode: number,
errorDescription: string,
contextDescription: string,
internalError?: Error
}

playbackSession.stop(playbackSessionID, error)


Report Errors

Application Errors

    import { analyticsReporter, Error } from '@quickplay/qp-rn-analytics';

let error: Error {
errorCode: number,
errorDescription: string,
contextDescription: string,
internalError?: Error
}

// To report Fatal errors
analyticsReporter.stop(error)

// To report Non-Fatal errors
analyticsReporter.addErrorEvent(error)

Download Errors

Any Download error can be reported using below API. Send Error to report download stop on any error.

    import { playbackSession, analyticsReporter, UserError } from '@quickplay/qp-rn-analytics';

// the unique id created earlier for a particular download for identification
let downloadSessionID = await analyticsReporter.createDownloadSession()

let error: Error{
errorCode: number,
errorDescription: string,
contextDescription: string,
internalError?: Error
}

downloadSession.stop(downloadSessionID, 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.

    import { playbackSession, analyticsReporter, UserError } from '@quickplay/qp-rn-analytics';

let userError: UserError {
errorCode: string,
errorDescription: string,
contextDescription: string,
internalError?: Error,
errorType?: ErrorType,
errorSeverity?: ErrorSeverity
}

let user: User = {
type: UserType,
id?: string,
profileID?: string,
subscription?: Subscription,
data?: { [key: string]: string },
profileType?: string | undefined,
baseSubscription?: string,
silentLogin?: boolean
}

userSession.addErrorEvent(userError, user)