Package-level declarations
Functions
Link copied to clipboard
fun LivestreamPlayer(modifier: Modifier = Modifier, call: Call, enablePausing: Boolean = true, onPausedPlayer: (isPaused: Boolean) -> Unit? = {}, backstageContent: @Composable BoxScope.(Call) -> Unit = {
LivestreamBackStage(call)
}, videoRendererConfig: VideoRendererConfig = videoRenderConfig(), livestreamFlow: Flow<ParticipantState.Video?> = call.state.participants.flatMapLatest { participants ->
// Re-sort by ingress source priority before picking. The grid-level preset
// already orders ingress sources first, but applying the livestream-specific
// priority here makes the picker independent of whatever preset is active —
// changing the grid preset cannot accidentally affect the livestream host.
// Stable sort preserves the upstream order among equal-priority participants.
val sorted = participants.sortedWith(
bySourcePriority(
ParticipantSource.PARTICIPANT_SOURCE_RTMP,
ParticipantSource.PARTICIPANT_SOURCE_WHIP,
ParticipantSource.PARTICIPANT_SOURCE_SRT,
ParticipantSource.PARTICIPANT_SOURCE_RTSP,
),
)
if (sorted.isEmpty()) {
flow { emit(null) }
} else {
combine(
sorted.map { participant ->
participant.videoEnabled.map { enabled -> participant to enabled }
},
) { pairs ->
pairs.firstOrNull { (_, enabled) -> enabled }?.first
}
}
}.flatMapLatest { participant ->
participant?.video ?: flow { emit(null) }
}, rendererContent: @Composable BoxScope.(Call) -> Unit = defaultRenderer, overlayContent: @Composable BoxScope.(Call) -> Unit = defaultLivestreamPlayerOverlay, liveStreamEndedContent: @Composable BoxScope.(Call) -> Unit = {
LivestreamEndedUi(call)
}, liveStreamHostVideoNotAvailableContent: @Composable BoxScope.(Call) -> Unit = {
HostVideoNotAvailableUi(call)
}, liveStreamErrorContent: @Composable BoxScope.(Call, () -> Unit) -> Unit = { _, retryJoin ->
LivestreamErrorUi(call, retryJoin)
}, onRetryJoin: () -> Unit = {})
Renders a livestream video player UI based on the current state of the provided call.