
Build a functional Android media playback app from scratch using Media3 Exoplayer and Jetpack Compose. The course requires a few months of Android development experience and familiarity with Jetpack Compose.
Master media playback features using Exoplayer while maintaining a clean, straightforward app interface. Build a solid foundation in general media technologies to effectively use Exoplayer and avoid overemphasizing architecture.
Explore the Android media playback workflow with Media3 ExoPlayer and Jetpack Compose, covering ExoPlayer core, ExoPlayer UI, media session, transformer, ad insertion, and DRM integration.
Download and explore the Media3 source code to run core demo apps, test streams, and learn how to implement dash, hls, smooth streaming, and ad insertion.
Explore the core components of media theory, including Exoplayer core, dash, hls, and ima, plus the media session and Media3 UI widgets for playback control.
Build a simple Android app that plays video with Media3 ExoPlayer in Compose, centering a 16 by nine video surface and wiring surface lifecycle for playback.
Add and configure media playback dependencies for Media3 Exoplayer, including core Exoplayer, Exoplayer dash if needed, and optional Media3 UI, using version 1.5.1 and a version catalog.
Create and configure an Exoplayer instance in a Compose app, attach a video surface, load a dash stream URL as a MediaItem, then prepare and play.
Explore how Android surface types power video playback, comparing surface view and texture view, and learn to use AndroidExternalSurface in Jetpack Compose to manage local and external surfaces with ExoPlayer.
Learn how texture view uses a surface texture object and a surface wrapped by the Android embedded external surface composable to feed ExoPlayer, and how this differs from surface view.
Compare surface view and texture view for drm content playback using ExoPlayer, exploring drm l1 widevine requirements, secure stream urls, and test workflows across labs modules.
Texture view supports transparency from early Android versions, while surface view requires Android 14, and external surface composables cannot apply alpha.
Compare surface view and texture view for video rotation, showing texture view supports a 90-degree rotation with rotation animation, while surface view fails due to separate local and external surfaces.
Compare surface view and texture view for video scale and offset, showing texture view copies pixels while surface view relays scale, offset, and alpha to the external surface on Android.
Compare surface view and texture view for video rendering, noting that surface view saves CPU and battery life and HDR support, while texture view risks frame drops.
Exoplayer supports progressive and adaptive media sources, infers types from stream URLs and manifest files, and dynamically switches dash, Apple HLS, and Microsoft Smooth Streaming tracks under changing network conditions.
Decode dash manifest in XML, focusing on adaptation sets and representations with bandwidth, width, height, and codecs. See how Exoplayer uses ABR and range headers to fetch segmented mp4 files.
Learn how video encoding compresses streams for storage and streaming, from raw frames to H264, Hevc, VP8, and VP9, and how ExoPlayer extracts and relies on hardware decoding.
Learn how a video encoder compresses video by exploiting temporal and spatial redundancy, using i-frames, p-frames, and b-frames with reference frames.
Trace the Exoplayer media playback workflow from backend encoding and packaging to dash manifest delivery via CDNs, through prepare, decode, and display on device hardware.
Add full playback controls and a home screen, including play, pause, rewind, fast forward, fullscreen, and track selection, while cleaning up code by organizing playback into the Lay Back package.
Set up two activities for home and playback, create a home UI model with a cover and description, pass the stream URL to playback, and attribute Tears of Steel.
Overlay a clickable play button on the home poster using a vector asset, and start playback by passing the stream URL to the playback activity via an intent.
Create a playback view model to persist the exoplayer instance across rotations, manage media items and surface bindings, and start playback in onStart for efficient memory use.
Identify and fix a memory leak in ExoPlayer by stopping and releasing playback in the ViewModel and the activity lifecycle, reducing Java heap usage and releasing hardware decoders.
Explore Exoplayer state transitions from idle to buffering to ready and ended, including the final released state, and how prepare, play, pause, and stop manage decoding and buffering.
Use ExoPlayer's on video size callback to obtain the real video size, compute the correct aspect ratio, and update the UI model to apply it.
Add a full screen toggle overlay to the video player, switching between full screen and portrait modes, with vector icons, a video overlay, playback controls, and a semi-transparent background.
Implement a full screen toggle by updating isFullScreen in the view model and propagating it to the UI. Hide the status bar in full screen and preserve playback during rotation.
Implement centered playback state controls for ExoPlayer in a Compose UI, including fast forward, rewind, start over, and play/pause, with loading indicators, restart on end, and error/retry behavior.
Learn to implement playback state controls in an Android media app using Media3 ExoPlayer and Compose, including handling actions, managing surfaces, seek, start, pause, resume, and error states.
Implement a bottom time bar on the player overlay using a timeline UI model with duration, current position, and buffer, updating every second from ExoPlayer and enabling scrubbing with seek.
Add a placeholder image below the player controls to show during idle playback, preventing a black screen for DRM content, with a view model that toggles visibility by playback state.
Add a bottom sheet track selector to lock exoplayer to video, audio, or subtitle tracks with auto, and define UI models for video, audio, subtitle tracks and their selection state.
Map ExoPlayer tracks to UI models by handling the on tracks changed callback, creating ExoPlayerTrack mappings for video, audio, and subtitle tracks.
Learn to implement track switching in Exoplayer by building a selection for video, audio, and subtitle tracks, clearing overrides, and applying overrides to update playback and the player interface state.
Implement a track selection UI for Android media playback with Media3 ExoPlayer and Compose, adding a settings button and a modal bottom sheet to switch video, audio, and subtitle tracks.
Add a subtitles composable that wraps the Exoplayer subtitle view in an Android view, renders cues in the video overlay, and updates the player UI model with current subtitles.
Test playback on an old fire tv stick, observe an out of memory crash, and enable a large heap flag to increase Java heap for ExoPlayer on legacy Android versions.
Exoplayer uses Java heap memory for the video buffer and unfinished network requests, and you can manage it via heap growth limit and heap size and the load control class.
Implement split view with two ExoPlayer streams. Tune load control and track selection parameters to reduce memory usage, limit video height to 720p, and fix orientation handling to prevent leaks.
Compare memory usage between exoplayer and a shaka webview player by playing tears of steel in a webview, showing app memory over 250mb while java heap stays around 14mb.
Compare client side ad insertion and server side ad insertion for video streams, focusing on Exoplayer Ima SDK for client side implementation.
Learn how edit tag provides metadata via a URL, how vmap and vast coordinate ad scheduling with pre-roll and mid-roll ads, how ad beacons report start, end, or mute events.
Explore VMAP and VAST in Android media playback, examining ad breaks with pre-roll, mid-roll groups, and end ads, ad tag URIs, VAST responses, media file selection, and ad beacon URLs.
Add the media3 ima sdk dependency and ad tag url, pass it through activities, and configure a custom exoplayer media source with an ad loader to switch content and ads.
Create the ImaAdsLoader and connect it to ExoPlayer to load ad content. Configure a default media source factory with an ad provider to stitch ads to the main content.
Add ad ui models and overlay elements that sync with ad states, including time bar markers for ad groups and an ad counter during playback.
Listen for ad events with the IMA SDK in ExoPlayer, fetch ad group data from EMR SDK, build ad groups from timeline, and update the UI model with ad progress.
Develop composable functions for ad playback user interface, render add groups markers on the time bar, show an ad counter during ad breaks (including pre-roll), while hiding playback controls.
Explore how drm, which encrypts media content, protects after access, explaining why drm matters for Android ExoPlayer and how a license url configures playback to guard against recording and sharing.
Understand DRM schemes and licenses, including how encryption, license issuance, and access restrictions operate on devices; learn about Widevine L1, Fairplay, and how license servers interact with secure hardware.
Resource limitations for drm restrict secure h264 decoders to one instance on Fire TV; the lecture demonstrates detecting max drm decoders via media codec list and adapting user interface accordingly.
Explain the drm workflow from key provisioning to playback, detailing safe drm and Widevine, content IDs and key IDs, dash manifests, exoplayer integration, and secure execution in the trusted environment.
In this course, you'll learn how to build a fully functional media playback app using Android’s modern Media3 ExoPlayer library. We’ll focus on integrating media playback seamlessly while leveraging Jetpack Compose for a modern and interactive UI.
This course is designed for Android developers who want to implement media playback in their apps. While prior experience with media playback isn’t required, you should have a decent understanding of Android development and be familiar with Jetpack Compose. The primary goal is to explore ExoPlayer and its capabilities rather than focusing on clean architecture.
What You Will Learn
Media3 Library Overview
Understand the core components of Media3, including exoPlayer, exoPlayer-ui, mediaSession, and transformer. This course primarily focuses on ExoPlayer for handling audio and video playback.
TextureView vs. SurfaceView
Learn the differences between TextureView and SurfaceView, the two primary video sinks used for rendering video content.
Interactive UI with Jetpack Compose
Build an interactive playback interface using Jetpack Compose with features like video seeking, track selection, and time bar rendering while optimizing memory usage.
Media Codecs & Media Sources
Explore adaptive streaming, media codecs, and container formats, and examine how different components in ExoPlayer interact during media playback.
Video Ads with ExoPlayer IMA
Learn how to insert video ads using the Interactive Media Ads (IMA) SDK with ExoPlayer. Get an introduction to VAST (Video Ad Serving Template) and VMAP (Video Multiple Ad Playlist).
Digital Rights Management (DRM)
Get a deep understanding or how DRM works in Android and how to configure ExoPlayer to play a DRM protected content.
By the end of this course, you’ll have a deep understanding of ExoPlayer and be able to integrate high-performance media playback into your Android apps.