Android Collector Migration Guide from API v2 to v3

We introduced our new v3 API with breaking changes. Together with the major version release, we also integrated our Analytics collector directly into Bitmovin Player (starting with player version 3.41.0).

This guide explains how to migrate from our v2 collector to the new v3 API which is pre-integrated into the Bitmovin Player. This guide also explains how to migrate our ExoPlayer collector to the latest API.

For more information about the reason behind these changes see Native Collector API v3.

Overview of changes

Bitmovin Player introduced a new Analytics API to simplify the setup and configuration of Analytics.

All public data classes used by the v3 API have been moved into the package com.bitmovin.analytics.api and are immutable.

The old BitmovinAnalyticsConfig is now split within AnalyticsConfig, holding all config information, and DefaultMetadata and SourceMetadata which holds metadata to enrich the analytics data. DefaultMetadata contains source independent metadata (e.g.: customUserId) and SourceMetadata contains source related metadata.

SourceMetadata moved to different package, is immutable and has a customData object with all customData fields (customData1-30).

Old Collector classes with constructors are deprecated and should be replaced by the player-specific factories.

Migrating to the new API

Bitmovin Player

Starting with version 3.41.0, the Bitmovin Player for Android includes Analytics out of the box.
This section describes how to migrate from the standalone v2 Analytics collector to the pre-integrated collector in the Player.

Step 1: Remove dependency to standalone collector

The player has a direct dependency on the analytics collector, and therefore there's no explicit dependency to the collector needed anymore.

- implementation "com.bitmovin.analytics:collector:2.18.0"

Step 2: Move to the integrated collector

Configure Player with Analytics and remove the standalone collector

The new configuration class AnalyticsConfig only contains behavioural settings for the collector, and no metadata. For a minimal setup, only the analytics license needs to be specified. The integrated analytics simplifies usage compared to the standalone collector since there is no explicit attaching and detaching needed anymore.

- val collector = BitmovinPlayerCollector(bitmovinAnalyticsConfig, appContext)
+ val analyticsConfig = AnalyticsConfig(licenseKey = "<YOUR ANALYTICS LICENSE KEY>")
+ val player = Player(
+	  context = appContext, 
+	  playerConfig = PlayerConfig(), 
+	  analyticsConfig = AnalyticsPlayerConfig.Enabled(analyticsConfig)
+ )

- collector.attach(player)
- collector.detach()

Move metadata from BitmovinAnalyticsConfig to SourceMetadata and add it to the source

- val bitmovinAnalyticsConfig = BitmovinAnalyticsConfig(analyticsKey)
- bitmovinAnalyticsConfig.title = "example title"
- bitmovinAnalyticsConfig.videoId = "exampleVideoId"
- bitmovinAnalyticsConfig.path = "bitmovin.ExampleActivity"
- bitmovinAnalyticsConfig.cdnProvider = "testCdnProvider"
- bitmvoinAnalyticsConfig.isLive = true
- bitmovinAnalyticsConfig.experimentName = "experiment-1"
- bitmovinAnalyticsConfig.customData1 = "exampleData1"
- bitmovinAnalyticsConfig.customData2 = "exampleData2"
- bitmovinAnalyticsConfig.customData3 = "exampleData3"

+ val customData = CustomData(
+   customData1 = "exampleData1",
+   customData2 = "exampleData2",
+   customData3 = "exampleData3",
+   experimentName = "experiment-1",
+ )
	
+ val sourceMetadata = SourceMetadata(
+   title = "example title",
+   videoId = "exampleVideoId",
+   path = "bitmovin.ExampleActivity",
+   cdnProvider = "testCdnProvider",
+   isLive = true,
+   customData = customData
+ )
                  
+ val source = Source(sourceConfig, sourceMetadata)

Move metadata from BitmovinAnalyticsConfig to DefaultMetadata

Metadata that is independent of the source can be set through the DefaultMetadata parameter when creating the player. If certain fields are specified in both, SourceMetadata and DefaultMetadata (e.g.: customData1, experimentName, cdnProvider), SourceMetadata takes precedence.

- val bitmovinAnalyticsConfig = BitmovinAnalyticsConfig(analyticsKey)
- bitmovinAnalyticsConfig.customUserId = "exampleUserId"
- bitmovinAnalyticsConfig.customData4 = "appVersion_4.0"
	
+ val defaultMetadata = DefaultMetadata(
+   customUserId = "exampleUserId",
+   customData = CustomData(customData4 = "appVersion_4.0")
+ )
                  
+ val player = Player(
+	  context = appContext, 
+	  playerConfig = PlayerConfig(), 
+	  analyticsConfig = AnalyticsPlayerConfig.Enabled(analyticsConfig, defaultMetadata),
+ )

Use the Player API to modify CustomData

// changing of customData on currently active source
- collector.customData = collector.customData.copy(customData1 = "newValue")
+ player.source?.analytics?.let {
+		it.customData = it.customData.copy(customData1 = "newValue")
+ }

// sending of a "customDataChanged" event
- collector.sendCustomDataEvent(customData)
+ player.analytics?.sendCustomDataEvent(customData)

ExoPlayer

Replace BitmovinAnalyticsConfig with AnalyticsConfig

The new configuration class AnalyticsConfig only contains behavioural settings for the collector, and no metadata. For a minimal setup, only the analytics license needs to be specified.

- val config = BitmovinAnalyticsConfig(key = "<YOUR_ANALYTICS_LICENSE_KEY>")
+ val config = AnalyticsConfig(licenseKey =  "<YOUR_ANALYTICS_LICENSE_KEY>")

Add DefaultMetadata (Optional)

Metadata that is independent of the source can be set through the DefaultMetadata parameter when creating the player. If certain fields are specified in both objects, SourceMetadata and DefaultMetadata (e.g.: customData1, experimentName, cdnProvider), SourceMetadata takes precedence.

- config.cdnProvider = "exampleCdnProvider"
- config.customerUserId = "exampleCustomUserId"
- config.customData1 = "exampleCustomData1"
+ val defaultMetadata = DefaultMetadata(
+   cdnProvider = "exampleCdnProvider",
+   customUserId = "exampleCustomUserId",
+   customData = CustomData(customData1 = "exampleCustomData1")
+ )

Replace old constructor call with new factory method call

Create the analytics collector with the player specific factory. defaultMetadata is an optional parameter.

- val collector = ExoPlayerCollector(config, applicationContext)
+ val collector = IExoPlayerCollector.Factory.create(applicationContext, config, defaultMetadata)

Move metadata from BitmovinAnalyticsConfig to SourceMetadata (Optional)

The video specific metadata is now provided by SourceMetadata.

- config.videoId = "exampleId"
- config.title = "exampleTitle"
- config.path = "example.Activity"
- config.isLive = true
- config.cdnProvider = "exampleCdnProvider"
- config.customData2 = "exampleCustomData2"
+ val sourceMetadata = SourceMetadata(
+   videoId = "exampleId",
+   title = "exampleTitle",
+   path = "example.Activity",
+   isLive = true,
+   cdnProvider = "exampleCdnProvider",
+   customData = CustomData(customData2 = "exampleCustomData2")
+ )

+ collector.sourceMetadata = sourceMetadata

Appendix: Mappings

Classes

Config and Metadata classes

v2v3
com.bitmovin.analytics.BitmovinAnalyticsConfigcom.bitmovin.analytics.api.AnalyticsConfig
com.bitmovin.analytics.api.DefaultMetadata
com.bitmovin.analytics.api.SourceMetadata
com.bitmovin.analytics.data.CustomDatacom.bitmovin.analytics.api.CustomData

Interfaces / Factories

v2v3
com.bitmovin.analytics.bitmovin.player.IBitmovinPlayerCollectorcom.bitmovin.analytics.bitmovin.player.api.IBitmovinPlayerCollector
com.bitmovin.analytics.exoplayer.IExoPlayerCollectorcom.bitmovin.analytics.exoplayer.api.IExoPlayerCollector

Fields

Config

v2 BitmovinAnalyticsConfigv3 AnalyticsConfig
keylicenseKey
adsadTrackingDisable
randomizeUseridrandomizeUserId
config.tryResendDataOnFailedConnectionretryPolicy = RetryPolicy.SHORT_TERM
config.longTermRetryEnabledretryPolicy = RetryPolicy.LONG_TERM
backendUrlbackendUrl
playerKeyremoved (autodetected)

Metadata

DefaultMetadata

v2 BitmovinAnalyticsConfigv3 DefaultMetadata
cdnProvidercdnProvider
customUserIdcustomUserId
customData1 - customData30customData object with customData1 - customdata30
experimentNamecustomData object with experimentName

SourceMetadata

v2 BitmovinAnalyticsConfigv3 SourceMetdata
titletitle
videoIdvideoId
pathpath
isLiveisLive
cdnProvidercdnProvider
customData1 - customData30customData object with customData1 - customdata30
experimentNamecustomData object with experimentName
mpdUrl', progUrl and m3u8Urlremoved (autodetected)

Methods

All Collectors

v2v3
collector.addDebugListener(listener)removed
collector.removeDebugListener(listener)removed

Bitmovin Player Collector / Player Integrated Analytics

v2v3
collector.customData = newCustomDataplayer.source?.analytics?.customData = newCustomData
collector.sendCustomDataEvent(customDataplayer.analytics?.sendCustomDataEvent(customData)
collector.impressionIdplayer.analytics?.impressionId
collector.userIdplayer.analytics?.userId