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:
- Datazoom
- Conviva
- NPAW
- Newrelic
Below are the steps for setting up and integrating each tool.
- Datazoom
- Conviva
- NPAW
- NewRelic
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.
Android Setup
Gradle Dependency:
dependencies {
implementation "com.conviva.sdk:conviva-core-sdk:<latest-version>"
implementation "com.conviva.sdk:conviva-media3-sdk:<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_CONVIVA'] = '1'
Configuration
let convivaConfiguration = {
customer_key: '<unique identifier>',
allowBackgroundDataCapture: false, // Android only
gateway_url: '<Touchstone debug URL>',
logLevel: 'DEBUG' // 'DEBUG' | 'INFO' | 'WARNING' | 'ERROR' | 'NONE' | 'FUNC'
}
Cost Optimization (Throttling)
To enable cost optimization, pass analyticsThrottlerServiceUrl in AnalyticsThrottlerConfiguration:
let analyticsThrottlerConfig = {
analyticsThrottlerServiceUrl: '<throttler URL>',
platformClient: { id: '123', type: Platform.OS === 'ios' ? 'iosmobile' : 'androidmobile' },
analyticsThrottlerSyncInterval: 30,
customParameters: { key: 'value' }
}
Call after authorization:
await analyticsReporter.initializeAnalyticsThrottling(analyticsThrottlerConfig);
CommonReportingData
Same as Datazoom (see above).
Initialization
import { analyticsReporter } from '@quickplay/qp-rn-analytics';
await analyticsReporter.initWithConfig({ convivaConfiguration }, 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.
Android Setup
Gradle Dependency:
// In build.gradle
maven { url 'https://artifact.plugin.npaw.com/artifactory/plugins/android' }
// In app/build.gradle
implementation "com.npaw.plugin:plugin:<version>"
implementation("com.npaw.plugin:plugin-media3-exoplayer:<version>") { exclude group: "androidx.media3" }
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_NPAW'] = '1'
Add the following source for Cocoapods:
source 'https://bitbucket.org/npaw/plugin-ios-cocoapods.git'
Configuration
const npawConfiguration = {
accountCode: '<unique identifier>',
enableDiagnosticOption: false,
logLevel: 'DEBUG'
}
CommonReportingData
Same as Datazoom (see above).
Initialization
import { analyticsReporter } from '@quickplay/qp-rn-analytics';
await analyticsReporter.initWithConfig({ npawConfiguration }, 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.
Android Setup
Gradle Dependency:
// In build.gradle
classpath("com.newrelic.agent.android:agent-gradle-plugin:<version>")
// In app/build.gradle
apply plugin: 'newrelic'
implementation "com.newrelic.agent.android:android-agent:<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_NEWRELIC'] = '1'
Configuration
const newrelicFeatureFlags = {
interactionTracing: true,
analyticsEventReporting: true, // Android only
nativeReporting: true, // Android only
eventPersistence: true, // Android only
swiftInteractionTracing: false, // iOS only
crashReporting: true,
nsURLSessionInstrumentation: true,
httpResponseBodyCapture: true,
webViewInstrumentation: true,
requestErrorEvents: true,
networkRequestsEvents: true,
handledExceptionReporting: true,
defaultInteractions: true,
distributedTracing: true,
appStartMetrics: true,
fedRampEnabled: false,
swiftAsyncURLSessionSupport: false, // iOS only
logReporting: false,
newEventSystem: false,
offlineStorage: false,
backgroundReporting: false,
autoCollectLogs: false
}
const newRelicEventReportingConfigs = {
progressReportingIntervalMs: 60000 // default 1 min
}
const newrelicConfiguration = {
appToken: '<token>',
primaryEventType: '<table name>',
newRelicFeatureFlags,
newRelicEventReportingConfigs
}
CommonReportingData
let application = {
app_name: string,
app_version: string,
app_build: string,
product: string,
display_language: string,
station: string,
property: string
}
let device = {
platformType: 'app' | 'web',
platformName: string,
deviceId: string
}
let user = {
userType: UserType,
profileId: string,
baseSubscription: string,
silentLogin: boolean
}
let commonReportingData = {
application,
user,
device
}
Initialization
import { analyticsReporter } from '@quickplay/qp-rn-analytics';
await analyticsReporter.initWithConfig({ newrelicConfiguration }, 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.
| Name | Type | Required | Description |
|---|---|---|---|
| analyticsThrottlerServiceUrl | String | True | The URL to fetch details related to analytics data stream throttling, such as enabling/disabling analytics reporting. |
| platformClient | PlatformClient | False | The PlatformClient instance representing platform-specific device identification. |
| analyticsThrottlerSyncInterval | Number | False | The time interval (in minutes) to periodically fetch throttler details. |
| customParameters | Map<String, String> | False | A 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.
initializeAnalyticsThrottlingshould be called immediately afterensureAuthorization, 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)