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).
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: AnHLSConfigthat defines how the interactive livestream layout should look.HLSConfigand its value types (ConfigLayout,ConfigLayoutGrid,ConfigLayoutPriority,ConfigTheme,ConfigMode,ConfigQuality,ConfigOrientation) are in thelive.videosdk.rtc.android.modelpackage. It defaults tonull, which uses the defaults. A field leftnulltakes the server's default. -
transcription: APostTranscriptionConfigthat transcribes the stream once it ends. It defaults tonull, which skips it.
startHLS()andstopHLS()aresuspendfunctions. Call them from a coroutine, such aslifecycleScope.launch(fromandroidx.lifecycle:lifecycle-runtime-ktx).- They return once the request is sent, not when the stream has started or stopped. Wait for
onHlsStateChangedto reportHLS_PLAYABLEbefore 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) or3065(ERROR_ROOM_RECONNECTING) ononErrorinstead 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}")
}
}
}
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.
-
onHlsStateChangedreceives the newHLSStateand anHLSUrl?. When the state changes toHLS_PLAYABLE, readhlsUrl.playbackHlsUrlto play the stream on the viewer side.hlsUrlisnullwith every other state.
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

