ExoPlayer 2.11 - What’s new

Olly Woodman
AndroidX Media3
Published in
5 min readDec 11, 2019

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 own MediaCodecInfo class via new hardwareAccelerated, softwareOnly and vendor 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 a ConcatenatingMediaSource to use a different DrmSessionManager, enabling use cases such as playlists of DRM protected content requiring different DrmSessionManager 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 one MediaSource 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 to DefaultDrmSessionManager.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 using ParametersBuilder.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. The ParametersBuilder setPreferredTextLanguage and setPreferredTextRoleFlags 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 in SimpleExoPlayer. To enable this feature, just call setHandleWakeLock(true). When enabled, a WakeLock is held whenever the player is in the READY or BUFFERING states with playWhenReady = 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 by SimpleExoPlayer. To enable this feature, just call setHandleAudioBecomingNoisy(true). Playback will be paused automatically (setting playWhenReady to false) 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 calling player.addAnalyticsListener(playbackStatsListener). You can query the latest stats any time by calling getPlaybackStats() and getCombinedPlaybackStats() on the PlaybackStatsListener. The PlaybackStatsListener.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 as getRebufferRate(), getMeanVideoFormatHeight() and getTotalPlayTimeMs().
  • 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 of PlaybackStats 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 flexible SimpleExoPlayer.Builder and ExoPlayer.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" in SegmentTimeline 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!

--

--