ExoPlayer 2.11 - What’s new
ExoPlayer 2.11 contains many new features, improvements and bug fixes. This post highlights some of the most significant changes. As always, we recommend also taking a look at the full release notes.
Android 10
ExoPlayer 2.11 is our first release that targets Android 10 (compileSdkVersion = 29
) and exposes support for Android 10 features:
- Android 10 includes a new feature that enables other applications to capture your application’s audio. This feature enables important use cases like Live Captioning, and is described in detail by the Capturing Audio in Android Q blog post. Since allowing audio capture may not be desirable in all cases, it’s possible to specify an audio capture policy that enables or disables capture, or restricts it to system apps. When using earlier versions of ExoPlayer, it was possible to specify a global audio capture policy in your
AndroidManifest.xml
. ExoPlayer 2.11 adds support for specifying the audio capture policy on a per player basis. To do so, configure an AudioAttributes with the desired audio capture policy, and pass it to the player by calling setAudioAttributes. - Android 10 introduces new APIs to
MediaCodecInfo
for querying whether a codec is hardware accelerated, whether it’s software only, and whether it’s provided by the device manufacturer or the Android platform. ExoPlayer 2.11 surfaces this information in its ownMediaCodecInfo
class via newhardwareAccelerated
,softwareOnly
andvendor
flags. These flags are accessible and (in most cases) set correctly even when running on older versions of Android.
In a future release, we also plan to use Android 10’s audio offload functionality. Audio offload allows tunneling of compressed audio to a digital signal processor (DSP) in the device chipset. This moves work from the application processor, which allows it to go to sleep for extended periods during playback. This can result in a significant reduction in power consumption for audio only playback. Stay tuned for more details!
DRM
There are significant changes to DRM in ExoPlayer 2.11. Injecting a DrmSessionManager
when creating an ExoPlayer
instance is now deprecated. DrmSessionManager
instances should now be injected when building MediaSources
, via new setDrmSessionManager
methods that have been added to the MediaSource Factory implementations. We’re aware that this is a painful change to our API, however it’s a change that’s necessary to remove a number of limitations that ExoPlayer currently has:
- The immediate benefit in 2.11 is that it’s now possible for each
MediaSource
in aConcatenatingMediaSource
to use a differentDrmSessionManager
, enabling use cases such as playlists of DRM protected content requiring differentDrmSessionManager
configurations (GitHub issue #5619). - In a future release, it will allow us to request keys in advance of them being needed for playback (GitHub issue #4133). This will allow us to remove the brief pause that currently occurs when a new key is required to during playback (e.g. due to key rotation within a
MediaSource
, or a playlist transition from oneMediaSource
to the next). For adaptive playbacks, it will also allow us to check key statuses within the player on API level 23 and above (GitHub issue #4825), removing the requirement for application code to filter out streams whose keys will be unusable on the playback device.
There are several other improvements to DRM support in this release:
DefaultDrmSessionManager
now has a builder to simplify creating instances.- We now support setting a custom
LoadErrorHandlingPolicy
for key and provisioning requests (GitHub issue #6334). A custom policy can be passed toDefaultDrmSessionManager.Builder.setLoadErrorHandlingPolicy
. - We’ve fixed leaking of
ExoMediaDrm
instances in some cases (GitHub issue 4721).
TrackSelection
We’ve made a number of tweaks to the DefaultTrackSelector
in ExoPlayer 2.11. In particular:
- For adaptive video playbacks where multiple video resolutions are available, we now exclude resolutions that are excessive for the device’s display by default. This helps to avoid unnecessary bandwidth and battery consumption, and can also reduce the probability of playback failure on lower end devices.
ParametersBuilder.clearViewportSizeConstraints
can be used to disable this functionality if you prefer. It’s also possible to specify a custom viewport usingParametersBuilder.setViewportSize
. - For media with subtitles and/or captions, we now query
CaptioningManager
to obtain the user’s device wide accessibility settings, and use them by default when selecting text tracks. TheParametersBuilder
setPreferredTextLanguage
andsetPreferredTextRoleFlags
methods can be used to specify different constraints for text track selection if you prefer.
To get these new default behaviors, it’s important that you update your code to use non-deprecated constructors and methods when obtaining instances of DefaultTrackSelector
, DefaultTrackSelector.Parameters
and DefaultTrackSelector.ParametersBuilder
.
WakeLock and AUDIO_BECOMING_NOISY handling
ExoPlayer 2.11 makes it easier for application developers to do the right thing when playing media on Android. In particular:
- For screen-off playback, we’ve added support for automatic
WakeLock
handling inSimpleExoPlayer
. To enable this feature, just callsetHandleWakeLock(true)
. When enabled, aWakeLock
is held whenever the player is in theREADY
orBUFFERING
states withplayWhenReady = true
. This ensures the device stays awake for playback, even when the screen is off. - The
AUDIO_BECOMING_NOISY
intent can now be handled automatically bySimpleExoPlayer
. To enable this feature, just callsetHandleAudioBecomingNoisy(true)
. Playback will be paused automatically (settingplayWhenReady
tofalse
) whenever the intent is received. - It’s worth reminding you that
SimpleExoPlayer
can also handle audio focus. See the Easy Audio Focus with ExoPlayer blog post for more detail.
AV1
Android 10 includes an AV1 decoder, which previous versions of ExoPlayer could already use to play AV1 video on Android 10 devices. In ExoPlayer 2.11 we’re also introducing an AV1 extension. The AV1 extension bundles libgav1, allowing playback of AV1 video on devices running earlier versions of Android as well. See the Playing AV1 videos with ExoPlayer blog post for more detail.
Analytics
ExoPlayer 2.11 adds a PlaybackStatsListener
that makes it easier to collect common analytics metrics. The listener automatically produces a PlaybackStats
per playlist item, as well as combined stats across multiple playbacks.
- To use
PlaybackStatsListener
, register an instance with the player by callingplayer.addAnalyticsListener(playbackStatsListener)
. You can query the latest stats any time by callinggetPlaybackStats()
andgetCombinedPlaybackStats()
on thePlaybackStatsListener
. ThePlaybackStatsListener.Callback
is notified when the stats become final. PlaybackStats
exposes individual metrics via public fields. It also provides a large number of helpful convenience methods for calculating derived metrics, such asgetRebufferRate()
,getMeanVideoFormatHeight()
andgetTotalPlayTimeMs()
.- When reporting metrics to an analytics backend, we recommend reporting all fields of
PlaybackStats
to retain maximum flexibility for later analysis. Derived metrics can be recomputed in your backend. The source code ofPlaybackStats
shows how each of the derived metrics are calculated.
We hope to publish a more detailed blog post about analytics soon!
And much more
There’s much more to the 2.11 release than just the features highlighted above. Other miscellaneous improvements include:
ExoPlayerFactory
has been replaced with more flexibleSimpleExoPlayer.Builder
andExoPlayer.Builder
classes.- We’ve made it easier to determine whether content being played is a live stream. This can be queried using
Player.isCurrentWindowLive()
. - ExoPlayer’s testutils package is now available via jCenter, making it easier for you to use it in your own tests.
- For DASH playbacks, we now support
@r=”-1"
inSegmentTimeline
S
elements.
See the full release notes for a more comprehensive list.
As always, please feel free to get in touch via our issue tracker if you have any questions or encounter problems. Thanks for reading!