Play a live stream
Show a live stream to viewers with one composable.
Prerequisites
net.bunny:playerdependencyBunnyStreamApi.initialize(...)called, see Getting started- Jetpack Compose (the live player is Compose-only)
- The stream's GUID, from the dashboard or from Manage live streams
Basic playback
BunnyLiveStreamPlayer(
libraryId = 12345L,
streamId = "stream-guid",
modifier = Modifier
.fillMaxWidth()
.aspectRatio(16f / 9f),
)
libraryId must be the same library the SDK was initialized with.
What the player does for you
The composable renders the correct screen for the stream's state and moves between states on its own; you never refresh or reconnect manually:
- Scheduled stream: a countdown to the start time, over the stream thumbnail.
- Pre-stream trailer configured: the trailer plays in a muted loop instead of the thumbnail.
- Encoder connected, stream started: live playback with the standard controls and a LIVE badge.
- Stream with DVR: viewers can pause and seek back within the DVR window, and jump back to the live edge with one tap. Without DVR the timeline is hidden.
- Playback hiccup mid-stream: the player recovers on its own.
- Stream ends: if the stream records a VOD, the player switches to the recording, with a normal seek bar.
- Stream offline or over: an offline screen with the stream thumbnail.
The player checks the stream status every few seconds and connects automatically the moment the stream goes live.
Reading stream state from your UI
To show your own metadata next to the player (title, viewer count, status), read the view model's state flows:
val viewModel: BunnyLiveStreamPlayerViewModel = viewModel()
BunnyLiveStreamPlayer(
libraryId = libraryId,
streamId = streamId,
viewModel = viewModel,
)
val stream by viewModel.liveStream.collectAsStateWithLifecycle()
Text(stream?.title.orEmpty())
Vertical (9:16) streams
The player reports the real video size, so your container can adapt:
var aspect by remember { mutableStateOf(16f / 9f) }
BunnyLiveStreamPlayer(
libraryId = libraryId,
streamId = streamId,
onVideoSizeChanged = { w, h -> if (w > 0 && h > 0) aspect = w.toFloat() / h },
modifier = Modifier.fillMaxWidth().aspectRatio(aspect),
)
Appearance
The live player is configured from the Bunny dashboard (Stream > your library > Player): accent color, font, UI language, which controls are visible, compact mode. There is no code-side configuration object; change the dashboard and the player follows.
Token-protected libraries
Pass a playback token, same as for videos - see Secure playback:
BunnyLiveStreamPlayer(libraryId, streamId, token = token, expires = expires)
Gotchas
- An ended stream cannot go live again. The player will show the recording (when the stream recorded one) or the offline screen. Start a new stream for a new broadcast.
- The countdown appears only for streams with a scheduled start time.
- Casting and Picture-in-Picture follow the same host-app requirements as the video player, see Picture-in-Picture and Chromecast.
Working example: LiveStreamPlayerScreen in the demo app.