Exoplayer: What Is It, Usage & More

What is Exoplayer?

ExoPlayer is an open-source library developed by Google for playing media on Android devices. It provides an alternative to Android’s MediaPlayer API for more robust media playback capabilities. ExoPlayer supports features like Dynamic Adaptive Streaming over HTTP (DASH), SmoothStreaming, and Common Encryption.

ExoPlayer is designed to be highly extensible and customizable. It uses a modular architecture that separates components for media playback into different classes like track selection, media sources, loaders, and renderers. This allows developers to swap out components or extend functionalities as needed. Some key advantages of ExoPlayer include:

  • Adaptive bitrate streaming support for better performance
  • Customizable UI and playback logic
  • Easy integration of ads, subtitles, and multiple audio tracks
  • Stable and consistent playback experience
  • Regular updates and optimization from Google

In summary, ExoPlayer provides a robust media playback framework for Android apps to deliver high-quality video and audio streaming with advanced customization options compared to MediaPlayer.

Exoplayer Architecture

Exoplayer has a modular architecture that separates media playback functionality into components (according to https://exoplayer.dev/glossary.html). The main components are:

  • MediaSource – Loads media data.
  • Renderers – Consume media data and output it.
  • TrackSelector – Selects tracks provided by the MediaSource.

The MediaSource loads media data using Extractors and feeds it to the Renderers via MediaPeriods. The Renderers consume the media samples and render audio, video or text outputs. The TrackSelector evaluates the available tracks and selects the optimal combination to play (according to http://freepine.blogspot.com/2015/12/exoplayer-architecture.html).

This separation of concerns allows building highly customized playback experiences by swapping in different implementations of each component.

Key Exoplayer Features

ExoPlayer is packed with advanced features that make it a powerful media player library for Android. Here are some of the key capabilities:

Adaptive streaming support – ExoPlayer has built-in support for adaptive streaming protocols like HLS, DASH, and SmoothStreaming. This allows playing media streams that adjust quality to match changing network conditions. The library handles buffering, switching between different quality levels, and other complexities behind the scenes. ExoPlayer automatically selects the optimal quality stream for the available bandwidth.[1]

Media formats/codecs support – ExoPlayer supports a wide range of media formats and codecs out of the box, including MP4, MPEG-TS, FLV, WebM, MP3, AAC, Ogg Vorbis, and more. The modular ExoPlayer core allows extending support to additional formats via plugin components.[2]

UI customization and extensibility – ExoPlayer provides ample flexibility for customizing the look and feel of the media player UI. Callbacks allow monitoring events like state changes, errors etc. to update the UI accordingly. The library itself handles media playback while developers can focus on building the UI and custom logic.[3]

With these capabilities, ExoPlayer provides full control over the playback experience while handling the complex media operations under the hood.

[1] https://jounggj.github.io/product/exoplayer/features/
[2] https://medium.com/@rohitsaini3342/demystifying-exoplayer-unleashing-android-multimedia-capabilities-ebce0be0a591
[3] https://tudip.com/blog-post/what-is-exoplayer-and-which-is-the-best-player-for-live-streaming-in-android/

Setting Up Exoplayer

Getting started with Exoplayer involves adding the necessary dependencies and creating an Exoplayer instance.

To add Exoplayer to your Android project, you’ll need to add the following dependencies in your app’s build.gradle file:

implementation 'com.google.android.exoplayer:exoplayer:2.X.X'
implementation 'com.google.android.exoplayer:exoplayer-core:2.X.X'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.X.X' 
implementation 'com.google.android.exoplayer:exoplayer-ui:2.X.X'

Be sure to replace 2.X.X with the latest stable Exoplayer version.

Once the dependencies are added, you can create a new instance of Exoplayer in your activity or fragment like so:

val player = SimpleExoPlayer.Builder(context).build()

This will give you a basic Exoplayer instance to start working with. Additional configuration can be done on the Builder before calling .build().

That covers the basics of getting Exoplayer set up in your Android app!

Preparing Media Sources

ExoPlayer supports playing both progressive and adaptive media sources. Progressive sources include local files or network streams with a single quality level. Adaptive sources contain multiple quality levels that allow the player to adjust streaming quality based on factors like network conditions.

To set up a progressive media source, you can simply construct a ProgressiveMediaSource object by passing in a DataSource and Extractor for the media. For example:

ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(url));

For adaptive sources like DASH or HLS, ExoPlayer provides prebuilt factories like DashMediaSource.Factory and HlsMediaSource.Factory to generate the necessary media sources. You can initialize these with any required options like drm session managers.

When dealing with DRM-protected content, make sure to provide the required key request generators, drm session managers, and optional provisioning managers. ExoPlayer makes working with Widevine DRM straightforward.

The MediaSource objects prepared here can then be passed to a SimpleExoPlayer instance to kick off playback.

Configuring Renderers

Exoplayer has built-in renderers for video, audio and text. The VideoRenderer handles decoding and rendering video frames. The AudioRenderer handles audio decoding and output. The TextRenderer handles text output like captions and subtitles. These renderers can be configured on the ExoPlayer instance:

For example:

player = ExoPlayerFactory.newSimpleInstance(
  new DefaultRenderersFactory(context)

This configures Exoplayer with the default video, audio and text renderers. Custom renderers can also be implemented by extending BaseRenderer or SimpleExoPlayer.Renderer. Custom implementations allow handling non-standard media formats or custom outputs.

For example, a customized VideoRenderer could decode a proprietary video format. Or an AudioRenderer could output to a sound visualization library instead of the standard Android audio APIs.

Building a Player UI

ExoPlayer provides several view components that can be used to build the player UI, such as PlaybackControlView for the playback controls. You can include these components in your activity or fragment layouts to quickly put together a functioning video player.

While ExoPlayer’s built-in components provide a good starting point, most apps will want to customize the UI and controls to fit their brand and design. This can be done by extending ExoPlayer’s view classes like PlaybackControlView and overriding methods to tweak the behavior and layout. You can also build your own custom UI from scratch using ExoPlayer’s Player interface.

Some examples of customizing the player UI include:

  • Changing control icons and button styles
  • Adding or removing certain controls like the fast forward button
  • Customizing control positioning and sizing
  • Implementing a completely custom layout and design

When customizing the UI, the ExoPlayer documentation recommends extending the built-in views rather than building from scratch. This allows you to retain needed functionality while swapping out the views and resources.

Handling Playback State Changes

To receive notifications about playback state changes in ExoPlayer, you need to add a PlaybackListener when initializing the player. The PlaybackListener will be invoked whenever the player’s state changes. This lets you update your app’s UI based on what’s happening in the player.

Some key methods you may want to implement in your PlaybackListener include:

  • onPlaybackStateChanged() – Called whenever the playback state changes, like when playback transitions from idle to playing.
  • onPlayerError() – Invoked when an error occurs during playback. You can handle the error here.
  • onPositionDiscontinuity() – Called when playback is disrupted, like during a seek. You may need to adjust the UI.

When handling playback state changes, it’s important to update your app’s UI to match the player’s current state. For example, you’ll want to show the play icon when playback is paused and hide it when the video is playing. Implementing PlaybackListener allows you to keep your UI in sync.

Properly handling playback errors is also crucial to provide a good user experience. When onPlayerError() is called, you may want to alert the user, take an action like restarting playback, or enable retry logic in your app.

By listening to ExoPlayer’s playback state changes and errors, you can build a robust video player app that gracefully handles all playback situations.

Advanced Customization

ExoPlayer offers extensive customization options to tailor the player experience. Some key areas of customization include:

Format Support

ExoPlayer supports a wide range of media formats out of the box, including HLS, MPEG-DASH, SmoothStreaming, RTMP, and more. Developers can further extend format support by implementing custom loaders and decoders via the ExoPlayer core media rendering interfaces.

For example, ExoPlayer’s modular design allowed the creator of the NTP timeshift extension to add support for playing HLS streams with server-side timeshift. This highlights ExoPlayer’s flexibility to handle advanced media formats.

Quality Selection

ExoPlayer provides APIs to list available tracks and override the default adaptive selection logic. Developers can build customized track selection algorithms and UI based on application requirements.

Some customizations around quality selection include adding abr algorithms optimized for fast startup or highest bandwidth, restricting selections to save data, or preferring higher quality audio.

Analytics Integration

ExoPlayer emits numerous events across playback, loading, errors which can be hooked to integrate analytics and monitoring. Developers can track metrics like startup time, rebuffering, bitrates, errors to tune performance.

Plugins exist to integrate ExoPlayer with analytics platforms like IMA and Nielsen. The flexible APIs allow adding any analytics provider.

Exoplayer vs Alternatives

ExoPlayer is commonly compared to Android’s MediaPlayer and VideoView classes when building media playback into apps. Here’s how ExoPlayer compares:

Comparison with MediaPlayer

ExoPlayer has several advantages over MediaPlayer:

  • Supports advanced features like adaptive streaming and Timed Metadata Tracks
  • Easier to customize and extend playback logic
  • Handles orientation changes and background audio playback better

However, ExoPlayer also has some downsides according to developers:

  • “One key disadvantage is that when using audio only, ExoPlayer uses significantly more battery than MediaPlayer” (Source)
  • Higher memory usage due to buffering streams
  • More complex setup and configuration

Comparison with VideoView

Compared to VideoView, ExoPlayer:

  • Supports many more media formats and streaming protocols
  • Much more customizable and extensible
  • Higher FPS and smoother playback in tests (Source)

The tradeoff is ExoPlayer requires more setup and optimization to achieve optimal performance.

Leave a Reply

Your email address will not be published. Required fields are marked *