Skip to main content
Version: 3.x.x

Pin/Unpin Participants - Android

In a live stream setup, you often want to control which participant is actively visible on screen — whether it’s the host, a special guest, or someone screen sharing. To manage this dynamically, the Participant class provides two key methods:

  • pin() – Focus on a specific participant’s camera or screen share

  • unpin() – Remove that focus and return to the default layout

This allows you to programmatically decide who gets the spotlight in your live stream layout.

pin()​

Call pin() on a Participant to pin their camera, screen share or both for everyone in the live stream. The pin is room-wide state: every participant gets onPinStateChanged, and your layout code decides where to place the pinned host, for example fullscreen or in a highlighted position.

pin() is a suspend function, so call it from a coroutine such as lifecycleScope.launch. Pass PinType.CAM or PinType.SHARE to pin only the camera or only the screen share; with no argument it pins both (PinType.SHARE_AND_CAM). Before the live stream is joined, or while it is reconnecting, pin() reports 3035 or 3065 on onError and returns without throwing.

private fun pinParticipant(participant: Participant) {
lifecycleScope.launch {
try {
participant.pin(PinType.SHARE_AND_CAM)
Toast.makeText(context, "Participant pinned", Toast.LENGTH_SHORT).show()
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "pin failed: ${e.code} ${e.message}")
}
}
}

unpin()​

When a host is no longer the focus, for example when their segment is over, call unpin() to clear their pin. Your layout code can then go back to the default grid or promote the next speaker.

unpin() is also a suspend function and takes the same values as pin().

private fun unpinParticipant(participant: Participant) {
lifecycleScope.launch {
try {
participant.unpin(PinType.SHARE_AND_CAM)
Toast.makeText(context, "Participant unpinned", Toast.LENGTH_SHORT).show()
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "unpin failed: ${e.code} ${e.message}")
}
}
}

Events associated with pin/unpin​

The following callbacks are received when a host is pinned or unpinned in the livestream.

  • Every participant, hosts and audience alike, receives onPinStateChanged event with the participantId of the participant whose pin changed, their state as a ParticipantPinState with the booleans cam and share, and pinnedBy, the participant who made the change (null when the server did not say). Both false means the participant is unpinned. participant.pinState already holds the new state.
private val roomEventListener = object : RoomEventListener() {
override fun onPinStateChanged(participantId: String, state: ParticipantPinState, pinnedBy: String?) {
Log.d("VideoSDK", "onPinStateChanged: $participantId $state by $pinnedBy")

room?.let {
val participant = it.participants[participantId] ?: it.localParticipant
val name = participant.displayName
val pinned = state.cam || state.share
Toast.makeText(this@MainActivity, if (pinned) "Pinned $name" else "Unpinned $name", Toast.LENGTH_SHORT).show()
}
}
}

info
  • Based on the onPinStateChanged event, you should update your live stream layout for all participants (including the audience) to reflect the current pinned participant. This means conditionally rendering the pinned participant in the main view or spotlight area across all clients.

API Reference​

The API references for all the methods and events utilized in this guide are provided below.

Got a Question? Ask us on discord