How to integrate video streaming in your android app

April 25, 2025
8 Min
Video Engineering
Jump to
Share
This is some text inside of a div block.
Join Our Newsletter for the Latest in Streaming Technology

If you’re building an Android app, chances are you need video whether it’s on-demand playback, live streaming, or short video clips. This guide shows you how to add streaming to your Android application with the right tools and protocols.

  • How to stream on-demand and live video in Android using ExoPlayer
  • Choosing the right streaming protocols like HLS and MPEG-DASH
  • Adding adaptive streaming, DRM protection, and custom playback controls
  • Key backend tips for smooth playback  plus how FastPix can handle the heavy lifting for you

Streaming types and protocols for android apps

In Android development, you’ll typically work with two types of video streaming:

  • On-demand streaming (VOD) : Plays pre-recorded content like tutorials, trailers, or product videos. Users can pause, seek, and buffer smoothly using Android playback libraries like ExoPlayer.
  • Live streaming : Delivers real-time video for events, gaming, or webinars. Requires a backend that supports live ingest and adaptive bitrate streaming to handle different network conditions.

Recommended streaming protocols for android

  • HLS (HTTP Live Streaming): The most common choice for both VOD and live streaming on Android. Breaks video into small segments and supports adaptive playback.
  • MPEG-DASH: Similar to HLS, codec-agnostic, and an open standard. Also works well for adaptive streaming on Android.
  • RTMP: Still used for pushing live streams from encoders, but typically converted to HLS or DASH for playback in Android apps.
  • Progressive download (MP4): Simple to implement but doesn’t support adaptive streaming. Best for basic video playback without live or ABR requirements.

For most Android apps, HLS or MPEG-DASH are the best options for reliable, scalable video streaming. Both work seamlessly with ExoPlayer and handle variable network conditions effectively.

Native Media Playback: MediaPlayer vs. ExoPlayer

Before integrating video streaming into your Android app, it’s important to choose the right player. Android doesn’t offer true “native adaptive streaming” out of the box — instead, you get playback libraries that handle media decoding and rendering.

The two main options:

1. MediaPlayer (Android SDK)

  • Comes built into Android.
  • Supports basic playback of formats like MP4 and HLS.
  • Limited error handling and customization.
  • No support for adaptive bitrate streaming across all use cases.
  • Missing advanced features like DRM, track selection, and analytics.

When to use: Only for simple, lightweight use cases with basic MP4 or HLS playback. Not recommended for production-grade streaming apps.

2. ExoPlayer (Recommended)

  • Open-source, developed and maintained by Google.
  • Full support for HLS, MPEG-DASH, SmoothStreaming, MP4.
  • Adaptive bitrate streaming with seamless switching between qualities.
  • DRM support including Widevine for content protection.
  • Offers features like background playback, offline downloads, subtitles, analytics hooks, and playback speed control.
  • Actively maintained with regular updates and community support.

When to use: Ideal for any serious production app that needs reliable, flexible, and scalable video playback.

How to set up ExoPlayer in android studio

Step 1: Add ExoPlayer Dependencies

In your app-level build.gradle:

groovy

1dependencies {
2    implementation 'com.google.android.exoplayer:exoplayer:2.19.1'
3}
4

Sync your project after adding the dependency.

Step 2: Add playerview to your layout

In your activity_main.xml (or fragment layout):

xml

1<com.google.android.exoplayer2.ui.PlayerView
2    android:id="@+id/playerView"
3    android:layout_width="match_parent"
4    android:layout_height="250dp"
5    android:background="@android:color/black" />
6

PlayerView handles video rendering and includes built-in playback controls like play, pause, and seek.

Step 3: Initialize ExoPlayer and play video

Java example:

1PlayerView playerView;
2ExoPlayer exoPlayer;
3
4@Override
5protected void onCreate(Bundle savedInstanceState) {
6    super.onCreate(savedInstanceState);
7    setContentView(R.layout.activity_main);
8
9    playerView = findViewById(R.id.playerView);
10    exoPlayer = new ExoPlayer.Builder(this).build();
11    playerView.setPlayer(exoPlayer);
12
13    MediaItem mediaItem = MediaItem.fromUri("https://your-server.com/your-video.mp4");
14    exoPlayer.setMediaItem(mediaItem);
15    exoPlayer.prepare();
16    exoPlayer.play();
17}
18
19@Override
20protected void onDestroy() {
21    super.onDestroy();
22    if (exoPlayer != null) {
23        exoPlayer.release();
24    }
25}
26

Kotlin example:

private lateinit var playerView: PlayerView
private lateinit var exoPlayer: ExoPlayer

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

    playerView = findViewById(R.id.playerView)
    exoPlayer = ExoPlayer.Builder(this).build()
    playerView.player = exoPlayer

    val mediaItem = MediaItem.fromUri("https://your-server.com/your-video.mp4")
    exoPlayer.setMediaItem(mediaItem)
    exoPlayer.prepare()
    exoPlayer.playWhenReady = true
}

override fun onDestroy() {
    super.onDestroy()
    exoPlayer.release()
}

If you care about smooth playback, adaptive streaming, and reliable error handling on Android especially for live or long-form video ExoPlayer is the right tool for the job.

Optional enhancements (Consider adding later)

  • Offline playback setup.
  • Handling playback errors and recovery.
  • Using adaptive bitrate manifests (HLS/DASH).
  • Integrating DRM (Widevine).
  • Adding analytics (e.g., ExoPlayer analytics listener or custom events).

Adding adaptive streaming with ExoPlayer

If your video source is an HLS (.m3u8) or MPEG-DASH stream, ExoPlayer handles adaptive bitrate switching automatically. No extra configuration is required — just provide the streaming URL:

kotlin

1val mediaItem = MediaItem.fromUri("https://your-server.com/stream/playlist.m3u8")
2exoPlayer.setMediaItem(mediaItem)
3exoPlayer.prepare()
4exoPlayer.playWhenReady = true
5

ExoPlayer adjusts video quality in real time based on network conditions, providing smoother playback on both fast and unstable connections.

Live streaming with ExoPlayer

For live streams, use the same approach. If your backend supports HLS or DASH, ExoPlayer can handle the live playback, including adaptive bitrate and low-latency optimizations.

Example for live HLS:

Kotlin

val liveStreamUrl = "https://your-server.com/live/stream.m3u8"
val mediaItem = MediaItem.Builder()
    .setUri(liveStreamUrl)
    .setLiveConfiguration(
        MediaItem.LiveConfiguration.Builder()
            .setMaxPlaybackSpeed(1.02f) // Slight speed-up to stay closer to real-time
            .build()
    )
    .build()

exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
exoPlayer.playWhenReady = true

The LiveConfiguration helps ExoPlayer handle live-specific playback optimizations, like reducing latency and maintaining sync with the live edge.

Improving playback performance

Getting streaming to work is one thing making sure it performs well across devices and networks is where production-ready apps stand out. Here are key practices for improving playback quality in Android:

Caching segments for smoother playback

ExoPlayer supports SimpleCache to locally cache video chunks. This helps reduce rebuffering, especially on unstable networks.

Handling playback errors

Always listen for playback errors to catch issues like network drops or invalid streams:

Kotlin

1exoPlayer.addListener(object : Player.Listener {
2    override fun onPlayerError(error: PlaybackException) {
3        Toast.makeText(this@MainActivity, "Playback error: ${error.message}", Toast.LENGTH_SHORT).show()
4    }
5})
6

Managing player lifecycle

Avoid memory leaks by releasing the player properly when the activity or fragment stops:

Kotlin

override fun onPause() {
    super.onPause()
    exoPlayer.playWhenReady = false
}

override fun onDestroy() {
    super.onDestroy()
    exoPlayer.release()
}

Adding subtitles or captions

ExoPlayer supports multiple subtitle formats like VTT, SRT, and TTML. Here’s how to add subtitles:

Kotlin

val subtitle = MediaItem.SubtitleConfiguration.Builder(Uri.parse("https://your-server.com/subtitles.vtt"))
    .setMimeType(MimeTypes.TEXT_VTT)
    .build()

val mediaItem = MediaItem.Builder()
    .setUri("https://your-server.com/video.mp4")
    .setSubtitleConfigurations(listOf(subtitle))
    .build()

exoPlayer.setMediaItem(mediaItem)

Enabling DRM for secure content

If your app includes paid or premium content, use Widevine DRM to prevent unauthorized access:

Kotlin

val drmConfiguration = MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
    .setLicenseUri("https://your-license-server.com")
    .build()

val mediaItem = MediaItem.Builder()
    .setUri("https://your-server.com/protected-content.m3u8")
    .setDrmConfiguration(drmConfiguration)
    .build()

exoPlayer.setMediaItem(mediaItem)

Backend considerations for better streaming

Great playback also depends on your backend setup not just your player code.

  • Use a CDN like Cloudflare, AWS CloudFront, or Akamai to reduce latency and buffering.
  • Segment your videos properly (HLS chunks are usually 6–10 seconds).
  • Offer multiple resolutions and bitrates for adaptive streaming.
  • Monitor your stream health (bitrate, latency, failures) to optimize delivery.

Platforms like FastPix can handle these complexities for you from adaptive encoding to live-to-VOD recording and content protection so you can focus on your Android app instead of managing video pipelines or CDN workflows.

 

Testing your streaming setup

Don’t forget to test across:

  • Various network speeds (WiFi, 4G, 3G, throttled connections).·      
  • Device types (low-end to flagship phones).·      
  • Orientation and background/foreground states.·      
  • Live vs. recorded content.

Tools like Android Profiler and Charles Proxy can help analyze network calls and media buffering.

Advanced video streaming in android: exoplayer customization, drm, and server setup

If you’re building serious video streaming into your Android app, basic playback isn’t enough. Production-ready apps need flexibility, security, and reliable delivery at scale.

In this section, we’ll cover:

  • Advanced ExoPlayer customization.
  • Implementing Widevine DRM.
  • Server-side best practices for adaptive streaming and live delivery.

Advanced ExoPlayer customization

ExoPlayer is more than a plug-and-play player it’s built for customization.

Custom playback controls

The default PlayerView gives you standard controls, but ExoPlayer lets you fully replace the UI.

Example: Custom play button with manual control:

xml

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/customPlayerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:use_controller="false" />

    <ImageButton
        android:id="@+id/playButton"
        android:src="@drawable/ic_play"
        android:layout_centerInParent="true"
        android:background="?attr/selectableItemBackgroundBorderless"/>
</RelativeLayout>
kotlin
CopyEdit
playButton.setOnClickListener {
    if (exoPlayer.isPlaying) {
        exoPlayer.pause()
    } else {
        exoPlayer.play()
    }
}

Playback speed control

ExoPlayer supports speed adjustments out of the box:

Kotlin

exoPlayer.setPlaybackParameters(PlaybackParameters(1.5f))

You can wire this to a UI dropdown or slider for dynamic user control.

Picture-in-Picture (PiP) mode

Enable PiP to keep video playback running when users switch apps:

kotlin

override fun onUserLeaveHint() {
    val params = PictureInPictureParams.Builder().build()
    enterPictureInPictureMode(params)
}

DRM: Protecting your content with Widevine

For apps that monetize video or stream licensed content, DRM is non-negotiable. ExoPlayer supports Widevine DRM, Google’s content protection system.

Setting up Widevine DRM in ExoPlayer

Kotlin

val drmConfiguration = MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
    .setLicenseUri("https://license-server.com/getlicense")
    .build()

val mediaItem = MediaItem.Builder()
    .setUri("https://yourserver.com/encrypted/video.mpd")
    .setDrmConfiguration(drmConfiguration)
    .build()

exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
exoPlayer.play()

The license server handles authentication and delivers the decryption keys securely.

Offline DRM playback

For subscription models or download-to-watch apps:

  1. Fetch and store the DRM license.
  2. Use the license for offline playback without re-fetching.
  3. Widevine handles expiration and renewal.

This reduces server load and ensures secure offline viewing.

Server-Side setup for smooth streaming

Your playback experience depends as much on the backend as on the app. Here’s what to get right on the server side:

Choose the right protocol

  • HLS: Reliable across Android, iOS, and web.
  • MPEG-DASH: Open standard, codec-flexible.
  • RTMP: Used for live ingest, usually converted to HLS or DASH for playback.

For Android apps, HLS or DASH are the most scalable options.

 

Use a CDN to reduce latency

CDNs like, AWS CloudFront, or FastPix cache content closer to your users. This cuts down:

  • Startup delays.
  • Buffering.
  • Server load.

Adaptive bitrate (ABR) strategy

Your video manifest (.m3u8 for HLS, .mpd for DASH) should list multiple resolutions, for example:

  • 1080p (high)
  • 720p (medium)
  • 480p (low)

ExoPlayer automatically selects the best stream based on the user’s network bandwidth.

Live streaming setup for android

For live video, your backend needs:

  • RTMP ingest (Nginx RTMP module or equivalent).
  • Conversion to HLS or DASH for delivery.
  • Distribution via CDN.

If you want to skip server management, FastPix supports:

  • RTMP/SRT ingest.
  • Instant live encoding.
  • HLS and DASH playback.
  • Live-to-VOD recording.

This removes the need to handle segmenting, packaging, or scaling infrastructure yourself.

Conclusion

For production-grade video on Android:

  • Use ExoPlayer for playback and customization.
  • Implement Widevine DRM for content protection.
  • Prepare your backend with proper encoding, ABR manifests, and CDN delivery.
  • For live streaming, ensure RTMP ingest and adaptive playback with HLS or DASH.

If you don’t want to spend time managing encoders, packaging workflows, or CDN configurations, FastPix handles the entire streaming stack for you from just-in-time encoding and adaptive bitrate packaging to live-to-VOD recording and content protection.

With support for HLS and MPEG-DASH out of the box, FastPix lets you stream on Android and iOS without the overhead of building and scaling your own video infrastructure. You focus on your app and user experience FastPix takes care of the video delivery. Go through our Docs and Guides to understand FastPix better or talk to us to see how we can help with your workflow.

FAQs

How can I preload video segments in ExoPlayer to reduce buffering?

ExoPlayer supports segment-level caching using SimpleCache, which allows you to store video chunks locally. This helps reduce rebuffering during playback, especially under fluctuating network conditions. You can integrate CacheDataSourceFactory and configure cache size and eviction policies to control performance.

Can ExoPlayer handle dynamic resolution switching during live events?

Yes, ExoPlayer supports adaptive bitrate (ABR) streaming for live content. If your HLS or DASH stream includes multiple quality renditions, ExoPlayer will automatically switch between them based on real-time bandwidth conditions — ensuring minimal buffering and optimal quality.

What’s the difference between MediaItem.LiveConfiguration and regular playback in ExoPlayer?

MediaItem.LiveConfiguration is designed for live stream tuning. It enables features like low-latency playback and playback speed adjustments to stay close to the live edge. Regular playback settings don’t optimize for real-time latency or sync in the same way.

Which video streaming library is best for Android apps in 2025?

For Android in 2025, ExoPlayer remains the top choice due to its support for adaptive streaming, DRM, and customization. Unlike MediaPlayer, it’s actively maintained by Google, handles modern formats like HLS/DASH, and integrates with analytics, subtitles, and offline playback.

How do I stream high-quality video in Android apps without buffering?

To stream high-quality video without buffering, use adaptive bitrate streaming with ExoPlayer, deliver content via a CDN, and segment videos into smaller chunks. Caching, error handling, and real-time bitrate switching are key to smooth playback across devices.

It's Free

Enjoyed reading? You might also like

Try FastPix today!

FastPix grows with you – from startups to growth stage and beyond.