val isCameraEnabled by call.camera.isEnabled.collectAsState()
val isMicrophoneEnabled by call.microphone.isEnabled.collectAsState()
CallLobby(
call = call,
modifier = Modifier.fillMaxWidth(),
isCameraEnabled = isCameraEnabled,
isMicrophoneEnabled = isMicrophoneEnabled,
)Call Lobby
The call lobby displays a local video preview before joining a call. It allows you to control the camera, microphone, and permissions before joining. The call lobby consists of these components:
- onRenderedContent: A video renderer, which renders a local video track before joining a call.
- onDisabledContent: Content is shown that a local camera is disabled. It displays user avatar by default.
- lobbyControlsContent: Content is shown that allows users to trigger different actions to control a preview call.
- onCallAction: Handler when the user triggers a Call Control Action.
Here's how to implement a basic call lobby:
After running your project, you'll see the result below:

Control Actions
Similar to CallContent, and CallLobby supports these main action handlers with the onCallAction lambda:
CallLobby(
call = call,
modifier = Modifier.fillMaxWidth(),
isCameraEnabled = isCameraEnabled,
isMicrophoneEnabled = isMicrophoneEnabled,
onCallAction = { action ->
when (action) {
is ToggleCamera -> call.camera.setEnabled(action.isEnabled)
is ToggleMicrophone -> call.microphone.setEnabled(action.isEnabled)
else -> Unit
}
}
)You can customize the control actions by implementing your own composable for the lobbyControlsContent like the code below:
CallLobby(
call = call,
modifier = Modifier.fillMaxWidth(),
isCameraEnabled = isCameraEnabled,
isMicrophoneEnabled = isMicrophoneEnabled,
lobbyControlsContent = {
ControlActions(
call = call,
actions = listOf(
{
ToggleCameraAction(
isCameraEnabled = isCameraEnabled,
onCallAction = { }
)
},
{
ToggleMicrophoneAction(
isMicrophoneEnabled = isMicrophoneEnabled,
onCallAction = { }
)
}
)
)
},
..
)Then you'll see the result below:

Permission Requests
The call lobby needs to get permission to access the camera and microphone. CallLobby implements the permission request by default, so you don't need to do anything to request permission from your side. If you implement the CallLobby composable, it will ask you to grant camera and microphone permission like the image below:

You can also customize what permission you want to ask by passing a list of permission to the permission parameter like the example below:
CallLobby(
permissions: VideoPermissionsState = rememberCallPermissionsState(
call = call,
permissions = listOf(
android.Manifest.permission.CAMERA,
android.Manifest.permission.RECORD_AUDIO,
..
),
),
..
)If you don't want to let CallLobby request permissions and want to handle them manually from your side, you can just pass an empty list like the code below:
CallLobby(
permissions: VideoPermissionsState = rememberCallPermissionsState(
call = call,
permissions = listOf()
),
..
)Preview For Disabled Camera
The CallLobby component displays a user avatar when the camera lacks permission or is disabled.

You can customize the preview component by implementing your own composable to the onDisabledContent composable parameter:
CallLobby(
call = call,
modifier = Modifier.fillMaxWidth(),
onDisabledContent = {
Box(modifier = Modifier.fillMaxSize()) {
Text(
modifier = Modifier.align(Alignment.Center),
text = "Camera is disabled",
color = VideoTheme.colors.textHighEmphasis
)
}
},
..
)After building the project, you'll see the result below:

Customization
The CallLobby component has more options when it comes to customization. It exposes the following parameters that let you change its UI:
@Composable
public fun CallLobby(
modifier: Modifier = Modifier,
call: Call,
user: User = StreamVideo.instance().user,
labelPosition: Alignment = Alignment.BottomStart,
isCameraEnabled: Boolean,
isMicrophoneEnabled: Boolean,
video: ParticipantState.Video,
permissions: VideoPermissionsState,
onRenderedContent: @Composable (video: ParticipantState.Video) -> Unit,
onDisabledContent: @Composable () -> Unit,
onCallAction: (CallAction) -> Unit,
lobbyControlsContent: @Composable (call: Call) -> Unit
)modifier: The standard Jetpack Compose modifier used to style things like the component size, background, shape and similar.callThe call includes states and will be rendered with participants.userA user to display their name and avatar image on the preview.labelPositionThe position of the user audio state label.videoA participant video to render on the preview renderer.permissionsAndroid permissions that should be required to render a video call properly.onRenderedContentA video renderer, which renders a local video track before joining a call.onDisabledContentContent is shown that a local camera is disabled. It displays user avatar by default.onCallActionHandler when the user triggers a Call Control Action.lobbyControlsContentContent is shown that allows users to trigger different actions to control a preview call.