Skip to main content
Version: 3.x.x

Interactive Livestream (HLS) - Android

Interactive live streaming (HLS) refers to a type of live streaming where viewers can actively engage with the content being streamed and with other viewers in real-time.

In an interactive live stream (HLS), viewers can take part in a variety of activities like live polling, Q&A sessions, and even sending virtual gifts to the content creator or each other.

You can set the interactive livestream layout with a prebuilt layout in the configuration, or with your own custom template.

This guide shows how to start and stop interactive live streaming (HLS).

important

To start HLS automatically when a session begins, set hls in autoStartConfig when you create the room with the Create Room API.

startHLS()​

room.startHLS() starts an interactive livestream of the room. It takes two parameters:

  • config: An HLSConfig that defines how the interactive livestream layout should look. HLSConfig and its value types (ConfigLayout, ConfigLayoutGrid, ConfigLayoutPriority, ConfigTheme, ConfigMode, ConfigQuality, ConfigOrientation) are in the live.videosdk.rtc.android.model package. It defaults to null, which uses the defaults. A field left null takes the server's default.

  • transcription: A PostTranscriptionConfig that transcribes the stream once it ends. It defaults to null, which skips it.

note
  • startHLS() and stopHLS() are suspend functions. Call them from a coroutine, such as lifecycleScope.launch (from androidx.lifecycle:lifecycle-runtime-ktx).
  • They return once the request is sent, not when the stream has started or stopped. Wait for onHlsStateChanged to report HLS_PLAYABLE before you play the stream.
  • If the request fails, they throw VideoSDKException.
  • Called before the room is joined, or while it is reconnecting, they do nothing and report 3035 (ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED) or 3065 (ERROR_ROOM_RECONNECTING) on onError instead of throwing.
// Layout Configuration
val layout = ConfigLayout(
type = ConfigLayoutGrid.GRID, // SPOTLIGHT | SIDEBAR, Default : GRID
priority = ConfigLayoutPriority.SPEAKER, // PIN, Default : SPEAKER
gridSize = 4, // MAX : 25
)

val config = HLSConfig(
layout = layout,
// Theme of interactive livestream layout
theme = ConfigTheme.DARK, // LIGHT | DEFAULT
// `mode`: stream video and audio, or audio only.
mode = ConfigMode.VIDEO_AND_AUDIO, // AUDIO, Default : VIDEO_AND_AUDIO
// Quality of interactive livestream, only applicable to VIDEO_AND_AUDIO mode.
// LOW (SD HLS) | MED (HD HLS) | HIGH (FHD HLS)
quality = ConfigQuality.HIGH,
// Orientation of the interactive livestream.
// LANDSCAPE : Start interactive livestream of the room horizontally
// PORTRAIT : Start interactive livestream of the room vertically (Best for mobile view)
orientation = ConfigOrientation.PORTRAIT, // LANDSCAPE, Default : LANDSCAPE
)

// Post Transcription Configuration
val prompt = "Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
val summaryConfig = SummaryConfig(true, prompt)
val modelId = "raman_v1"
val transcription = PostTranscriptionConfig(true, summaryConfig, modelId)

lifecycleScope.launch {
try {
room!!.startHLS(config, transcription)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Start HLS failed: ${e.code} ${e.name}")
}
}

stopHLS()​

  • room.stopHLS() stops the interactive livestream of the room.

Example​

// keep track of hls, updated in onHlsStateChanged below
var isHlsStarted = false

findViewById<View>(R.id.btnHls).setOnClickListener { view: View? ->
lifecycleScope.launch {
try {
if (!isHlsStarted) {
val config = HLSConfig(
layout = ConfigLayout(ConfigLayoutGrid.GRID, ConfigLayoutPriority.SPEAKER, 4),
theme = ConfigTheme.DARK,
mode = ConfigMode.VIDEO_AND_AUDIO,
quality = ConfigQuality.HIGH,
orientation = ConfigOrientation.PORTRAIT,
)

// Post Transcription Configuration
val prompt = "Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
val summaryConfig = SummaryConfig(true, prompt)
val modelId = "raman_v1"
val transcription = PostTranscriptionConfig(true, summaryConfig, modelId)

// Start Hls
room!!.startHLS(config, transcription)
} else {
// Stop Hls
room!!.stopHLS()
}
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "HLS request failed: ${e.code} ${e.name}")
}
}
}
tip

If you want to learn more about the Interactive Livestream and how you can implement it in your own platform, you can check out this guide.

Event associated with HLS​

  • onHlsStateChanged - Triggered whenever the room's HLS state changes.

  • onHlsStateChanged receives the new HLSState and an HLSUrl?. When the state changes to HLS_PLAYABLE, read hlsUrl.playbackHlsUrl to play the stream on the viewer side. hlsUrl is null with every other state.

note

HLS_STARTED only means the server accepted the request. Wait for HLS_PLAYABLE before you play the stream.

private val roomEventListener: RoomEventListener = object : RoomEventListener() {
override fun onHlsStateChanged(state: HLSState, hlsUrl: HLSUrl?) {
when (state) {
HLSState.HLS_STARTING -> Log.d("onHlsStateChanged", "HLS is starting")
HLSState.HLS_STARTED -> {
isHlsStarted = true
Log.d("onHlsStateChanged", "HLS is started")
}
HLSState.HLS_PLAYABLE -> {
Log.d("onHlsStateChanged", "HLS is playable now")
// on hls playable you will receive the playback URL
val playbackHlsUrl = hlsUrl?.playbackHlsUrl
}
HLSState.HLS_STOPPING -> Log.d("onHlsStateChanged", "HLS is stopping")
HLSState.HLS_STOPPED -> {
isHlsStarted = false
Log.d("onHlsStateChanged", "HLS is stopped")
}
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
//...

// add listener to room
room!!.addEventListener(roomEventListener)
}

API Reference​

The API references for all the methods utilised in this guide are provided below.

Got a Question? Ask us on discord