Participant Class Methods - Android
Methods marked suspend must be called from a coroutine, for example with lifecycleScope.launch. They throw VideoSDKException when the call is refused or fails.
lifecycleScope.launch {
try {
participant.disableMic()
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "disableMic failed: ${e.code} ${e.name}")
}
}
Called before join(), or while the room is reconnecting, the suspend methods other than captureImage() report 3035 or 3065 on onError and return without throwing. Called while a join is still running, for example from onParticipantJoined() for the people already in the room, they wait for the join to finish first.
enableCam()
enableCam()is asuspendfunction. It asks the participant to turn on their camera.
Events associated with enableCam() :
-
First the participant will get a callback on onWebcamRequested() and once the participant accepts the request, the camera turns on. If they reject it, you are not notified.
-
Every participant that receives the participant's camera gets an
onStreamEnabledevent ofParticipantEventListenerwith thestreamobject. Every participant getsonMediaStatusChanged, including one that joined withcreateRoom(autoConsume = false)and does not receive the camera.
Returns
Unit
disableCam()
disableCam()is asuspendfunction. It turns off the participant's camera. The participant is not asked first.
Events associated with disableCam() :
- Every participant that receives the participant's camera gets an
onStreamDisabledevent ofParticipantEventListenerwith thestreamobject, and every participant getsonMediaStatusChanged.
Throws
VideoSDKExceptionwhen the server refuses the request.
Returns
Unit
enableMic()
enableMic()is asuspendfunction. It asks the participant to turn on their microphone.
Events associated with enableMic() :
-
First the participant will get a callback on onMicRequested() and once the participant accepts the request, the mic turns on. If they reject it, you are not notified.
-
Every participant that receives the participant's microphone gets an
onStreamEnabledevent ofParticipantEventListenerwith thestreamobject. Every participant getsonMediaStatusChanged, including one that joined withcreateRoom(autoConsume = false)and does not receive the microphone.
Returns
Unit
disableMic()
disableMic()is asuspendfunction. It mutes the participant's microphone. The participant is not asked first.
Events associated with disableMic():
- Every participant that receives the participant's microphone gets an
onStreamDisabledevent ofParticipantEventListenerwith thestreamobject, and every participant getsonMediaStatusChanged.
Throws
VideoSDKExceptionwhen the server refuses the request.
Returns
Unit
pin()
-
pin()is asuspendfunction. It pins the participant's camera, screen share or both. -
The pin state is shared with everyone in the room. Your app decides how to show a pinned participant.
Parameters
- pinType:
PinType(optional) - which streams to pin:PinType.SHARE_AND_CAM(the default),PinType.CAMorPinType.SHARE.
Events associated with pin() :
- Every participant will receive an
onPinStateChangedevent, and the participant'spinStateis updated.
Returns
Unit
Example
lifecycleScope.launch {
try {
participant.pin(PinType.CAM)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "pin failed: ${e.code} ${e.name}")
}
}
unpin()
unpin()is asuspendfunction. It releases a pin set withpin(), for the camera, the screen share or both.
Parameters
- pinType:
PinType(optional) - which streams to unpin:PinType.SHARE_AND_CAM(the default),PinType.CAMorPinType.SHARE.
Events associated with unpin() :
- Every participant will receive an
onPinStateChangedevent, and the participant'spinStateis updated.
Returns
Unit
setQuality()
-
setQuality()is asuspendfunction. It picks the quality of the participant's camera video that this device receives. -
It does nothing for the local participant, or when
videoQualityalready has the requested value.
Parameters
- quality:
VideoQuality-VideoQuality.HIGH,VideoQuality.MEDIUMorVideoQuality.LOW.
Throws
VideoSDKExceptionwith code3068(ERROR_ACTION_NOT_SUPPORTED) when this device receives no camera stream from the participant, for example while their camera is off.
Returns
Unit
Example
lifecycleScope.launch {
try {
participant.setQuality(VideoQuality.LOW)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "setQuality failed: ${e.code} ${e.name}")
}
}
setScreenShareQuality()
-
setScreenShareQuality()is asuspendfunction. It picks the quality of the participant's screen share that this device receives. -
It does nothing for the local participant. Unlike
setQuality(), it sends the request every time you call it, even with the same value.
Parameters
- quality:
VideoQuality-VideoQuality.HIGH,VideoQuality.MEDIUMorVideoQuality.LOW.
Throws
VideoSDKExceptionwith code3068(ERROR_ACTION_NOT_SUPPORTED) when this device receives no screen share from the participant.
Returns
Unit
Example
lifecycleScope.launch {
try {
participant.setScreenShareQuality(VideoQuality.HIGH)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "setScreenShareQuality failed: ${e.code} ${e.name}")
}
}
setViewPort()
-
setViewPort()is asuspendfunction. It tells the server how large the view showing the participant is, so this device receives the camera quality that fits it. -
It applies to the participant's camera, not their screen share. Call it when the view showing the participant is laid out, and again when it is resized.
Parameters
- width:
Int- the width of the view in pixels, not dp. - height:
Int- the height of the view in pixels, not dp.
Throws
VideoSDKExceptionwhen this device receives no camera stream from the participant, for example while their camera is off. It also throws on the local participant, so don't call it for your own view.
Returns
Unit
setQuality(), setScreenShareQuality() and setViewPort() choose among the layers the participant sends. A participant who sends a single layer, for example with multiStream turned off or with a codec other than VP8, has only one, so these calls can't change what you receive.
To know more about layers visit here
consumeMicStreams()
-
consumeMicStreams()is asuspendfunction. It starts receiving the participant's microphone on this device. -
Takes effect only when the room was created with
autoConsumeset tofalse. -
Use it in a room joined with
createRoom(autoConsume = false), where remote microphones and cameras are not received until you ask for them. Also use it to receive a microphone again afterstopConsumingMicStreams(). -
It only affects this device and asks nothing of the participant.
-
Called while
join()is still running, for example fromonParticipantJoined, it waits for the join to finish.
Events associated with consumeMicStreams() :
- If the participant's microphone is on, an
onStreamEnabledevent fires on the participant once it arrives.
Returns
Unit
Example
override fun onParticipantJoined(participant: Participant) {
lifecycleScope.launch {
try {
participant.consumeMicStreams()
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "consumeMicStreams failed: ${e.code} ${e.name}")
}
}
}
consumeWebcamStreams()
-
consumeWebcamStreams()is asuspendfunction. It starts receiving the participant's camera on this device. -
Takes effect only when the room was created with
autoConsumeset tofalse. -
Use it in a room joined with
createRoom(autoConsume = false), and to receive a camera again afterstopConsumingWebcamStreams(). LikeconsumeMicStreams(), it only affects this device and waits for a join that is still running.
Events associated with consumeWebcamStreams() :
- If the participant's camera is on, an
onStreamEnabledevent fires on the participant once it arrives.
Returns
Unit
stopConsumingMicStreams()
-
stopConsumingMicStreams()is asuspendfunction. It stops receiving the participant's microphone on this device, which frees that bandwidth. -
Takes effect only when the room was created with
autoConsumeset tofalse. -
The participant is not muted, and everyone else still hears them. Their
audiostream goes away on this device, so a mute indicator based on that stream shows them as muted. -
Call
consumeMicStreams()to receive it again.
Returns
Unit
stopConsumingWebcamStreams()
-
stopConsumingWebcamStreams()is asuspendfunction. It stops receiving the participant's camera on this device, which frees that bandwidth. Use it, for example, for participants scrolled off screen. -
Takes effect only when the room was created with
autoConsumeset tofalse. -
The participant's camera stays on for everyone else. Call
consumeWebcamStreams()to receive it again.
Returns
Unit
remove()
remove()is asuspendfunction. It removes the participant from the room.
Events associated with remove() :
- The removed participant will receive an
onRoomLeftevent. - All other participants will receive an
onParticipantLeftevent with theparticipantand aLeaveReason.
Throws
VideoSDKExceptionwhen the server refuses the request.
Returns
Unit
captureImage()
-
captureImage()is asuspendfunction. It takes a still image from your own camera. -
It works only on the local participant, and only while their camera is on.
-
It returns the image as a
base64string. With video effects on, the image includes them: it is the frame other participants see.
Parameters
- width:
Int(optional) - the maximum width in pixels.0, the default, keeps the camera's own width. - height:
Int(optional) - the maximum height in pixels.0, the default, keeps the camera's own height. - flash:
CaptureFlash(optional) -CaptureFlash.ONlights the scene for about half a second while the image is captured. The camera's flash is used when it has one. A front camera without a flash uses the screen flash set withVideoSDK.setScreenFlash(), and with none set the image is captured unlit.CaptureFlash.OFFis the same as leavingflashout.
captureImage() with no arguments captures the image at the camera's own size.
Returns
String- the image as a base64-encoded JPEG, without adata:prefix.
Throws
VideoSDKExceptionwith code3062(ERROR_WEBCAM_NOT_ENABLED) when the camera is off.VideoSDKExceptionwith code3069(ERROR_CAPTURE_IMAGE_FAILED) when the capture fails. This error is also reported ononError.Error(kotlin.Error, not anException) when called on a remote participant. Acatch (e: Exception)block does not catch it, so callcaptureImage()only onroom.localParticipant.
Example
lifecycleScope.launch {
try {
val base64Image: String = room.localParticipant.captureImage(width = 1280, height = 720)
val bytes = Base64.decode(base64Image, Base64.DEFAULT)
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Capture failed: ${e.code} ${e.name}")
}
}
To light the scene, pass flash. For front cameras without a flash, set a screen flash first:
VideoSDK.setScreenFlash(ScreenFlash.whiteOverlay(this))
lifecycleScope.launch {
try {
val base64Image = room.localParticipant.captureImage(flash = CaptureFlash.ON)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Capture failed: ${e.code} ${e.name}")
}
}
getVideoStats()
-
getVideoStats()returns the metrics of the participant's camera video, such as jitter, packet loss and bitrate, as aJSONArray. -
It has one entry per video layer: one for each layer your own camera sends, and one for a remote participant's camera.
Returns
JSONArray?-nullwhen the participant has no video stream, or the stats could not be read. Each entry contains:jitter: It represents the variation in packet arrival time, in milliseconds (ms). Measured only on streams this device receives, so it reads0for the local participant.bitrate: It represents the bitrate of the stream which is being transmitted, in kbps.totalPackets: It represents the packets transmitted for the stream since the previous sample, not a running total.packetsLost: It represents the packets lost since the previous sample, not a running total.rtt: It represents the round-trip time between this device and the server, in milliseconds (ms). Measured only on streams this device sends, so it reads0for a remote participant.codec: It represents the codec used for the stream.size: It is an object containing theheight,widthandframerateof the stream.
Example
val videoStats: JSONArray? = participant.getVideoStats() // will return all possible stream layers, or null
val videoStat: JSONObject? = videoStats?.optJSONObject(0) // will return the first stream layer
getVideoStats() returns the metrics at the moment you call it, not an average over the session. The values refresh at most every 400 ms, so reading them about once a second is enough. Read each value with an opt method, such as optDouble("rtt"), because a value the SDK cannot measure can be missing.
To view the metrics for the complete session, use the stats API documented here.
If you are getting rtt greater than 300ms, try using a different region which is nearest to your user. To know more about changing region visit here.
If you are getting high packet loss, try using a custom camera track for better experience. To know more about custom tracks visit here
getAudioStats()
getAudioStats()returns the metrics of the participant's microphone audio, such as jitter, packet loss and bitrate, as aJSONObject.
Returns
JSONObject?-nullwhen the participant has no audio stream, or the stats could not be read. It contains:jitter: It represents the variation in packet arrival time, in milliseconds (ms). Measured only on streams this device receives, so it reads0for the local participant.bitrate: It represents the bitrate of the stream which is being transmitted, in kbps.totalPackets: It represents the packets transmitted for the stream since the previous sample, not a running total.packetsLost: It represents the packets lost since the previous sample, not a running total.rtt: It represents the round-trip time between this device and the server, in milliseconds (ms). Measured only on streams this device sends, so it reads0for a remote participant.codec: It represents the codec used for the stream.
Example
val audioStat: JSONObject? = participant.getAudioStats()
getAudioStats() returns the metrics at the moment you call it, not an average over the session.
To view the metrics for the complete session, use the stats API documented here.
If you are getting rtt greater than 300ms, try using a different region which is nearest to your user. To know more about changing region visit here.
getShareStats()
getShareStats()returns the metrics of the participant's screen share, such as jitter, packet loss and bitrate, as aJSONObject.
Returns
JSONObject?-nullwhen the participant is not sharing their screen, or the stats could not be read. It contains:jitter: It represents the variation in packet arrival time, in milliseconds (ms). Measured only on streams this device receives, so it reads0for the local participant.bitrate: It represents the bitrate of the stream which is being transmitted, in kbps.totalPackets: It represents the packets transmitted for the stream since the previous sample, not a running total.packetsLost: It represents the packets lost since the previous sample, not a running total.rtt: It represents the round-trip time between this device and the server, in milliseconds (ms). Measured only on streams this device sends, so it reads0for a remote participant.codec: It represents the codec used for the stream.size: It is an object containing theheight,widthandframerateof the stream.
Example
val shareStat: JSONObject? = participant.getShareStats()
getShareStats() returns the metrics at the moment you call it, not an average over the session.
To view the metrics for the complete session, use the stats API documented here.
If you are getting rtt greater than 300ms, try using a different region which is nearest to your user. To know more about changing region visit here.
getShareAudioStats()
getShareAudioStats()returns the metrics of the audio shared with the participant's screen share, as aJSONArray. The microphone is not included; usegetAudioStats()for it. It isnullfor a participant sharing from Android, whose shared audio travels in the microphone stream.
Returns
JSONArray?-nullwhen the screen share carries no audio, or the stats could not be read. Each entry contains the same values asgetAudioStats().
Example
val shareAudioStats: JSONArray? = participant.getShareAudioStats()
getTransportStats()
-
getTransportStats()returns the participant's network transport metrics as aJSONObject: how much media data flows in and out over their connection. -
It waits for the server to answer, so call it off the main thread.
Returns
-
JSONObject?-nulloutside a room, before the connection is set up, or when the request fails. It contains:send: the data the participant uploads.outgoingBitrate: the upload bitrate, in kbps.totalSentBytes: the total bytes sent.
receive: the data the participant downloads.incomingBitrate: the download bitrate, in kbps.totalReceivedBytes: the total bytes received.
Right after joining, before media flows, these values can be
null.
Example
lifecycleScope.launch {
val transportStats: JSONObject? = withContext(Dispatchers.IO) {
participant.getTransportStats()
}
val uploadKbps = transportStats?.optJSONObject("send")?.optDouble("outgoingBitrate")
}
isAgent()
-
isAgent()returnstruewhen the participant is an AI agent. Call it as a function:participant.isAgent(). -
An agent is an
AgentParticipant(packagelive.videosdk.rtc.android.agent). Cast it withparticipant as? AgentParticipantto readgetAgentId(), the ID of the configured agent, andgetAgentState(), its last reportedAgentState. The agent events ofParticipantEventListenerfire on it. -
The agent controls its own media. On an agent,
enableMic(),disableMic(),enableCam(),disableCam(),setQuality(),captureImage()andgetShareStats()always throwUnsupportedOperationException. This is by design, andcatch (e: VideoSDKException)doesn't catch it, so checkisAgent()before calling them, for example when a host mutes everyone.
Returns
Boolean
addEventListener()
-
addEventListener()adds aParticipantEventListenerto the participant. A participant can have several listeners. -
It calls
onStreamEnabled()straight away, on the calling thread, for every stream the participant already has.
Parameters
- listener: ParticipantEventListener
Returns
Unit
removeEventListener()
Parameters
- listener: ParticipantEventListener
Returns
Unit
removeAllEventListeners()
removeAllEventListeners()removes everyParticipantEventListeneradded to the participant.
Returns
Unit
Got a Question? Ask us on discord

