Migrate Android SDK

Use this guide to migrate your Player Android SDK from AMP1 to AMP2.

The guide lists specific player features and functions, their AMP1 implementation, and how you should implement them in AMP2 for successful migration.

For a detailed AMP1 vs. AMP2 feature and function mapping with examples, see the following tables:

Additional reference:

1. Set up a project

AMP1 implementation:

  1. With AMP1, you had to add multiple .jar and .aar files into your project. Remove those dependencies.
  2. Remove com.akamai.amp.AmpPlayerView from the desired Activity's XML layout.

AMP2 implementation:

  1. Add a link to the player SDK repository and add the dependency to the project. See the Bitmovin tutorial for more details.
  2. Add com.bitmovin.player.PlayerView to the desired Activity's XML layout.

2. Instantiate the player

AMP1 implementation (docs):

private VideoPlayerContainer videoPlayerContainer;
private VideoPlayerView videoPlayerView;
@Override protected void onCreate(Bundle savedInstanceState) {
	videoPlayerContainer = findViewById(R.id.playerViewCtrl);
	videoPlayerContainer.setApiKey(API_KEY);
}

AMP2 implementation (docs):

val playerConfig = PlayerConfig()
val analyticsConfig = AnalyticsConfig(licenseKey = "<ANALYTICS_LICENSE_KEY>")
val player = Player(context, playerConfig, AnalyticsPlayerConfig.Enabled(analyticsConfig))
val playerView = this.findViewById(R.id.playerView)
playerView.player = player

3. Load an asset

AMP1 implementation (docs):

videoPlayerContainer.prepareResource(HLS_VOD);

@Override public void onResourceReady(MediaResource mediaResource) {
videoPlayerView = videoPlayerContainer.getVideoPlayer();
videoPlayerView.play(mediaResource);
}

AMP2 implementation (doc):

val sourceConfig = SourceConfig.fromUrl(HLS_VOD)
val sourceMetadata = SourceMetadata(title = "Art of Motion", customData1 = "sample data")
val source = Source(sourceConfig, AnalyticsSourceConfig.Enabled(sourceMetadata))
player.load(source)

4. Set up DRM content

AMP1 implementation (docs):

videoPlayerContainer.prepareResource(WIDEVINE_VIDEO_URL, DrmScheme.WIDEVINE, WIDEVINE_LICENSE_URL);

AMP2 implementation (doc):

val sourceConfig = SourceConfig(
	url = TODO("CONTENT_MANIFEST_URL"),
	type = SourceType.Dash,
	drmConfig = WidevineConfig(
		licenseUrl = TODO("LICENSE_URL")
	),
)

5. Set up ad playback

AMP1 implementation (docs):

private AmpIMAManager csaiManager;
csaiManager.setAdsUrl(ADS_URL);
videoPlayerContainer.prepareResource(HLS_VOD);

AMP2 implementation (docs):

val sourceConfig = SourceConfig(
	url = TODO("CONTENT_MANIFEST_URL"),
	type = SourceType.Dash,
	drmConfig = WidevineConfig(
		licenseUrl = TODO("LICENSE_URL")
	),
)

6. Set up a downloader for offline playback

AMP1 implementation (docs):

AmpDownloadManager downloadManager = AmpDownloader.create(ctx,maxParallelDownloads);
ampDownloadManager.startDownload(String name);
ampDownloadManager.deleteDownload(Uri uri);
videoPlayerview.setDownloadRequestProvider(DownloadRequestProvider provider);

AMP2 implementation (docs):

val offlineContentManager = OfflineContentManager.getOfflineContentManager( sourceConfig = SourceConfig.fromUrl(path),
location = getDir("offline", ContextWrapper.MODE_PRIVATE).path,
id = "uniqueID", listener = listener, context = androidContext
)
offlineContentManager.process(offlineContentOptions);
bitmovinPlayer.load(offlineContentManager.offlineSourceConfig);

7. Set up a Google cast support

AMP1 implementation (docs):

ampCastManager = new AmpCAF.Builder(Context).build();
ampCastManager.initCastButton(Context, Menu, MenuItemId);
ampCastManager.showIntroductoryOverlay(Context, MessageString, ColorResLayout);
ampCastManager.getQueueManager();

AMP2 implementation (docs):

BitmovinCastManager.initialize()
BitmovinCastManager.updateContext(context)

8. Set up player events

AMP1 implementation (docs):

videoPlayerView.addEventsListener(new IPlayerEventsListener() {
	@Override
	public boolean onPlayerEvent(int eventID) {
		Log.i(TAG, "AMP Event: " + PlayerEvents.toString(eventID));
		if (PlayerEvents.matches(eventID, IPlayerEventsListener.PLAYER_EVENT_APP_SENT_TO_FOREGROUND)) {
			/* handle app foregrounding */
		}
		return false;
	}

	@Override
	public boolean onPlayerExtendedEvent(int i, int i1, int i2) {
		/* handle extended event */
		return false;
	}
});

AMP2 implementation (docs):

player?.on(PlayerEvent::class.java) { event ->
	when (event) {
		is PlaybackFinished -> { /* handle playback end */ }
		is Error -> { /* handle error */ }
		is TimeChanged -> { /* update progress bar */ }
		// etc.
	}
}

📘

See Event mapping for Android SDK for a complete list of AMP1 vs. AMP2 event mapping.