ExoPlayer: What It Is, Features and Setup

Author: IT Sectr Published: 2026-05-23 Reading time: 8 min

ExoPlayer is an open-source media player library for Android developed by Google as an alternative to the built-in MediaPlayer. ExoPlayer provides audio and video playback in various formats, including DASH, HLS, SmoothStreaming and regular media files, through a single API with support for adaptive streaming. According to Google I/O (2024), ExoPlayer is used in over 60,000 Android applications, including YouTube, Google TV and Netflix.

Key Takeaways

  • ExoPlayer — an open-source media player library for Android from Google.
  • Cross-platform formats — ExoPlayer supports DASH, HLS, SmoothStreaming and RTSP through a modular extension system.
  • Customization — every player component (renderer, data source, DRM) can be replaced with a custom implementation.
  • Canvas and Compose — ExoPlayer integrates with both the traditional View approach (SurfaceView) and Jetpack Compose.
  • DRM — support for Widevine, PlayReady and ClearKey through a modular DRM system.

What is ExoPlayer?

ExoPlayer is an open-source (Apache 2.0) multimedia playback library for Android, whose first version was released by Google in 2014. Unlike the built-in MediaPlayer, which is a thin wrapper over the system media codec (MediaCodec), ExoPlayer is implemented entirely at the Java/Kotlin level, giving developers full control over every stage of playback.

Architecturally, ExoPlayer is built on a modular principle: each aspect of playback is implemented by a separate component. The core module (exoplayer-core) contains the player, renderers, track selectors and buffer management. Additional modules (exoplayer-dash, exoplayer-hls, exoplayer-rtsp, exoplayer-smoothstreaming) add support for the corresponding streaming protocols. This architecture allows applications to include only the necessary components, minimizing APK size.

ExoPlayer 2 (the current major version) was released in 2018 and brought a radical API overhaul: introduction of the Player Interface, Compose support through AndroidX Media3, improved error handling and adaptive track selection algorithms. Starting from version 2.19 (2024), ExoPlayer became part of the AndroidX Media library, simplifying integration and updates through the standard Android dependency manager.

ExoPlayer Architecture

At the core of ExoPlayer lies the ExoPlayerImpl component, which manages the playback lifecycle. It contains MediaSource (media source), TrackSelector (track selection), LoadControl (buffering management) and a list of Renderer (renderers for video, audio, subtitles and metadata). Each component can be replaced with a custom implementation through Builder or factory methods.

For video rendering, ExoPlayer uses SurfaceView, TextureView or SphericalSurfaceView (for 360-degree video). The recommended option is SurfaceView, as it provides hardware acceleration and minimal power consumption. For Jetpack Compose, the AndroidX Media3 library provides the `AndroidView` component, wrapping SurfaceView, and the experimental `Media3Compose` with native Compose integration.

ExoPlayer Features

ExoPlayer provides a wide range of features beyond a regular media player. Key capabilities include support for all popular streaming protocols, a flexible DRM system, adaptive bitrate switching (ABR) and playback analytics tools.

FeatureDescriptionModule
DASHAdaptive streaming per MPEG standardexoplayer-dash
HLSHTTP Live Streaming from Appleexoplayer-hls
SmoothStreamingAdaptive streaming from Microsoftexoplayer-smoothstreaming
RTSPReal-Time Streaming Protocol for liveexoplayer-rtsp
WidevineDRM content protectionexoplayer-drm
ConcatenationMerging multiple media filesexoplayer-core
AdsIMA SDK integration for advertisingexoplayer-ima

Adaptive Bitrate Switching

ABR (Adaptive Bitrate) in ExoPlayer is implemented through the AdaptiveTrackSelection interface. By default, AdaptiveTrackSelectionFactory is used, which creates DefaultAdaptiveTrackSelection — a balanced algorithm that takes into account network bandwidth and buffer size. For specific scenarios, alternative implementations can be plugged in: BOLA (minimizing switches), RandomAdaptiveTrackSelection (testing) or a custom implementation through the TrackSelection interface.

BandwidthMeter — another key component responsible for measuring network bandwidth. By default, DefaultBandwidthMeter is used, which collects statistics on all HTTP requests from the player. The developer can extend it to account for additional factors: network type (Wi-Fi, 4G, 5G), cell tower signal or data cost for the user.

DRM and Content Protection

ExoPlayer supports Widevine (L1, L3), PlayReady and ClearKey DRM. License acquisition is configured through DrmSessionManager, which interacts with the license server. For premium video (4K HDR), hardware support for Widevine L1 is required, which provides chip-level protection and prevents screen capture. The choice of DRM system depends on the target platform: Widevine is used on Android and Chromecast, PlayReady on Xbox and Windows, FairPlay on iOS and Apple TV. ExoPlayer automatically determines the available DRM system based on the MPD file and does not require manual configuration for basic scenarios.

How to Integrate ExoPlayer into an Android Project

Connecting ExoPlayer to an Android project is done through Gradle dependencies. Starting from version 2.19, ExoPlayer is part of AndroidX Media (androidx.media3), ensuring compatibility with Jetpack Compose and other AndroidX components. Let's look at a step-by-step integration in Kotlin.

Adding Dependencies

Add ExoPlayer modules to the build.gradle file (Module). The minimum set includes core, ui and the module for the required streaming protocol. For DASH content playback, exoplayer-dash is required, for HLS — exoplayer-hls.

groovy
dependencies {
    implementation "androidx.media3:media3-exoplayer:1.5.0"
    implementation "androidx.media3:media3-ui:1.5.0"
    implementation "androidx.media3:media3-exoplayer-dash:1.5.0"
    implementation "androidx.media3:media3-exoplayer-hls:1.5.0"
}

Basic Integration in Activity

Creating and configuring the player in an Activity or Fragment. ExoPlayer uses PlayerView (or StyledPlayerView for customization) to display video and built-in controls. The minimum configuration includes creating the player via ExoPlayer.Builder and passing a MediaItem with the source URI.

kotlin
class PlayerActivity : AppCompatActivity() {

    private var player: ExoPlayer? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_player)

        player = ExoPlayer.Builder(this).build()
        val playerView = findViewById<StyledPlayerView>(R.id.playerView)
        playerView.player = player

        val mediaItem = MediaItem
            .Builder()
            .setUri("https://example.com/video.mp4")
            .build()
        player?.setMediaItem(mediaItem)
        player?.prepare()
    }

    override fun onDestroy() {
        player?.release()
        super.onDestroy()
    }
}

Error Handling and States

For production applications, handling of possible playback errors is necessary: network failures, unsupported formats, DRM licensing errors. ExoPlayer provides the Player.Listener interface with methods onPlayerError, onPlaybackStateChanged and onPlayWhenReadyChanged. It is recommended to show users informative error messages with a retry option.

ExoPlayer vs MediaPlayer: Comparison

Choosing between ExoPlayer and the built-in MediaPlayer is a common question when developing Android applications. MediaPlayer has been part of the Android SDK since version 1.0, while ExoPlayer is a library that requires Gradle dependency. Let's look at their differences across key criteria.

CriterionExoPlayerMediaPlayer
ArchitectureModular, entirely in Java/KotlinWrapper over system C++ components
StreamingDASH, HLS, SmoothStreaming, RTSPLocal files only and HLS (Android 9+)
CustomizationFull (any component replaceable)Minimal (parameters only)
UpdatesVia Google Play or APK (OS independent)Only via Android update (OTA)
APK Size+1–3 MB (depending on modules)0 (part of OS)
Min SDKAPI 16+ (Android 4.1)API 1+
DRMWidevine, PlayReady, ClearKeyWidevine (limited)

ExoPlayer wins in scenarios requiring streaming (DASH, HLS), UI customization, DRM support and independence from Android version. MediaPlayer is suitable for simple applications playing local media files where APK size is critical and there are no adaptive streaming requirements. For modern applications with content from the network, ExoPlayer is the clear choice.

Exception — applications with a minimum SDK below API 16 (Android 4.1), which are practically non-existent on the market. For all applications with targetSdk 33+ and minimum SDK 21+, ExoPlayer is not only preferable but necessary for supporting modern formats such as AV1 and Dolby Vision through appropriate extensions.

Advanced ExoPlayer Configuration

For production applications, basic ExoPlayer integration often requires additional configuration: cache management, buffer optimization for mobile networks, analytics integration and audio track selection customization. Let's look at advanced usage scenarios.

Content Caching

CacheDataSourceFactory allows caching downloaded segments to local storage, saving traffic on repeat viewing and enabling offline playback. ExoPlayer uses SimpleCache from the exoplayer-cas library — file-based caching with LRU eviction support and size limits.

kotlin
val cache = SimpleCache(
    cacheDir,
    LeastRecentlyUsedCacheEvictor(50 * 1024 * 1024),
    AppDatabaseProvider(this)
)

val cacheDataSourceFactory = CacheDataSource
    .Factory()
    .setCache(cache)

val player = ExoPlayer.Builder(this)
    .setMediaSourceFactory(
        DefaultMediaSourceFactory(cacheDataSourceFactory)
    )
    .build()

Network Switching Handling

In mobile applications, handling network switching between Wi-Fi and cellular is critical. ExoPlayer provides ConnectivityManager for tracking network state. Upon connection loss, it is recommended not to stop the player but to switch it to PAUSED state while preserving the position. After connection is restored, resume playback with segment reloading.

Jetpack Compose Integration

With the release of AndroidX Media3, the library gained experimental support for Jetpack Compose. The `AndroidView` component wraps SurfaceView or PlayerView, ensuring compatibility with the Compose hierarchy. For deeper integration, the `androidx.media3:media3-ui-compose` library is used, providing Compose-compatible player controls.

kotlin
@Composable
fun VideoPlayer(uri: String) {
    val context = LocalContext.current
    val player = remember {
        ExoPlayer.Builder(context).build()
            .also { it.setMediaItem(MediaItem.fromUri(uri)) }
    }

    DisposableEffect(key = null) {
        player.prepare()
        onDispose { player.release() }
    }

    AndroidView(
        factory = { StyledPlayerView(context).also { it.player = player } }
    )
}

Frequently Asked Questions

What is the minimum Android version for ExoPlayer?

ExoPlayer supports Android API 16+ (Android 4.1 Jelly Bean). However, for DASH and HLS with fMP4 segments, API 21+ (Android 5.0 Lollipop) is recommended. DRM modules (Widevine) require API 19+, and hardware HEVC decoding is available from API 21.

Can ExoPlayer be used for audio without video?

Yes, ExoPlayer is excellent for audio. For audio-only playback, SurfaceView or PlayerView is not required. ExoPlayer will automatically select the audio renderer and work in the background. For background playback, it is recommended to use MediaSessionService for integration with system controls.

How to switch between audio tracks in ExoPlayer?

The TrackSelector in ExoPlayer manages audio track selection. To switch tracks, use player.getCurrentTracks().groups and player.setTrackSelectionParameters() specifying the preferred audio language. For DASH and HLS streams with multiple audio tracks, switching occurs without playback interruption.

Does ExoPlayer support subtitles?

Yes, ExoPlayer supports embedded (in MP4, WebM containers) and external subtitles in TTML, SRT, VTT and CEA-608 formats. For external subtitles, SingleSampleMediaSource or MergingMediaSource is used to merge with the video stream. Styled subtitle display is configured through CaptionStyleCompat.

How to reduce latency in live streaming with ExoPlayer?

For Low-Latency streaming, configure LoadControl with smaller target buffer values: use DefaultLoadControl.Builder().setTargetBufferBytes(1024 * 512).setBufferDurationsMs(500, 2000, 500, 1000) for HLS LL and DASH LL. Also set minPlaybackSpeed = 1.02 for accelerated buffer filling when behind the live broadcast.

Summary

  • ExoPlayer — an open-source media player library from Google with modular architecture and full customization.
  • Adaptive streaming — supports DASH, HLS, SmoothStreaming and RTSP through a modular extension system.
  • DRM — Widevine, PlayReady and ClearKey integrate through the exoplayer-drm module with a unified API.
  • Caching — SimpleCache enables offline playback and saves traffic on repeat viewings.
  • Compose — starting from AndroidX Media3, ExoPlayer integrates with Jetpack Compose through AndroidView.
  • Customization — every component (MediaSource, TrackSelector, LoadControl, Renderer) can be replaced.
  • Recommended to use ExoPlayer for all projects requiring streaming, DRM or playback customization.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also