Skip to main content
Version: 0.1.x

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.

app/build.gradle
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.

activity_viewer.xml
<?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_PLAYABLE status you will receive 2 urls
    • playbackHlsUrl - Live HLS with playback support
    • livestreamUrl - Live HLS without playback support
note

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.

ViewerActivity.kt
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
}
}
}

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