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
onPinStateChangedevent with theparticipantIdof the participant whose pin changed, theirstateas aParticipantPinStatewith the booleanscamandshare, andpinnedBy, the participant who made the change (nullwhen the server did not say). Bothfalsemeans the participant is unpinned.participant.pinStatealready 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()
}
}
}
- Based on the
onPinStateChangedevent, 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

