Migrating from ExoPlayer to the Bitmovin Player

In this guide, we will show you how to migrate from ExoPlayer to the Bitmovin Player in just three simple steps.

Step 1: Add & configure your Bitmovin Player

First, add a link to our Maven repository in your application's build.gradle or settings.gradle file. Make sure not to remove the Google Maven repository.

  allprojects {
    repositories {

+     maven {
+       url 'https://artifacts.bitmovin.com/artifactory/public-releases'
+     }

Next, add the Bitmovin Player as a dependency to your project as shown below:

+ implementation 'com.bitmovin.player:player:3.+'

We recommend you use the latest version of our Bitmovin Player. You can find all versions here.

Now, add the Bitmovin Player License Key to your AndroidManifest.xml:

  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />

    <application ... >
        <activity ... />

+       <meta-data android:name="BITMOVIN_PLAYER_LICENSE_KEY" android:value="<PLAYER_LICENSE_KEY>" />


And finally, register the package name of your application in your Bitmovin Dashboard under "Player" -> "Licenses". This security mechanism protects your license from being used elsewhere.

Step 2: Remove the ExoPlayer dependencies

In your Gradle file, remove all ExoPlayer dependencies:

-  implementation com.google.android.exoplayer.*



By default, an application cannot use both the Bitmovin Player and ExoPlayer as they define identical symbols. Thus, it is recommended that you migrate all ExoPlayer instances of your app to the Bitmovin Player.
Alternatively, you can use the Bitmovin +jason variant to use both Players in the same project as described here.

Step 3: Replace ExoPlayer references in your project

User Interface

To migrate the UI, simply replace occurrences of StylePlayerView with PlayerView.
An example:

-  <com.google.android.exoplayer2.ui.StylePlayerView
+  <com.bitmovin.player.PlayerView

Learn how to customize your cross-platform Bitmovin UI here.

Replace ExoPlayer API

The APIs of ExoPlayer and Bitmovin Player are similar in functionality. As a result, the migration is mostly about changing method names and signatures.

Here is an example of creating a new Bitmovin Player:

- val player = ExoPlayer.Builder(context).build()
+ val analyticsConfig = AnalyticsConfig(licenseKey = "<ANALYTICS_LICENSE_KEY>")
+ val player = Player(context, PlayerConfig(), AnalyticsPlayerConfig.Enabled(analyticsConfig))
  this.findViewById(R.id.playerView).player = player
- ExoPlayer player = new ExoPlayer.Builder(context).build();
+ AnalyticsConfig analyticsConfig = new AnalyticsConfig("<ANALYTICS_LICENSE_KEY>")
+ Player player = new PlayerBuilder(context)
+                 .configureAnalytics(analyticsConfig)
+                 .build()

Next, replace occurrences of MediaItem by SourceConfig and load your sources. Here is an example of loading a Dash stream:

  val url = "https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd"
- val mediaItem = MediaItem.Builder()
-         .setUrl(url)
-         .setMimeType(MimeTypes.APPLICATION_MPD) // Dash
-         .build();
- player.setMediaItem(mediaItem)
- player.prepare()
+ val sourceConfig = SourceConfig(url, SourceType.Dash) // or SourceConfig.fromUrl(url) to auto-detect the source type
+ val source = Source(sourceConfig)
+ player.load(source)
  String url = "https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd";
- MediaItem mediaItem = new MediaItem.Builder()
-         .setUrl(url)
-         .setMimeType(MimeTypes.APPLICATION_MPD) // Dash
-         .build();
- player.setMediaItem(mediaItem);
- player.prepare();
+ SourceConfig sourceConfig = new SourceConfig(url, SourceType.Dash); // or SourceConfig.fromUrl(url) to auto-detect the source type
+ Source source = new SourceBuilder(sourceConfig).build();
+ player.load(source);



Android Studio will also support you by flagging errors for any other ExoPlayer code.
To support you with the further migration, we've created mapping tables between the ExoPlayer and Bitmovin Player API, which you can refer to - especially for more advanced use cases.


And that's it!

You're ready to play a video in your application using the Bitmovin Player 😀


In this guide, we demonstrated how easy it is to migrate from ExoPlayer to the Bitmovin Player in just three simple steps: adding the Bitmovin Player, removing the ExoPlayer dependencies and mapping the ExoPlayer API to the Bitmovin Player API.

Next, you can

Appendix: Mapping Tables

For more advanced use cases, we've created the following mapping tables to support your migration.
In comparison, the Bitmovin Player API is written in Kotlin and allows more expressive and terse syntax by using default values whereas ExoPlayer makes heavy use of the builder pattern.



Methods and classes are only listed if their names are different.

Package mapping

ExoPlayerBitmovin Player

Class mapping

ExoPlayerBitmovin Player

ExoPlayer ➡️ Player method mapping

ExoPlayerBitmovin Player
Builder.build()Player or PlayerBuilder.build()
prepareNot needed, done in load
seekTo*See the Seeking section
addMediaItemPlaylistConfig or playlist.add
moveMediaItemplaylist.remove then add
getPlayerErrorSee the Events section

MediaItem ➡️ Source method mapping

ExoPlayerBitmovin Player
MediaItem.setClippingConfigurationNot supported

Additional Notes


ExoPlayer.seekTo(positionMs) (seeking in the current source) is equivalent to:

ExoPlayer.seekTo(mediaItemIndex, positionMs) (seeking in any source of the playlist) is equivalent to:

ExoPlayer has some other seek helper methods to seek in the timeline. (seekForward, seekToDefaultPosition, seekToNextMediaItem, etc.).
When using the Bitmovin Player you can get the seek position using player.currentPosition and player.playlist.


The Bitmovin Player provides an extensive Event Framework. Listening to a Player event is as simple as:

player.on<PlayerEvent.Seek> { seekEvent ->
    // ...
player.on(PlayerEvent.Seek.class, seekEvent ->
    // ...

If you were using exoPlayer.addAnalyticsListener(EventLogger()) to log ExoPlayer events to the logcat, you may use the equivalent described here

For more advanced use cases, take a look at our API documentation for the EventEmitter here.