Metrics
fl-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 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:
- Datazoom
- Conviva
- NPAW (NicePeopleAtWork)
NPAW integration is available only with QuickPlay Player SDK version 7.1.x
- NewRelic
Below are the steps for setting up and integrating each tool.
Setup
- Conviva
- Datazoom
- NPAW
- NewRelic
Quickplay's Player QOE metrics module with Conviva SDK which is a real-time analytics platform designed to optimize video streaming experiences. It provides insights into viewer engagement, streaming quality, and audience behavior, helping content providers improve performance and maximize user satisfaction. Through data-driven metrics, enables better decision-making for live and on-demand video services.
- Add the following dependencies for Conviva in your Application's
build.gradle
file's dependencies block.
dependencies {
implementation 'com.conviva.sdk:conviva-core-sdk:4.0.43'
implementation 'com.conviva.sdk:conviva-exoplayer-sdk:4.1.5'
}
- Add the following Moshi-Kotlin dependency, which QP Analytics library uses internally to convert kotlin native obejcts to collections and vice verse
dependencies {
implementation 'com.squareup.moshi:moshi-kotlin:1.9.1'
}
Quickplay's Player QOE metrics module with Datazoom SDK which provides a video data platform which continually gathers data from endpoints, like a CDN or a video player, through an ecosystem of collectors. Once the data is gathered, it is normalized using standardized data definitions. This data is then sent through available connectors to analytics platforms like Google BigQuery, Google Analytics, and Splunk and can be visualized in tools such as Looker and Superset. Datazoom is your key to a more effective and efficient data pipeline.
- Add following maven repository URL in your Root
build.gradle
file.
maven {
// Snapshot Repository
maven {
url 'https://gitlab.com/api/v4/projects/18323233/packages/maven'
}
// Release Repository
maven {
url 'https://gitlab.com/api/v4/projects/10353305/packages/maven'
}
}
If targeting QuickPlay Player SDK version 7.1.x with Media3 the maven repository setup is not required.
- Add the following dependencies for Datazoom Exo Player SDK in your Application's
build.gradle
file's dependencies block.
If targeting QuickPlay Player SDK version 7.0.x:
dependencies {
implementation 'com.datazoom.android:base-collector-gold:3.3.3'
implementation 'com.datazoom.android:exo-collector-gold-google:2.3.7'
}
If targeting QuickPlay Player SDK version 7.1.x:
dependencies {
implementation 'io.datazoom.sdk:media3:0.0.3'
}
Quickplay's Player QOE metrics module with NPAW SDK which provides an advanced solution designed to help control, and optimize users' video experience, as well as video delivery flow. NPAW Plugin collect metrics and metadata related to the behavior of any video streaming app, grouped into the following categories:
- Video Analytics: Obtain extensive real-time analytics on the video platform’s performance and audience behavior during video playback.
- Ads Analytics: Analyze ad performance concerning audience, business, quality, and engagement.
- App Analytics: Monitor any event within any app, providing a comprehensive understanding of user behavior beyond video playback.
- Add following maven repository URL in your Root
build.gradle
file.
maven {
// Release Repository
maven {
url 'https://artifact.plugin.npaw.com/artifactory/plugins/android'
}
}
- Add the following dependencies for NPAW SDK in your Application's
build.gradle
file's dependencies block.
dependencies {
implementation 'com.npaw.plugin:plugin:7.3.12'
implementation 'com.npaw.plugin:plugin-media3-exoplayer:1.6.1-7.3.12'
}
Quickplay's Player QOE metrics module with NewRelic SDK which is a real-time analytics platform designed to gathers data continuously for playback(both video and ad) and download. It provides insights into viewer engagement, streaming quality and audience behavior, helping content providers improve performance and maximize user satisfaction.
- Add NewRelic classpath to project level build.gradle.
buildscript {
dependencies {
classpath("com.newrelic.agent.android:agent-gradle-plugin:7.6.5")
}
} - Set minSdk version to 24 or above.
- Add NewRelic plugin and dependency to application or module level build.gradle.
apply plugin: 'newrelic'
dependencies {
implementation "com.newrelic.agent.android:android-agent:7.6.5"
}
If required to configure multiple analytics(Datazoom, Conviva, NPAW, and NewRelic) follow above setup for all four Datzoom, Conviva, NPAW, and NewRelic.
Create Application Session
ApplicationSession
provides the entry point to the library analytics protocols. It also serves as factory containing APIs to create other analytic sessions (PlaybackSession, UserSession, DownloadSession). Besides this ApplicationSession
also provides APIs for reporting app start and report fatal and non-fatal errors.
Create ApplicationSession
using the relevant APIs, creation of each parameter is briefed below
val appSession = ApplicationSession.createInstance(
configuration,
connectionListener,
commonData,
customEventsConfigEndpoint
)
ApplicationSession.getInstance()
// API to create PlaybackSession
appSession.createPlaybackSession()
// API to create UserSession
appSession.createUserSession()
// API to create DownloadSession
appSession.createDownloadSession()
Since ApplicationSession
is a singleton class, ApplicationSession.createInstance
should be called only once and ApplicationSession.getInstance
should be used to access the ApplicationSession
object thereafter.
Also note that ApplicationSession
acts as a factory to create the remaining analytics session instances(UserSession
, PlaybackSession
, DownloadSession
).
The library supports connection to multiple analytics provider (supports Datazoom, Conviva, NPAW, NewRelic at present) by create configuration to specific analytic provider, below is the section for creating configuration for respective analytics module.
Create Analytics Configuration
- Conviva
- Datazoom
- NPAW
- NewRelic
Create configuration to initialize conviva.
Name | Required | Description |
---|---|---|
customerKey | true | The unique identifier of the Conviva configuration key. |
gatewayURL | false | The url for show-casing playbackSession on touchstone (A Conviva tool designed to assist in debugging and validating the integration of Conviva's video sensor with streaming applications and platforms.). |
allowBackgroundDataCapture | false | Tracks metrics even when the application goes to background if the value is set to true. Default is set to false. |
setLogLevel | false | Set logger level for additional logs to debug, below is the table with possible enum values |
Name | Description |
---|---|
ConvivaLogLevel.DEBUG | To set debug level logs. |
ConvivaLogLevel.INFO | To set info level logs. |
ConvivaLogLevel.WARNING | To set warning level logs. |
ConvivaLogLevel.ERROR | To set error level logs. |
ConvivaLogLevel.NONE | fallback value |
val configuration = ConvivaConfiguration(
<provided customer key from conviva>,
appContext = applicationContext,
)
gatewayURL
has to be set only on debug builds if required, this should never be enabled on production build
Create configuration to initialize datazoom.
Name | Required | Description |
---|---|---|
Id | true | The unique Datazoom configuration key. |
url | true | The URL of the Datazoom server endpoint. |
appContext | true | The Android application instance. |
val configuration = DatazoomConfiguration(
<configuration id from Datazoom>,
<url given by Datazoom>,
applicationContext
)
Create configuration to initialize npaw plugin.
Name | Required | Description |
---|---|---|
accountCode | true | NicePeopleAtWork account code that indicates customer account. |
appContext | true | The Android application instance. |
val configuration = NPAWConfiguration(
<accountCode from NPAW>,
applicationContext
)
Create configuration to initialize NewRelic.
Name | Required | Description |
---|---|---|
token | true | The unique token of the NewRelic configuration. |
primaryEventType | true | The table name for NewRelic event reporting. |
newRelicFeatureFlag | false | Feature flags to enable or disable NewRelic features. |
newRelicEventReportingConfigs | false | Configurations to customize NewRelic event reporting. |
NewRelicFeatureFlag provides feature flags to enable or disable NewRelic features.
Name | Default value | Description |
---|---|---|
analyticsEventReporting | true | Enable or disable the reporting of event data. |
appStartUpMetricsReporting | true | Enable or disable reporting app launch time (cold and hot time) to the metrics. |
backgroundReporting | false | Enable or disable background reporting when application goes to the background state. |
crashReporting | false | Enables or disables deferred crash reporting. |
handledExceptionReporting | false | Enable or disable recording handled exceptions events, which appear on the Handled exception page. |
nativeReporting | false | Enable or disable recording of native runtime crashes, exceptions and Application Not Responding (ANR) conditions, which appear on the Crash Analysis page. |
distributedTracingReporting | false | Enable or disable the adding of distributed tracing headers to network requests. |
eventPersistence | false | Enable or disable event persistence. |
fedRampReporting | false | Enable or disable reporting data using different endpoints for US government clients. |
interactionTracing | false | Enable or disable interaction tracing. |
defaultInteractionsReporting | false | Enable or disable default interactions. |
logReporting | false | Enable or disable agent logging. |
networkRequestsReporting | false | Enable or disable reporting successful HTTP requests to the MobileRequest event type. |
networkErrorRequestsReporting | false | Enable or disable reporting network and HTTP request errors to the MobileRequestError event type. |
httpResponseBodyCapture | false | Enable or disable capture of HTTP response bodies for HTTP error traces, and MobileRequestError events. |
offlineStorage | true | Enable or disable offline data storage when no internet connection is available. |
NewRelicEventReportingConfigs provides configurations to customize NewRelic events reporting.
Name | Default value | Description |
---|---|---|
progressReportingIntervalMs | 60000L | Player in-progress event reporting interval in milliseconds. It's default value is 1 minute. |
val newRelicConfiguration = NewRelicConfiguration(
token = "<NewRelic Token>",
primaryEventType = "<NewRelic Event type or Table name to be used for event reporting>",
newRelicFeatureFlag = NewRelicFeatureFlag(
analyticsEventReporting = true,
appStartUpMetricsReporting = true,
backgroundReporting = false,
crashReporting = false,
handledExceptionReporting = false,
nativeReporting = false,
distributedTracingReporting = false,
eventPersistence = false,
fedRampReporting = false,
interactionTracing = false,
defaultInteractionsReporting = false,
logReporting = false,
networkRequestsReporting = false,
networkErrorRequestsReporting = false,
httpResponseBodyCapture = false,
offlineStorage = true
),
newRelicEventReportingConfigs = NewRelicEventReportingConfigs(
progressReportingIntervalMs = 60000L
),
appContext = applicationContext
)
Configure Multiple analytic tools
If required to configure multiple analytic tools (Datzoom, Conviva, or NPAW), create analytics configuration for all analytics providers and send the configurations as list when creating application session using createInstance
API
var configurations: MutableList<AnalyticsReporter.Configuration> = mutableListOf()
val datazoomConfiguration = DatazoomConfiguration(
<configuration id from Datazoom>,
<url given by Datazoom>,
applicationContext
)
val convivaConfiguration = ConvivaConfiguration(
<provided customer key from conviva>,
appContext = applicationContext,
)
val npawConfiguration = NPAWConfiguration(
<accountCode from NPAW>,
applicationContext
)
val newRelicConfiguration = NewRelicConfiguration(
token = "<NewRelic Token>",
primaryEventType = "<NewRelic Event type or Table name to be used for event reporting>",
newRelicFeatureFlag = NewRelicFeatureFlag(
analyticsEventReporting = true,
appStartUpMetricsReporting = true,
backgroundReporting = false,
crashReporting = false,
handledExceptionReporting = false,
nativeReporting = false,
distributedTracingReporting = false,
eventPersistence = false,
fedRampReporting = false,
interactionTracing = false,
defaultInteractionsReporting = false,
logReporting = false,
networkRequestsReporting = false,
networkErrorRequestsReporting = false,
httpResponseBodyCapture = false,
offlineStorage = true
),
newRelicEventReportingConfigs = NewRelicEventReportingConfigs(
progressReportingIntervalMs = 60000L
),
appContext = applicationContext
)
// create list of analytic reporters as below
configurations.add(datazoomConfiguration)
configurations.add(convivaConfiguration)
configurations.add(npawConfiguration)
configurations.add(newRelicConfiguration)
val appSession = ApplicationSession.createInstance(
configurations,
connectionListener,
commonData,
customEventsConfigEndpoint
)
Create Analytics Connection Status Listener
The library client can start reporting events only if successful connectivity has been established to analytics system and AnalyticsConnectionStateListener API provides the connectivity status.
val connectionListener = object : AnalyticsSessionActivationStateListener {
override fun onSuccess() {
// write logic for the case when connected to analytics system.
}
override fun onFailure(error: Error) {
// write logic for the case when we not connect to analytics system. Check the error for reason.
}
}
When multiple analytics tools are configured, the AnalyticsSessionActivationStateListener
callback triggers onSuccess
if at least one tool initializes successfully and onFailure
if both fail to initialize.
Create Common Data
When intergrating Conviva just provide the basic parameters provided below to create ApplicationSession
which is marked as required true
as Conviva is mainly player metrics focusses tool.
The Metadata that is expected to remain constant for the entire duration of a session should be provided using CommonReportingData. It encapsulates all relevant optional and mandatory metadata regarding different aspects of the AnalyticSession
.
Use API to update any of this common reporting data.
Application
Create application reporting data payload.
Name | Type | Required | Description |
---|---|---|---|
name | String | true | The name of the application. |
version | String | true | The version of the application. |
buildVersion | String | true | The build version of the application. |
product | String | false | The customer product. |
User
When integrating Conviva, the id
for the USER
type is mandatory, as Conviva categorizes data based on the user's ID, follow below snippet to initialize it.
val user = User(
UserType.ANONYMOUS // modify this as per user type
)
user.id = <userId collected by your system>
Create user's reporting data payload.
Name | Type | Required | Description |
---|---|---|---|
type | UserType | true | Indicates appropriate user type. |
id | String | false | The unique user identifier (eg: Customer Id) |
subscription | Subscription | false | User subscription details. |
profileID | String | false | The unique identifier for the user's profile |
baseSubscription | String | false | Subscription package detail |
accountID | String | false | The unique account identifier |
silentLogin | Boolean | false | TRUE if Application is silently logged in or FALSE when real user logged in. |
Subscription
Create Subscription
reporting data payload which will be reported as part of above user's payload.
Name | Type | Required | Description |
---|---|---|---|
subscriptionId | String | true | The unique subscription identifier for the user. |
subscriptionStatus | SubscriptionStatus | false | Indicates appropriate subscription status. |
subscriptionPlan | String | false | The subscription plan type name. |
subscriptionPlanID | String | false | The subscription plan type id |
Device
Create user device's reporting data payload.
Name | Type | Required | Description |
---|---|---|---|
platformType | PlatformType | true | Represents how user consuming service (eg: APP, WEB). |
platformName | PlatformName | false | Represents device platform user is using (eg: ANDROID_MOBILE, ANDROID_TV, FIRE_TV, ANDROID_AUTO). |
deviceId | String | false | The unique indentifier for user's device. |
customDeviceManufacturer | String | false | The manufacturer of the user's device if available. |
customDeviceName | String | false | The name of the device model if available. |
Create CommonReportingData
that has to be reported across all the events for the entire application lifecycle.
Name | Type | Required | Description |
---|---|---|---|
app | Application | true | The Application instance. |
user | User | false | The User instance. |
device | Device | false | The Device instance. |
val appInfo = Application("sample", "1", "1")
val userInfo = User(UserType.SUBSCRIBED)
val deviceInfo = Device(PlatformType.APP)
val commonData = CommonReportingData(
appInfo,
userInfo,
deviceInfo
)
Toggle Custom Events
Custom Events reporting to the Analytics server can be toggled on/off remotely. Passing the config end point URL, where the black-listed items are hosted, to the createInstance
will restricts the reporting of black-listed custom events
Name | Type | Required | Description |
---|---|---|---|
customEventsConfigEndpoint | String | false | The end point where custom events configuration details are hosted |
Analytics throttling for Conviva
We offer a feature to throttle the data reported to Conviva, helping to optimize reporting costs. An API is exposed for this purpose, allowing configuration with the following parameters.
ApplicationSession
provides an API called initializeAnalyticsThrottling
which takes AnalyticsThrottlerConfiguration
object as parameter. This API triggers the analytics throttling feature.
Create AnalyticsThrottlerConfiguration
Create AnalyticsThrottlerConfiguration
object to be passed as parameter to initializeAnalyticsThrottling
We make API call to QP backend to fetch decision on how to throttle analytics reporting and this call is authorized call, so
the corresponding PlatformAuthorizer
object has to be provided for building AnalyticsThrottlerConfiguration
along with PlatformClient instance
Name | Type | Required | Description |
---|---|---|---|
platformAuthorizer | PlatformAuthorizer | true | PlatformAuthorizer instance to authorize |
platformClient | PlatformClient | true | PlatformClient instance |
analyticsThrottlerServiceUrl | String | true | The URL to fetch details related to analytics data stream throttling, such as enabling/disabling analytics reporting. |
analyticsThrottlerSyncInterval | Long | false | The time interval (in minutes) to periodically fetch throttler details. |
customParameters | Map<String, Any> | false | A list of custom key-value parameters. |
val throttlingConfig = AnalyticsThrottlerConfiguration(
platformAuthorizer,
platformClient,
analyticsThrottlerServiceUrl = <The URL to fetch details related to analytics data stream throttling, such as enabling/disabling analytics reporting>,
analyticsThrottlerSyncInterval = <The time interval (in minutes) to periodically fetch throttler details.>,
// below provider values are for sample
mapOf("userStatus" to "subscribed", "customerSegment" to "residentialnova", "segmantName" to "cohort1")
)
appSession.initializeAnalyticsThrottling(throttlingConfig)
initializeAnalyticsThrottling
should be called immediately once platformAuthorizer
instance is created.
Standard Playback Events & Metrics
Create Playback Session
Create PlaybackSession
to report player related events.
val playbackSession = appSession.createPlaybackSession()
Attach Player
Call above attachPlayer
API right after player has been created using PlayerBuilder
.
When composing the player (with IMA, Yospace, Brightcove or MediaTailor), invoke the attachPlayer API immediately after the player is composed with the said additional capabilities.
PlaybackSession
provides and API called attachPlayer
which takes Player
instance 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.
playbackSession.attachPlayer(player: Player)
Call above attachPlayer
API once player has been loading, Listen for PlaybackState.LOADING
state (refer Here).
Playback events that are auto-captured by library itself
- Conviva
- Datazoom
- NPAW
- NewRelic
Name | Description |
---|---|
pause | This event is reported when the player is paused. |
resume | This event is reported when the user begins playing after pausing the video. |
buffer_start | Buffer Start identifies anytime the player has to wait for the video buffer to fill with video segments. |
buffer_end | Event is reported when video starts playing again after a buffer is completed. |
player error | Thrown if an error occurs during content playback or retrieval of the video. |
seek_start | This event records when the user interacts with time controls within the player to move forward or backward in the video timeline. |
see_end | Event is reported when the player stops moving the playhead position to jump to a specific point on the timeline. |
playing | The media is no longer blocked from playback, and has started playing. Reported when playback resumes from Stall, Buffering or Seek. |
Name | Description |
---|---|
playback_start | This event is reported when the video starts playing for the user. |
heartbeat | This event is reported at periodic intervals (1 minute) during content playback. |
media_request | This event is reported after the user invokes playback. |
player_ready | Signifies when the player has been initialized and is ready for playback. |
pause | This event is reported when the player is paused. |
resume | This event is reported when the user begins playing after pausing the video. |
buffer_start | Buffer Start identifies anytime the player has to wait for the video buffer to fill with video segments. |
buffer_end | Event is reported when video starts playing again after a buffer is completed. |
stall_start | Stall Start event is reported when playback of video stops because the buffer has been depleted causing an unexpected interruption for the user. |
stall_end | Event reported when video starts playing again after a stall and the buffer has been replenished and playback resumes. |
error | Thrown if an error occurs during content playback or retrieval of the video. |
playback_complete | This event signifies that the video player has reached the end of the currently playing content. |
stop | This event is reported when the player has entered a stopped state. |
milestone | Reported when the playheadPosition passes a predetermined percentile milestone of the video's duration. Current milestones are fired at the 10, 25, 50, 75, 90 & 95 percentiles. |
seek_start | This event records when the user interacts with time controls within the player to move forward or backward in the video timeline. |
see_end | Event is reported when the player stops moving the playhead position to jump to a specific point on the timeline. |
playing | The media is no longer blocked from playback, and has started playing. Reported when playback resumes from Stall, Buffering or Seek. |
Name | Description |
---|---|
playback_start | This event is reported when the video starts playing for the user. |
pause | This event is reported when the player is paused. |
resume | This event is reported when the user begins playing after pausing the video. |
buffer_start | Buffer Start identifies anytime the player has to wait for the video buffer to fill with video segments. |
buffer_end | Event is reported when video starts playing again after a buffer is completed. |
player error | Thrown if an error occurs during content playback or retrieval of the video. |
seek_start | This event records when the user interacts with time controls within the player to move forward or backward in the video timeline. |
see_end | Event is reported when the player stops moving the playhead position to jump to a specific point on the timeline. |
playing | The media is no longer blocked from playback, and has started playing. Reported when playback resumes from Stall, Buffering or Seek. |
Name | Description |
---|---|
playback_start | This event is reported when initiates intent to play. |
playback_prepared | Called when the Player 'prepare' method is called indicating intent to play, but before any networking, or authentication/verification occurs. |
playback_started | This event is reported when start of video display. |
playback_inprogress | This event is reported when the playback is in progress and it is being sent every interval. |
playback_buffering_start | This event is reported when the player started buffering. |
playback_buffering_end | This event is reported when the buffering ends. |
playback_seek_start | This event is reported when user initiate seek. |
playback_seek_complete | This event is reported when user stop seek. |
playback_paused | This event is reported when playback is paused. |
playback_resumed | This event is reported when playback resumes after pause. |
playback_stopped | This event is reported when the playback is stopped for any reason. |
playback_complete | This event is reported when the video playback completes. |
playback_variant_change | This event is reported when the video variant changes. |
playback_audio_language_change | This event is reported when the audio variant changes. |
playback_subtitle_language_change | This event is reported when the subtitle variant changes. |
error | This event is reported when any error is thrown during playback. |
Report Custom Playback Events
The Android implementation of fl-analytics library does not provide support for multiple concurrent playback event reporting.
Report Playback Start
PlaybackSession
provides API to report playback_request
event.
PlaybackRequest
Content Specific metadata
Create data payload for specific type of contents as below.
SportContent
Create SportContent
reporting data payload that is specific to sport event.
Name | Type | Required | Description |
---|---|---|---|
id | String | true | The unique identifier for content item. |
type | String | true | The type of content to report. |
name | String | false | The content name from CMS. |
providerId | String | false | The content's provider identifier. |
genre | String | false | The genre of the content. |
licenseWindowStartDate | String | false | The license window start date. The clear content may not have this parameter. |
sportName | String | false | The name of the sport. |
leagueName | String | true | The name of the sport league. |
team1Name | String | false | The name of the first sport team. |
team2Name | String | false | The name of the second sport team. |
leagueID | String | false | The unique identifier of the sport league. |
leagueExternalID | String | false | The external unique identifier of the sport league. |
leagueShortName | String | false | The short name of the sport league. |
gameID | String | false | The unique identifier of the sport game. |
gameExternalId | String | false | The external unique identifier of the sport game. |
venueName | String | false | The name of the sport event venue. |
venueCity | String | false | The city where the sport event takes place. |
venueCountry | String | false | The country where the sport event takes place. |
team1ID | String | false | The unique identifier of the first sport team. |
team1ExternalID | String | false | The external unique identifier of the first sport team |
team1ShortName | String | false | The short name of the first sport team. |
team2ID | String | false | The unique identifier of the second sport team. |
team2ExternalID | String | false | he external unique identifier of the second sport team. |
team2ShortName | String | false | The short name of the second sport team. |
channel | String | false | The channel on which the content is consumed. |
streamType | ContentType | true | The type of content being streamed, such as live or VOD. |
brand | String | false | The name of the brand to which the content belongs. |
affiliate | String | false | Affiliate or MVPD name for TV Everywhere authenticated services. |
assetProviderName | String | false | The name of CMS Provider. |
cdnName | String | false | The name of CDN from where the streaming resource is played. |
externalContentID | String | false | The unique identifier for content from external system. |
enrichmentContentID | String | false | The unique identifier for content from external system. |
channelID | String | false | The unique channel identifier. |
channelName | String | false | The name of the channel. |
programID | String | false | The unique program identifier. |
programName | String | false | The name of the program. |
TVShow
Create TVShow
reporting data payload that is specific to TV show.
Name | Type | Required | Description |
---|---|---|---|
id | String | true | The unique identifier for content item. |
type | String | true | The type of content to report. |
name | String | false | The content name from CMS. |
providerId | String | false | The content's provider identifier. |
genre | String | false | The genre of the content. |
licenseWindowStartDate | String | false | The license window start date. The clear content may not have this parameter. |
seriesID | String | true | The unique identifier of the TV show series. |
seriesName | String | true | The name of the TV show series. |
seasonNumber | String | true | The season number of the TV show series. |
episodeNumber | String | true | The number of one of the episodes in the TV show series. |
channel | String | false | The channel on which the content is consumed. |
streamType | ContentType | true | The type of content being streamed, such as live or VOD. |
brand | String | false | The name of the brand to which the content belongs. |
affiliate | String | false | Affiliate or MVPD name for TV Everywhere authenticated services. |
assetProviderName | String | false | The name of CMS Provider. |
cdnName | String | false | The name of CDN from where the streaming resource is played. |
externalContentID | String | false | The unique identifier for content from external system. |
enrichmentContentID | String | false | The unique identifier for content from external system. |
programID | String | false | The unique program identifier. |
programName | String | false | The name of the program. |
MiscellaneousContent
Create MiscellaneousContent
video content reporting data payload that belongs to categories other than SportContent
or TVShow
.
Name | Type | Required | Description |
---|---|---|---|
id | String | true | The unique identifier for content item. |
type | String | true | The type of content to report. |
name | String | false | The content name from CMS. |
providerId | String | false | The content's provider identifier. |
genre | String | false | The genre of the content. |
licenseWindowStartDate | String | false | The license window start date. The clear content may not have this parameter. |
channel | String | false | The channel on which the content is consumed. |
streamType | ContentType | true | The type of content being streamed, such as live or VOD. |
brand | String | false | The name of the brand to which the content belongs. |
affiliate | String | false | Affiliate or MVPD name for TV Everywhere authenticated services. |
assetProviderName | String | false | The name of CMS Provider. |
cdnName | String | false | The name of CDN from where the streaming resource is played. |
externalContentID | String | false | The unique identifier for content from external system. |
enrichmentContentID | String | false | The unique identifier for content from external system. |
channelID | String | false | The unique channel identifier. |
channelName | String | false | The name of the channel. |
programID | String | false | The unique program identifier. |
programName | String | false | The name of the program. |
Fallback to MiscellaneousContent
if the content type is neither SportContent
nor TVShow
.
The following metadata properties are required for all content types to meet Conviva certification requirements:
brand
affiliate
assetProviderName
cdnName
If any of these properties are not applicable to your app’s use case, please notify the Conviva team when submitting your build for certification.
ApplicationContainer
Create ApplicationContainer
reporting data payload related to application container.
Name | Type | Required | Description |
---|---|---|---|
id | String | true | The unique identifier of the carousel where the content or link to the collection is located. |
name | String | true | The name of the carousel where the content or link to the collection is located. |
UserJourney
Create UserJourney
reporting data payload related to user journey.
Name | Type | Required | Description |
---|---|---|---|
pageID | String | false | The unique page identifier. |
storefrontID | String | false | The unique store front identifier. |
storefrontName | String | false | The store front name. |
tabID | String | false | The unique tab identifier. |
tabName | String | false | The tab name. |
containerID | String | false | The unique container identifier. |
containerName | String | false | The container name. |
collectionID | String | false | The unique collection identifier. |
collectionName | String | false | The collection name. |
verticalPosition | Int | false | The vertical position of the element. |
horizontalPosition | Int | false | The horizontal position of the element. |
currentScreen | String | false | The current screen name or identifier. |
searchItemPosition | Int | false | The position of the search item based on search result and user click to play. |
displayLanguage | String | false | The application display Language - English, etc. |
prefDownloadOnWifiOnly | Boolean | false | The user preference to download content on wifi only. |
priceCode | String | false | The Price code for TVOD. Credits / Rental price code of a content user chooses to redeem or rent. |
Location
Create Location
reporting data payload related to user location.
Name | Type | Required | Description |
---|---|---|---|
postalCode | String | false | The user postal code. |
latitude | Float | false | The latitude of user location. |
longitude | Float | false | The longitude of user location. |
Create PlaybackRequest
reporting data payloads related to video playback request event.
Name | Type | Required | Description |
---|---|---|---|
content | Content | true | The Content details. |
playbackSource | PlaybackSource | false | The PlaybackSource details. |
container | ApplicationContainer | false | The ApplicationContainer details. |
userJourney | UserJourney | false | The UserJourney details. |
location | Location | false | The Location details. |
val container = ApplicationContainer("456", "Movies")
val playbackSource = PlaybackSource(PlaybackSourceType.CAROUSEL)
// For MiscellaneousContent
val contentInfo = MiscellaneousContent("12345", "movie", "Sample Content")
// For SportContent
val contentInfo = SportContent("1234", "sport_show")
// For TVShow
val contentInfo = TVShow("2345", "Magic Show", "1", "5")
val playbackRequest = PlaybackRequest(contentInfo, playbackSource, container)
playbackSession.start(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)
// Report Interruption start
val event = "content_authorization_started"
val reportingData = mapOf("key" to "value")
val customEvent = CustomEvent(event, reportingData)
playbackSession.interruptStart(customEvent)
// Report Interruption end
val event = "content_authorization_success"
val reportingData = mapOf("key" to "value")
val customEvent = CustomEvent(event, reportingData)
playbackSession.interruptEnd(customEvent)
Configure Playback Metadata
Add Playback custom metadata
PlaybackSession
provides an API that inserts common metadata to be reported across all playback related events.
playbackSession.addMetadata(
mapOf("key" to "value")
)
Update Playback custom metadata
PlaybackSession
provides an API to update common metadata to be reported across all playback related events.
playbackSession.updateMetadataRecord(
mapOf("cc_enabled" , "true")
)
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.
playbackSession.stop(error)
Valued Added Events & Metrics
Click to see more details on creating other sessions(User, Download sessions), prefer this section if integrating Datazoom or NewRelic
Application Events
Report Application start
ApplicationSession
provides an API to report app_start
event along with app start time.
ApplicationMetrics
Create ApplicationMetrics
reporting data payload related to application performance metrics.
Name | Type | Required | Description |
---|---|---|---|
startUpTimeMs | Long | true | The time, in milliseconds, it takes to start the application. |
appSession.start(
ApplicationMetrics(3000)
)
Report Application End
ApplicationSession
provides an API to report app_end
event.
appSession.stop()
User Events
Create UserSession
and start session to report user related events.
val userSession = appSession.createUserSession()
userSession.start(Unit)
UserSession
provides the following API to report user action based events.
// 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 "start subscription" flow.
userSession.startSubscription(user: User)
// Called when [User] executes "purchase subscription" flow.
userSession.purchaseSubscription(user: User)
// Called when [User] executes "change subscription" flow.
userSession.changeSubscription(user: User)
// Called when [User] executes "complete payment" flow.
userSession.completePayment(user: User)
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.
val downloadSession = appSession.createDownloadSession()
Report Download Start
DownloadSession
provides API to report download_request
event.
DownloadRequest
NewRelicUpdate
-
Create Content, video content reporting data payload based on type of content that is being requested. Create SportContent if sport content was requested or TVShow if TV show content was requested, MiscellaneousContent otherwise.
-
Create ApplicationContainer reporting data payload related to application container.
-
Create
DownloadRequest
reporting data payloads related to video playback request event.
Name | Type | Required | Description |
---|---|---|---|
content | Content | true | The Content details. |
playbackSource | PlaybackSource | false | The PlaybackSource details. |
container | ApplicationContainer | false | The ApplicationContainer details. |
userJourney | UserJourney | false | The UserJourney details. |
location | Location | false | The Location details. |
val container = ApplicationContainer("456", "Movies")
val playbackSource = PlaybackSource(PlaybackSourceType.CAROUSEL)
// For MiscellaneousContent
val contentInfo = MiscellaneousContent("12345", "movie", "Sample Content")
// For SportContent
val contentInfo = SportContent("1234", "sport_show")
// For TVShow
val contentInfo = TVShow("2345", "Magic Show", "1", "5")
val userJourney = UserJourney(
pageID = "Home",
tabID = "platform",
prefDownloadOnWifiOnly = false
)
val location = Location(
postalCode = "987650",
latitude = 1.29345F,
longitude = 23.3454F
)
val downloadRequest = DownloadRequest(contentInfo, playbackSource, container, userJourney, location)
downloadSession.start(downloadRequest)
Download events that are auto-captured by library itself
Name | Description |
---|---|
download_prepared | This event is reported when a download is prepared |
download_started | This event is reported when a download is started |
download_inprogress | This event is reported when a download is in progress |
download_paused | This event is reported when a download is paused |
download_resumed | This event is reported when a download is resumed |
download_stopped | This event is reported when a download is stopped |
download_completed | This event is reported when a download is completed |
download_deleted | This event is reported when a download is deleted |
DownloadSession
will continue using DownloadRequest
data for all events.
But for already downloaded content(in past application sessions), SDK don't hold any data.
So, to initiate events for it, like resume/pause/delete downloads, client application is
require to set necessary data to report events.
To send such data, call DownloadSession.updateDownloadRequest()
.
val downloadSession = applicationSession.createDownloadSession(contentUrl)
downloadSession.updateDownloadRequest(
DownloadRequest(
content,
playbackSource,
userJourney = UserJourney(
pageID = "Home",
tabID = "platform",
prefDownloadOnWifiOnly = false
),
location = Location(
postalCode = "987650",
latitude = 1.29345F,
longitude = 23.3454F
)
)
)
Report Custom Events
ApplicationSession
provides an API to report custom events. The library provides MiscellaneousEvent
names for the client application to reuse.
val customEvent = CustomEvent("sample_event", mapOf("key" to "value"))
appSession.addEvent(customEvent)
- 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"
- In datazoom, any custom event will be reported as event name with
custom_
prefix. (eg: playback_start as custom_playback_start)
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
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.
appSession.addMetadata(
mapOf("key" to "value")
)
Update Application custom metadata
ApplicationSession
provides an API if the application wants to change any application level attribute at any point of time during the application session.
Example: If the application wants to report the changeable language that it is rendering in, a key - value pair denoting the information can be added using this method. If the language is updated at any point of time during the session, this change can be reflected using below API.
appSession.updateMetadata(
mapOf("catalogue_selected" , "English")
)
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, null)
Download Errors
Any Download error can be reported using below API. Send Error to report download stop on any error.
downloadSession.stop(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
Name | Type | Required | Description |
---|---|---|---|
code | String | true | The unique error code. |
message | String | true | The message describing the error. |
description | String | false | The contextual description of the error. |
val userError = UserError("<error-code>", "user action failure")
val user = User(UserType.SUBSCRIBED)
userSession.addErrorEvent(userError, user)
Out-of-box Player Metrics
Click to know more about out-of-box player reporting 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
-
Playback Startup Time
- Playback startup time is the time taken for player to start the playback measured from the moment playback was requested. -
BufferedRange
- The accumulated duration of the media downloaded in the buffer so far (ratio of currentPosition and bufferedDuration). -
BufferPercentage
- Returns an estimate of the percentage in the current content window or ad up to which data is buffered. -
DecodedFrameRate
- Provides number of frames being decoded (the average bandwidth in bits per second). -
DisplayedFrameRate
- Provides number of Frames being displayed (per second). -
DroppedDecodedFrameCount
- Provides the number of frames that could not be decoded. -
DroppedDisplayableFrameCount
- Provides the number of displayable frames that could not be displayed. -
AudioDecoderInfo
- Provides the audio codec type and name used by player. -
VideoDecoderInfo
- Provides the video codec type and name used by player. -
ObservedBandwidth
- Provides the Observed bandwidth. -
BandwidthEstimate
- Provides the player's current estimate bandwidth. -
VariantSwitchCount
- The number of times video/audio variant switch based on network bandwidth.
The Quickplay Player's StreamInformation
and NetworkInformation
classes provides all metric info required. For more information please refer sample app.
class MetricsOverlayView(context: Context) : Player.AuxiliaryListener {
override fun onNetworkInfoChanged(networkInfo: NetworkInformation) {
// access here all networkInfo metrics related to playback
}
override fun onStreamInfoChanged(streamInfo: StreamInformation) {
// access here streamInfo metrics related to playback
}
}