Benefit from the architectural and performance improvements, along with new features that become available with our new major version 3 of the Android SDK. Learn how to migrate from your current v2 SDK Project to v3 with ease!
Overview
The following points will explain all breaking changes, renamed functions and configuration objects, as well as minimum requirements that need to be fulfilled to migrate and benefit from all the major performance and usability improvements that become available with v3.
V3 of the Android Player SDK marks a new direction where the player itself and the sources it plays back become more decoupled. This allows for sources to have their own lifecycle, emit their own events and offer functionality even when the source is currently not being played back. For more details on how the top-level components fit together in V3, refer to the Player, Source and PlaylistApi documentation.
With this new direction comes the ability to load multiple sources into the player via a PlaylistConfig
. The player will play back one source after another until it reaches the end of the playlist. Sources in the playlist can already preload content before they are being played back, leading to gapless playback across sources without the overhead of unloading and loading a new source like in V2.
As events are a big part of interacting with the SDK, we have also completely reworked how to interact with them. The Player
, Source
and PlayerView
all implement the new EventEmitter
, which offers a more intuitive and flexible way of handling event subscriptions with less boilerplate.
This release also includes improvements like reworked documentation, a better developer experience by including the source-code of the public API and by improving the Maven publishing process, and more.
Minimum Requirements
Supported Android Platforms
- no requirement changes compared to v2
Google Cast
- CAF compatible v3 receiver applications required Learn More
Bitmovin Player UI
v3.25.x
or higher (default and custom versions)
Limitations
- The initial
3.0.0
version does not support loading live-streams inside a playlist. As we can't detect the type until we actually start loading the source there won't be an error when loading a live-stream. Doing so will result in unexpected behavior. - The event migration towards
SourceEvents
isn't finished yet. More events will be migrated to be emitted on a per-source basis over the next releases. See also the API doc for an updated list of the already migrated events. - Suspended offline downloads of individual tracks that were started utilizing
v2
cannot be resumed withv3
when using a version below3.8.1
. Downloads of specific tracks that were started utilizingv2
without using theCompatibilityHelper.PARCELABLE_ACTION_DATA
flag can not be resumed inv3
due to internal changes in the serialization workflow. Trying to resume such a download will result in anIllegalStateException
. This limitation was removed in version3.8.1
.
Package and Dependency Changes
New Maven Artifact ID
The artifactId
of the SDK changed from playercore
to player
. The full dependency is now declared as follows:
// v2
dependencies {
implementation "com.bitmovin.player:playercore:2.65.0"
}
// v3
dependencies {
implementation "com.bitmovin.player:player:3.0.0"
}
Transitive Dependencies
The Maven setup has been reworked to avoid unnecessary dependency leakage. This might force the explicit inclusion of dependencies that are used in the project, but were previously included transitively via the Bitmovin player.
Google Cast Package names
Please see the section Casting for more details.
New package and class names
We have sanitized the package structure used throughout the SDK. This will cause many of the existing imports to break. The easiest way to fix broken imports is to remove the existing imports and re-import the classes while paying attention to possible name changes.
Renamings
There are three general changes in naming conventions that were cleaned up throughout the SDK:
- All configurations were renamed from
*Configuration
to*Config
. E.g.PlaybackConfiguration
is now calledPlaybackConfig
. - All enum entries were renamed from SCREAMING_SNAKE_CASE to PascalCase. E.g.
AdSourceType.UNKNOWN
was renamed toAdSourceType.Unknown
. - All UPPERCASE abbreviations in class names were changed to PascalCase. E.g.
UserInterfaceAPI
was renamed toUserInterfaceApi
.
This table lists all simple name changes from v2
to v3
.
v2 | v3 |
---|---|
BitmovinPlayer | Player |
BitmovinPlayerView | PlayerView |
BitmovinSubtitleView | SubtitleView |
BitmovinPlayerNotificationManager | PlayerNotificationManager |
SourceItem | SourceConfig |
OfflineSourceItem | OfflineSourceConfig |
MediaSourceType | SourceType |
FullscreenHandler.isFullScreen | FullscreenHandler.isFullscreen |
SourceItem.addDrmConfig | SourceConfig.setDrmConfig |
AdaptationConfiguration.isAllowRebuffering | AdaptationConfig.isRebufferingAllowed |
EventHandler.addEventListener | EventEmitter.on (Details) |
EventHandler.removeEventListener | EventEmitter.off (Details) |
Removals
This table lists API which was removed in v3 with its replacements (if any).
v2 | v3 |
---|---|
All deprecated functionality from v2 | the various replacements |
CastConfiguration | RemoteControlConfig |
PlayerAPI | Player |
GoogleCastReceiverVersion | removed without replacement (Details) |
PlayerView constructor that takes a PlayerConfig | PlayerView(Context, Player?) |
PlayerFragment | removed without replacement |
Player.setup | removed without replacement (Details) |
ConfigurationUpdatedEvent | removed as a configuration can't be updated anymore |
PlayerConfiguration.sourceConfiguration | replaced with new loading workflows (Details) |
Configuration interface from all *Config s | removed without replacement |
DRMSystems enum | WiedevineConfig and ClearKeyConfig |
flags parameter from OfflineContentManager.getOfflineContentManager() and BitmovinDownloadService() | not necessary anymore |
fromJson function from PlayerConfiguration and SourceConfiguration | removed without replacement |
JsonConverter | removed without replacement |
Player setup
Configurations
Many configs were refactored to data classes, making it possible to use named parameters instead of creating an empty config and setting values after creation:
v2
val playerConfig = PlayerConfig()
playerConfig.adaptationConfig = AdaptationConfig()
playerConfig.advertisingConfig = AdvertisingConfig()
v3
val playerConfig = PlayerConfig(adaptationConfig = AdaptationConfig, advertisingConfig = AdvertisingConfig)
Instance Setup
While in v2 BitmovinPlayer
was a concrete class that could simply be created using the constructor, in v3 Player
is an interface and PlayerBuilder
has to be used for instance creation.
v2
val player = BitmovinPlayer(context, playerConfiguration)
v3
val player = new PlayerBuilder(context).setPlayerConfig(playerConfig).build()
In addition, we removed the Player.setup
call as well as the ConfigurationUpdatedEvent
, which means that the configuration can't be changed anymore once a player was created.
Loading a Source
SourceConfig
The SourceItem
was renamed to SourceConfig
and the old SourceConfiguration
was removed completely. SourceConfig
from now on refers to the old SourceItem
.
As our old SourceConfiguration
was based on the SourceConfig
from the Web Player SDK there was the possibility to set up multiple configurations for each streaming technology (HLS, Dash ...). We are moving away from this concept starting with v3, therefore we deprecated all the legacy types which were used to set up those different sources, which will be removed in an upcoming minor version:
MediaSource
AdaptiveSource
HLSSource
DASHSource
SmoothSource
ProgressiveSource
The new designated way to create a SourceConfig
is to use the url
and the type
directly in the SourceConfig
constructor:
v2
val sourceConfig = SourceItem(HLSSource(url))
v3
val sourceConfig = SourceConfig(url, SourceType.Hls)
Alternatively, a SourceConfig
can be created by automatically detecting its type from an url:
v2
val sourceConfig = SourceItem("sample.mpd")
v3
val sourceConfig = SourceConfig.fromUrl("sample.mpd")
Source
The Source
is, next to the Player
, the new main component in the SDK. See the documentation for more detailed insights.
To create an instance of a Source
, a SourceConfig
is needed. The SourceConfig
can then be passed to a SourceBuilder
to build a Source
instance.
val source = new SourceBuilder(sourceConfig).build()
To load a Source
into the Player
, a new load function accepting a Source
was added:
val source = new SourceBuilder(SourceConfig.fromUrl("some.mpd")).build()
player.load(source)
If you don't need to handle Source
s explicitly, you can still load a SourceConfig
directly:
val sourceConfig = SourceConfig.fromUrl("some.mpd")
player.load(sourceConfig)
Event handling
We completely reworked how to manage event subscriptions to make it more intuitive and flexible in v3. You can now subscribe to events directly with a lambda or an EventListener<Event>
implementation.
Event listener changes
In v2, addEventListener
and removeEventListener
was called with an event specific EventListener
(e.g. the OnSourceLoadListener
).
In v3, this functionality is now available as on
and off
. Additionally, the event specific listeners were replaced by two approaches that offer idiomatic usage from both Kotlin and Java:
Usage from Kotlin
// Quick fire-and-forget subscription
player.on<PlayerEvent.Ready> { println("Player is ready") }
// Adding a subscriber for an event and removing it later
val onPlayerActive: (PlayerEvent.Active) -> Unit = { println("Player is active") }
player.on(onPlayerActive)
player.off(onPlayerActive)
Usage from Java
// Quick fire-and-forget subscription
player.on(PlayerEvent.Ready.class, event -> System.out.println("Player is ready"));
// Adding an event listener for an event and removing it later
EventListener<PlayerEvent.Active> onPlayerActive = event -> System.out.println("Player is active");
player.on(PlayerEvent.Active.class, onPlayerActive);
player.off(PlayerEvent.Active.class, onPlayerActive);
More details and examples can be found in the EventEmitter
documentation.
Source-specific events
Each Source
can have its own event listeners to notify about changes in the source. To enable that, we split the existing BitmovinPlayerEvent
into PlayerEvent
and SourceEvent
and introduced a separate sealed class hierarchy for both of them.
v2
class BitmovinPlayerEvent { ... }
class ReadyEvent : BitmovinPlayerEvent { ... }
class SourceLoadedEvent: BitmovinPlayerEvent { ... }
v3
sealed class Event { ... }
sealed class PlayerEvent : Event {
class Ready() : PlayerEvent()
}
sealed class SourceEvent : Event {
class Loaded() : SourceEvent()
}
We introduce the new Event
class as the root type for all events. Each SourceEvent
(e.g. SourceEvent.Loaded
) extends SourceEvent
and each PlayerEvent
(e.g. PlayerEvent.Play
) extends PlayerEvent
.
Every SourceEvent
emitted from the currently active Source
will also be emitted through the Player
.
This means that SourceEvent
s of a specific source can be received either on the specific Source
instance directly or on the Player
, if the source is active. In order to receive events for sources that are not active, event listeners must be added to each source directly.
When migrating a v2 workflow, there is naturally only one source which is always active, leading to all source-specific events being emitted trough the player. In general, this eliminates the requirement for listening for source specific events on a Source
in single source use cases.
Listening for source-specific events
In order to listen for SourceEvent
s from a specific source, the same syntax as listening for PlayerEvent
s from the player is applied:
source.on<SourceEvent.Loaded> { ... }
Events related to source loading
The SourceEvent.Loaded
and the SourceEvent.Unloaded
equivalent events in v2 were often used to track the lifecycle of a player. With v3, these events are emitted per source, and also for non-active sources. In order to ensure that existing workflows still produce the expected results, new events for playback session tracking were introduced.
v2 | v3 |
---|---|
SourceLoadedEvent is emitted when the player is about to load a source indicating a source life-cycle has started | PlayerEvent.Active is emitted when the player received one or more sources and has started a playback session |
SourceUnloadedEvent is emitted after the player finished unloading a source indicating that the source life-cycle has finished | PlayerEvent.Inactive is emitted when all sources were removed from the player and the playback session has finished |
Error / Warning codes
WARNING: The integer values of the warning and error codes changed in v3.
Further, error and warning codes were restructured. In previous versions they were represented by plain integers on the respective ErrorCodes
and WarningCodes
classes.
They are now divided in Player
, Source
and Offline
specific codes that are represented by enumerations. See the error and warning code documentation for further details.
The codes are surfaced by ErrorEvent
s or WarningEvent
s that can be a PlayerEvent
, a SourceEvent
as well as an OfflineErrorEvent
.
Casting
Support for Cast Receivers with version 2 (former GoogleCastReceiverVersion.V2
) was dropped. Going forward, only CAF-compatible receivers (former GoogleCastReceiverVersion.V3
) are supported.
Casting package names
Special attention needs to be paid to package paths referenced in AndroidManifest
files as they are easily missed. Be sure to replace the following packages in case you are using cast functionality.
v2 | v3 |
---|---|
com.bitmovin.player.cast.ExpandedControllerActivity | com.bitmovin.player.casting.ExpandedControllerActivity |
com.bitmovin.player.cast.BitmovinCastOptionsProvider | com.bitmovin.player.casting.BitmovinCastOptionsProvider |
UI / View
The new v3 Android SDK isn’t compatible with Bitmovin Player Web UI v2.x
. To use the v3 SDK with a customized Bitmovin Player Web UI you will need to update your Player Web UI version to v3.x
. The recommended version is 3.25.0
and above.
We continue to support Bitmovin Player Web UI v2.x
for use with our v2 Android SDK only. More details on the Bitmovin Player Web UI can be found here.
Examples
We have updated our Android Samples GH Repository as well to get you started with our new major version 3 for Android. Check them out!