How to Implement Android HLS Player with ExoPlayer?

Learn how to implement an Android HLS player using ExoPlayer. Follow our step-by-step guide to stream high-quality video content seamlessly on your Android app.

What is Android HLS Player?

Android HLS Player is a media player specifically designed to stream video and audio content using

HTTP Live Streaming (HLS) protocol

on Android devices. HLS is a streaming protocol developed by Apple, widely used for delivering media content over the internet. It breaks down video content into small segments, which are delivered to the client as a series of HTTP requests. This allows for

adaptive bitrate streaming

, where the quality of the video can adjust dynamically based on the network conditions and device capabilities, ensuring smooth playback with minimal buffering.
This article aims to guide developers through the process of intergrating HLS player in android application leveraging the powerful ExoPlayer library. By the end of this guide, you will have a solid understanding of HLS, be able to implement a basic HLS player, customize its features, and troubleshoot common issues.

What is HLS (HTTP Live Streaming)?

HLS (HTTP Live Streaming) is a streaming protocol that delivers video content in small chunks, allowing for adaptive bitrate streaming. This means the video quality can automatically adjust based on the viewer's internet connection, providing a smooth playback experience without buffering.

Benefits of HLS

  • Adaptive Bitrate Streaming: HLS automatically adjusts the quality of the stream according to the viewer's bandwidth, ensuring continuous playback even with fluctuating internet speeds.
  • Cross-Platform Compatibility: HLS is supported across various devices and platforms, including iOS, Android, and web browsers.
  • Scalability: HLS can handle large-scale streaming, making it suitable for live broadcasts and on-demand video services.

Comparison HLS with Other Streaming Protocols

  • DASH (Dynamic Adaptive Streaming over HTTP): Similar to HLS, but with more flexibility in codecs and segment formats. However, HLS has broader native support on Apple devices.
  • RTSP (Real-Time Streaming Protocol): More suitable for real-time communications like video conferencing, but less efficient for adaptive bitrate streaming compared to HLS.

Setting Up an Android HLS Player: The Basics

Before diving into the implementation, ensure you have the following tools and libraries ready:
  • Android Studio: The official IDE for Android development.
  • ExoPlayer: A powerful media player library for Android that supports HLS.
To get started with HLS streaming in Android, you need to set up a new Android project and install the necessary dependencies. Follow the step step guide here.

Step 1. Create a New Android Project:

  • Open Android Studio and create a new project.
  • Select "Empty Activity" and configure your project settings (name, package name, save location, etc.).

Step 2. Add ExoPlayer Dependency:

  • Open your project's build.gradle file (Module: app).
  • Add the following dependency:
1     implementation 'com.google.android.exoplayer:exoplayer:2.15.1'
2
Sync your project to download and integrate the ExoPlayer library.

Implementing a Simple HLS Player in Android

With your project set up, it's time to implement

HLS player in android

using ExoPlayer.

Code Snippet for a Basic HLS Player

javascript

1// MainActivity.java
2package com.example.hlsplayer;
3
4import android.net.Uri;
5import android.os.Bundle;
6import androidx.appcompat.app.AppCompatActivity;
7import com.google.android.exoplayer2.ExoPlayer;
8import com.google.android.exoplayer2.MediaItem;
9import com.google.android.exoplayer2.ui.PlayerView;
10
11public class MainActivity extends AppCompatActivity {
12
13    private ExoPlayer player;
14    private PlayerView playerView;
15
16    @Override
17    protected void onCreate(Bundle savedInstanceState) {
18        super.onCreate(savedInstanceState);
19        setContentView(R.layout.activity_main);
20
21        playerView = findViewById(R.id.player_view);
22
23        // Initialize the ExoPlayer
24        player = new ExoPlayer.Builder(this).build();
25        playerView.setPlayer(player);
26
27        // Prepare the HLS media source
28

java

1        Uri hlsUri = Uri.parse("https://path/to/your/hls/stream.m3u8");
2        MediaItem mediaItem = MediaItem.fromUri(hlsUri);
3
4        // Set the media item to be played
5        player.setMediaItem(mediaItem);
6        player.prepare();
7        player.play();
8    }
9
10    @Override
11    protected void onStop() {
12        super.onStop();
13        player.release();
14    }
15}
16

Explanation of the Code

  • ExoPlayer Initialization: We initialize ExoPlayer and bind it to a PlayerView in our layout.
  • Setting the Media Source: We create a MediaItem from the HLS stream URL and set it on the player.
  • Preparing and Playing the Stream: The player is prepared and playback starts immediately.
  • Releasing the Player: Ensuring resources are released when the activity stops to avoid memory leaks.

Running the Application and Initial Testing

Layout Configuration

Create a PlayerView in your activity_main.xml layout file:

xml

1     <!-- activity_main.xml -->
2     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3         xmlns:tools="http://schemas.android.com/tools"
4         android:layout_width="match_parent"
5         android:layout_height="match_parent"
6         tools:context=".MainActivity">
7
8         <com.google.android.exoplayer2.ui.PlayerView
9             android:id="@+id/player_view"
10             android:layout_width="match_parent"
11             android:layout_height="match_parent"
12             android:layout_centerInParent="true"/>
13
14     </RelativeLayout>
15

Testing

  • Run the application on an Android device or emulator.
  • Ensure that the HLS stream plays smoothly without interruptions.

Advanced Implementation and Customization of HLS Player

Advanced HLS Player Features

Enhancing your HLS player involves handling different qualities, bitrates, and implementing adaptive bitrate streaming.

Handling Different Qualities and Bitrates

ExoPlayer can automatically switch between different stream qualities based on the user's network conditions. This feature, known as adaptive bitrate streaming, ensures a smooth viewing experience.

Implementing Adaptive Bitrate Streaming

Adaptive bitrate streaming is handled internally by ExoPlayer, but you can customize it further.

Code Example for Adaptive Bitrate Streaming

Javascript

1// Create a default TrackSelector
2TrackSelector trackSelector = new DefaultTrackSelector(this);
3trackSelector.setParameters(
4    trackSelector.buildUponParameters().setMaxVideoSizeSd());
5
6// Initialize the ExoPlayer with the track selector
7player = new ExoPlayer.Builder(this).setTrackSelector(trackSelector).build();
8playerView.setPlayer(player);
9
10// Prepare the HLS media source as before
11Uri hlsUri = Uri.parse("https://path/to/your/hls/stream.m3u8");
12MediaItem mediaItem = MediaItem.fromUri(hlsUri);
13
14player.setMediaItem(mediaItem);
15player.prepare();
16player.play();
17

Explanation

  • TrackSelector: Allows customization of the media tracks (video, audio, etc.) selected for playback.
  • Max Video Size: In this example, we set the maximum video size to SD (Standard Definition).

Customizing the Player UI

A custom UI enhances user interaction and experience. ExoPlayer provides a default UI, but it can be customized extensively.

Modifying Default Player Controls

You can modify the default controls or create your own controls to replace the default ones. To customize the UI, modify the PlayerView attributes or create your own layout.

Example of Custom UI Implementation

Custom Controller Layout

xml

1   <!-- custom_controller.xml -->
2   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3       android:layout_width="match_parent"
4       android:layout_height="wrap_content"
5       android:orientation="horizontal">
6
7       <Button
8           android:id="@+id/play_button"
9           android:layout_width="wrap_content"
10           android:layout_height="wrap_content"
11           android:text="Play"/>
12
13       <SeekBar
14           android:id="@+id/seek_bar"
15           android:layout_width="0dp"
16           android:layout_weight="1"
17           android:layout_height="wrap_content"/>
18
19       <Button
20           android:id="@+id/pause_button"
21           android:layout_width="wrap_content"
22           android:layout_height="wrap_content"
23           android:text="Pause"/>
24   </LinearLayout>
25

Binding Custom Controller to Player

javascript

1   // In MainActivity.java
2   PlayerControlView playerControlView = findViewById(R.id.player_control_view);
3
4   Button playButton = playerControlView.findViewById(R.id.play_button);
5   Button pauseButton = playerControlView.findViewById(R.id.pause_button);
6   SeekBar seekBar = playerControlView.findViewById(R.id.seek_bar);
7
8   playButton.setOnClickListener(v -> player.play());
9   pauseButton.setOnClickListener(v -> player.pause());
10
11   player.addListener(new Player.Listener() {
12       @Override
13       public void onPlaybackStateChanged(int playbackState) {
14           if (playbackState == Player.STATE_READY && player.getPlayWhenReady()) {
15               seekBar.setMax((int) player.getDuration());
16           }
17       }
18   });
19
20   // Update SeekBar during playback
21   new Handler().postDelayed(new Runnable() {
22       @Override
23       public void run() {
24           if (player != null && player.isPlaying()) {
25               seekBar.setProgress((int) player.getCurrentPosition());
26           }
27           handler.postDelayed(this, 1000);
28       }
29   }, 0);
30

Get Free 10,000 Minutes Every Months

No credit card required to start.

Error Handling and Debugging

Proper error handling ensures a robust user experience. ExoPlayer provides various listeners to handle errors and states.

[a] Common Issues and Solutions

  • Network Interruptions: Implement retries and fallbacks for network errors.
  • Unsupported Formats: Check media format compatibility and provide appropriate feedback to users.

[b] Implementing Error Listeners in ExoPlayer

javascript

1player.addListener(new Player.Listener() {
2    @Override
3    public void onPlayerError(PlaybackException error) {
4        // Handle error
5        Toast.makeText(MainActivity.this, "Playback error: " + error.getMessage(), Toast.LENGTH_LONG).show();
6    }
7});
8

[c] Debugging Tips and Best Practices

  • Logcat: Use Android's Logcat for detailed logs.
  • ExoPlayer DebugViewHelper: Provides detailed playback information for debugging.
  • Below is the example for debuging..

javascript

1// Adding a DebugViewHelper to monitor player state
2DebugViewHelper debugViewHelper = new DebugViewHelper(player, playerView);
3debugViewHelper.start();
4
By following these steps and using the provided code snippets, you can implement a robust, customizable HLS player in your Android application, capable of delivering high-quality streaming experiences to your users.

Conclusion

In conclusion, integrating an Android HLS Player using ExoPlayer empowers developers to deliver seamless streaming experiences to users. By leveraging HLS protocol's adaptive bitrate streaming capabilities, cross-platform compatibility, and scalability, developers can ensure smooth playback across diverse network conditions and device types. With advanced features like adaptive bitrate streaming, custom UI modifications, and effective error handling, developers can create a highly customizable and robust streaming solution tailored to their application's needs, enriching user engagement and satisfaction.

Want to level-up your learning? Subscribe now

Subscribe to our newsletter for more tech based insights

FAQ