Setup HLS Player - Android
In this guide, we will add player which will be responsible for playing the HLS stream. Before starting this guide, make sure you have a VideoSDK meetings setup allowing you to join the room. To learn more about setting up a VideoSDK meeting, follow this quick start guide.
To play the HLS stream we will be using the Exoplayer library.
1. Setup player into your project
Step 1: Let's first add ExoPlayer module dependency into the project.
dependencies {
  implementation 'com.google.android.exoplayer:exoplayer:2.18.5'
  // other app dependencies
  }
Step 2: Now let's add the StyledPlayerView which will display livestreaming. And also add the TextView which will be shown when there is no active HLS. For these, we will use the onHlsStateChanged event from the MeetingEventListener abstract class to identify if there is an active HLS.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/waitingLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Waiting for host \n to start the live streaming"
        android:textFontWeight="700"
        android:textSize="20sp"
        android:gravity="center"/>
    <com.google.android.exoplayer2.ui.StyledPlayerView
        android:id="@+id/player_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        app:resize_mode="fixed_width"
        app:show_buffering="when_playing"
        app:show_subtitle_button="false"
        app:use_artwork="false"
        app:show_next_button="false"
        app:show_previous_button="false"
        app:use_controller="true"/>
</LinearLayout>
2. Initialize player and Playing HLS stream
Step 1: Now that player is setup, let's initialize player and play the HLS once it becomes playable. For these, we will get the playbackHlsUrl and livestreamUrl when the onHlsStateChanged event of MeetingEventListener state changes to HLS_PLAYABLE.
- when you receive 
HLS_PLAYABLEstatus you will receive 2 urlsplaybackHlsUrl- Live HLS with playback supportlivestreamUrl- Live HLS without playback support
 
downstreamUrl is now depecated. Use playbackHlsUrl or livestreamUrl in place of downstreamUrl
Step 2: We also need to release player and show TextView which shows there is no active HLS. We will release player when the onHlsStateChanged event of MeetingEventListener state changes to HLS_STOPPED.
- Kotlin
 - Java
 
class ViewerActivity : AppCompatActivity() {
    private val meeting: Meeting? = null
    private var playerView: StyledPlayerView? = null
    private var waitingLayout: TextView? = null
    private var player: ExoPlayer? = null
    private var dataSourceFactory: DefaultHttpDataSource.Factory? = null
    private val startAutoPlay = true
    private var playbackHlsUrl: String? = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_meeting)
        playerView = findViewById(R.id.player_view)
        waitingLayout = findViewById(R.id.waitingLayout)
        // setup meeting
        //...
        // add listener to the meeting
        meeting!!.addEventListener(meetingEventListener)
    }
    private val meetingEventListener: MeetingEventListener = object : MeetingEventListener() {
        override fun onMeetingJoined() {
            Log.d("VideoSDK", "onMeetingJoined: ")
        }
        override fun onMeetingLeft() {
            Log.d("VideoSDK", "onMeetingLeft: ")
        }
        @RequiresApi(api = Build.VERSION_CODES.P)
        override fun onHlsStateChanged(HlsState: JSONObject) {
            if (HlsState.has("status")) {
                try {
                    if (HlsState.getString("status") == "HLS_PLAYABLE" && HlsState.has("playbackHlsUrl")) {
                        playbackHlsUrl = HlsState.getString("playbackHlsUrl")
                        waitingLayout!!.visibility = View.GONE
                        playerView!!.visibility = View.VISIBLE
                        // initialize player
                        initializePlayer()
                    }
                    if (HlsState.getString("status") == "HLS_STOPPED") {
                        // release the player
                        releasePlayer()
                        playbackHlsUrl = null
                        waitingLayout!!.text = "Host has stopped \n the live streaming"
                        waitingLayout!!.visibility = View.VISIBLE
                        playerView!!.visibility = View.GONE
                    }
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            }
        }
    }
    private fun initializePlayer() {
        if (player == null) {
            dataSourceFactory = DefaultHttpDataSource.Factory()
            val mediaSource = HlsMediaSource.Factory(dataSourceFactory!!).createMediaSource(
                MediaItem.fromUri(Uri.parse(playbackHlsUrl))
            )
            val playerBuilder = ExoPlayer.Builder( /* context= */this@ViewerActivity)
            player = playerBuilder.build()
            // auto play when player is ready
            player!!.playWhenReady = startAutoPlay
            player!!.setMediaSource(mediaSource)
            // if you want display setting for player then remove this line
            playerView!!.findViewById<View>(com.google.android.exoplayer2.ui.R.id.exo_settings).visibility =
                View.GONE
            playerView!!.player = player
        }
        player!!.prepare()
    }
    private fun releasePlayer() {
        if (player != null) {
            player!!.release()
            player = null
            dataSourceFactory = null
            playerView!!.player = null
        }
    }
}
public class ViewerActivity extends AppCompatActivity {
    private Meeting meeting;
    protected StyledPlayerView playerView;
    private TextView waitingLayout;
    protected @Nullable
    ExoPlayer player;
    private DefaultHttpDataSource.Factory dataSourceFactory;
    private boolean startAutoPlay = true;
    private String playbackHlsUrl = "";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_meeting);
        playerView = findViewById(R.id.player_view);
        waitingLayout = findViewById(R.id.waitingLayout);
        // setup meeting
        //...
        // add listener to the meeting
        meeting.addEventListener(meetingEventListener);
    }
    private final MeetingEventListener meetingEventListener = new MeetingEventListener() {
        @Override
        public void onMeetingJoined() {
            Log.d("VideoSDK", "onMeetingJoined: ");
        }
        @Override
        public void onMeetingLeft() {
            Log.d("VideoSDK", "onMeetingLeft: ");
        }
        @RequiresApi(api = Build.VERSION_CODES.P)
        @Override
        public void onHlsStateChanged(JSONObject HlsState) {
            if (HlsState.has("status")) {
                try {
                    if (HlsState.getString("status").equals("HLS_PLAYABLE") && HlsState.has("playbackHlsUrl")) {
                        playbackHlsUrl = HlsState.getString("playbackHlsUrl");
                        waitingLayout.setVisibility(View.GONE);
                        playerView.setVisibility(View.VISIBLE);
                        // initialize player
                        initializePlayer();
                    }
                    if (HlsState.getString("status").equals("HLS_STOPPED")) {
                        // release the player
                        releasePlayer();
                        playbackHlsUrl = null;
                        waitingLayout.setText("Host has stopped \n the live streaming");
                        waitingLayout.setVisibility(View.VISIBLE);
                        playerView.setVisibility(View.GONE);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    protected void initializePlayer() {
        if (player == null) {
            dataSourceFactory = new DefaultHttpDataSource.Factory();
            HlsMediaSource mediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(
                    MediaItem.fromUri(Uri.parse(this.playbackHlsUrl)));
            ExoPlayer.Builder playerBuilder =
                    new ExoPlayer.Builder(/* context= */ ViewerActivity.this);
            player = playerBuilder.build();
            // auto play when player is ready
            player.setPlayWhenReady(startAutoPlay);
            player.setMediaSource(mediaSource);
            // if you want display setting for player then remove this line
            playerView.findViewById(com.google.android.exoplayer2.ui.R.id.exo_settings).setVisibility(View.GONE);
            playerView.setPlayer(player);
        }
        player.prepare();
    }
    protected void releasePlayer() {
        if (player != null) {
            player.release();
            player = null;
            dataSourceFactory = null;
            playerView.setPlayer(/* player= */ null);
        }
    }
}
With this, the player is setup to play the HLS.


API Reference
The API references for all the methods utilized in this guide are provided below.
Got a Question? Ask us on discord

