Skip to main content
Version: 4.x.x

Participant Class Methods - iOS

note

Methods marked async throws must be called with try await from an async context, such as a Task. When a call is refused or fails, it throws a VideoSDKError. Read its code, name and message.

Task {
do {
try await participant.disableMic()
} catch let error as VideoSDKError {
print("disableMic failed: \(error.code) \(error.name) \(error.message)")
} catch {
print("disableMic failed: \(error)")
}
}

Every async throws method except captureImage() throws ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) when it is called before the room is joined or after you leave, and ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting. The same error is also sent to onError(), so don't show it to the user twice.

On an agent participant (isAgent() returns true), enableMic(), disableMic(), enableCam(), disableCam(), setQuality(), captureImage() and getShareStats() throw ERROR_ACTION_NOT_SUPPORTED (3068).

enableCam()​

  • enableCam() is used to ask a remote participant to turn on their webcam. It is async throws.
  • It works only on remote participants. To turn on your own webcam, use enableCam() of the Room class.

Events associated with enableCam():​

  • First the participant will get a callback on onWebcamRequested() and once the participant accepts the request, webcam will be enabled.

  • Every participant that receives the participant's video will get an onStreamEnabled() event with the stream object.

Returns​

  • Void

disableCam()​

  • disableCam() is used to turn off the webcam of a remote participant. It is async throws.
  • The webcam turns off right away. The participant is not asked first.
  • It works only on remote participants. To turn off your own webcam, use disableCam() of the Room class.

Events associated with disableCam():​

  • Every participant that receives the participant's video will get an onStreamDisabled() event with the stream object.

Returns​

  • Void

enableMic()​

  • enableMic() is used to ask a remote participant to turn on their mic. It is async throws.
  • It works only on remote participants. To turn on your own mic, use unmuteMic() of the Room class.

Events associated with enableMic():​

  • First the participant will get a callback on onMicRequested() and once the participant accepts the request, mic will be enabled.

  • Every participant that receives the participant's audio will get an onStreamEnabled() event with the stream object.

Returns​

  • Void

disableMic()​

  • disableMic() is used to turn off the mic of a remote participant. It is async throws.
  • The mic turns off right away. The participant is not asked first.
  • It works only on remote participants. To turn off your own mic, use muteMic() of the Room class.

Events associated with disableMic():​

  • Every participant that receives the participant's audio will get an onStreamDisabled() event with the stream object.

Returns​

  • Void

setQuality()​

  • setQuality() is used to set the quality of the participant's video stream that this device receives. It is async throws.
  • It does nothing for the local participant, or when videoQuality already has the requested value.

Parameters​

  • quality: VideoQuality (.low | .medium | .high)

Throws​

  • ERROR_ACTION_NOT_SUPPORTED (3068) when this device receives no video from the participant's webcam, for example while it is off.

Returns​

  • Void

Example​

Task {
do {
try await participant.setQuality(.low)
} catch let error as VideoSDKError {
print("setQuality failed: \(error.code) \(error.name)")
} catch {
print("setQuality failed: \(error)")
}
}

setScreenShareQuality()​

  • setScreenShareQuality() is used to set the quality of the participant's screen share that this device receives. It is async throws.
  • It changes only the screen share. The webcam video keeps its quality.

Parameters​

  • quality: VideoQuality (.low | .medium | .high)

Throws​

  • ERROR_ACTION_NOT_SUPPORTED (3068) when this device receives no screen share from the participant.

Returns​

  • Void

setViewPort()​

  • setViewPort() is used to tell the SDK the size at which the participant's webcam video is shown, so that the server sends a quality that fits it. It is async throws.
  • Call it when the view is laid out, and again when it is resized. It applies to the webcam video, not to the screen share.

Parameters​

  • width: Int - the width of the view, in pixels (not points).
  • height: Int - the height of the view, in pixels (not points).

Throws​

  • A VideoSDKError when this device receives no video from the participant's webcam, for example while it is off. It also throws for the local participant, so call it only for remote participants.

Returns​

  • Void

Example​

let scale = videoView.traitCollection.displayScale
let width = Int(videoView.bounds.width * scale)
let height = Int(videoView.bounds.height * scale)

Task {
do {
try await participant.setViewPort(width: width, height: height)
} catch {
print("setViewPort failed: \(error)")
}
}
info

setQuality(), setScreenShareQuality() and setViewPort() choose among the layers the participant publishes. If the participant publishes a single layer, for example with multiStream set to false, these calls can't change what you receive. To know more about layers, see Simulcast.


consumeMicStreams()​

  • consumeMicStreams() is used to start receiving the participant's audio on this device. It is async throws.
  • Takes effect only when the room was created with autoConsume set to false. See createRoom(). In such a room, remote audio and video are not received until you ask for them. Also use it to receive the audio again after stopConsumingMicStreams().
  • It changes only what this device receives. The participant is not asked.
  • Call it after the room is joined. Participants who were already in the room are reported through onParticipantJoined() before onRoomJoined(), so start receiving them from onRoomJoined().

Events associated with consumeMicStreams():​

  • If the participant's mic is on, an onStreamEnabled() event is triggered once their audio arrives.

Returns​

  • Void

Example​

In this example, hasJoined is a Bool property of your view controller that starts as false.

extension RoomViewController: RoomEventListener {
func onRoomJoined() {
hasJoined = true
// Participants who were already in the room
room?.participants.values.forEach { receiveMedia(of: $0) }
}

func onParticipantJoined(_ participant: Participant) {
// Participants who join later
if hasJoined {
receiveMedia(of: participant)
}
}

func receiveMedia(of participant: Participant) {
Task {
do {
try await participant.consumeMicStreams()
try await participant.consumeWebcamStreams()
} catch {
print("Could not receive media of \(participant.displayName): \(error)")
}
}
}
}

consumeWebcamStreams()​

  • consumeWebcamStreams() is used to start receiving the participant's webcam video on this device. It is async throws.
  • It works like consumeMicStreams(), for video. Takes effect only when the room was created with autoConsume set to false. Use it to receive a participant's video, or to receive it again after stopConsumingWebcamStreams().

Events associated with consumeWebcamStreams():​

  • If the participant's webcam is on, an onStreamEnabled() event is triggered once their video arrives.

Returns​

  • Void

stopConsumingMicStreams()​

  • stopConsumingMicStreams() is used to stop receiving the participant's audio on this device, which saves bandwidth. It is async throws.
  • Takes effect only when the room was created with autoConsume set to false.
  • The participant is not muted, and everyone else still hears them. Call consumeMicStreams() to receive the audio again.

Returns​

  • Void

stopConsumingWebcamStreams()​

  • stopConsumingWebcamStreams() is used to stop receiving the participant's webcam video on this device, which saves bandwidth. Use it, for example, for participants who are not on screen. It is async throws.
  • Takes effect only when the room was created with autoConsume set to false.
  • The participant's webcam stays on for everyone else. Call consumeWebcamStreams() to receive the video again.

Returns​

  • Void

remove()​

  • remove() is used to remove this participant from the room. It is async throws.

Events associated with remove():​

  • The removed participant will receive an onRoomLeft(reason:) event.
  • All other participants will receive an onParticipantLeft(_:reason:) event of the Room class.

Returns​

  • Void

pin()​

  • pin() is used to pin this participant's webcam, screen share, or both. It is async throws.
  • The pin state is shared with everyone in the room. Your app decides how to show a pinned participant.

Parameters​

  • pinType: PinType (Optional) - .SHARE_AND_CAM (default), .CAM or .SHARE.

Events associated with pin():​

Returns​

  • Void

Example​

Task {
do {
try await participant.pin(.CAM)
} catch {
print("pin failed: \(error)")
}
}

unpin()​

  • unpin() is used to unpin this participant's webcam, screen share, or both. It is async throws.

Parameters​

  • pinType: PinType (Optional) - .SHARE_AND_CAM (default), .CAM or .SHARE.

Events associated with unpin():​

Returns​

  • Void

getAudioStats()​

  • getAudioStats() will return an array which will contain details regarding the participant's critical audio metrics such as Jitter, Packet Loss etc.
  • It returns the values at the moment you call it, not averages over the whole time in the room.

Returns​

  • Any? - an array of dictionaries ([[String: Any]]). Each entry contains:
    • jitter : It represents the variation in packet arrival time, in milliseconds (ms).
    • bitrate : It represents the bitrate of the stream which is being transmitted, in kbps.
    • totalPackets : It represents the packets transmitted 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).
    • codec: It represents the codec used for the stream.
  • It returns nil before the room is joined, after you leave, or while the room is reconnecting. The array is empty when there is no audio stream, or no stats are available yet.

Example​

if let audioStats = participant.getAudioStats() as? [[String: Any]],
let stats = audioStats.first {
print("Audio bitrate: \(stats["bitrate"] ?? 0) kbps")
}

getVideoStats()​

  • getVideoStats() will return an array which will contain details regarding the participant's critical video metrics such as Jitter, Packet Loss etc.
  • It has one entry per video layer: one for each layer your own webcam sends, and one for the webcam video of a remote participant.

Returns​

  • Any? - an array of dictionaries ([[String: Any]]). Each entry contains:
    • jitter : It represents the variation in packet arrival time, in milliseconds (ms).
    • bitrate : It represents the bitrate of the stream which is being transmitted, in kbps.
    • totalPackets : It represents the packets transmitted 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).
    • codec: It represents the codec used for the stream.
    • size: It is a dictionary containing the width, height and, when known, framerate of the stream.
  • It returns nil before the room is joined, after you leave, or while the room is reconnecting. The array is empty when there is no webcam video, or no stats are available yet.

Example​

if let videoStats = participant.getVideoStats() as? [[String: Any]] {
for layer in videoStats {
print("Video bitrate: \(layer["bitrate"] ?? 0) kbps, size: \(layer["size"] ?? [:])")
}
}

getShareStats()​

  • getShareStats() will return an array which will contain details regarding the participant's critical screen share metrics such as Jitter, Packet Loss etc.
  • Call it with try. It throws only on an agent participant.

Returns​

  • Any? - an array of dictionaries ([[String: Any]]). Each entry contains:
    • jitter : It represents the variation in packet arrival time, in milliseconds (ms).
    • bitrate : It represents the bitrate of the stream which is being transmitted, in kbps.
    • totalPackets : It represents the packets transmitted 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).
    • codec: It represents the codec used for the stream.
    • size: It is a dictionary containing the width, height and, when known, framerate of the stream.
  • It returns nil before the room is joined, after you leave, or while the room is reconnecting. The array is empty when the participant is not sharing their screen, or no stats are available yet.

Example​

do {
if let shareStats = try participant.getShareStats() as? [[String: Any]] {
print("Screen share bitrate: \(shareStats.first?["bitrate"] ?? 0) kbps")
}
} catch {
print("getShareStats failed: \(error)")
}

getShareAudioStats()​

  • getShareAudioStats() will return an array with the metrics of the audio shared along with the participant's screen share. The mic is not included; use getAudioStats() for it.

Returns​

  • Any? - an array of dictionaries ([[String: Any]]). Each entry contains the same values as getAudioStats().
  • It returns nil before the room is joined, after you leave, or while the room is reconnecting. The array is empty when the screen share has no audio.

Example​

let shareAudioStats = participant.getShareAudioStats() as? [[String: Any]]

getTransportStats()​

  • getTransportStats() will return the participant's network transport metrics: how much data flows in and out over their connection, for all their streams together.
  • It waits for a reply from the server, so call it off the main thread.

Returns​

  • Any? - a dictionary ([String: Any]) containing:
    • send: the data the participant sends.
      • outgoingBitrate: the send bitrate, in kbps.
      • totalSentBytes: the total bytes sent.
    • receive: the data the participant receives.
      • incomingBitrate: the receive bitrate, in kbps.
      • totalReceivedBytes: the total bytes received.
  • It returns nil before the room is joined, after you leave, while the room is reconnecting, or when the request fails.

Example​

DispatchQueue.global(qos: .utility).async {
let transportStats = participant.getTransportStats() as? [String: Any]
let send = transportStats?["send"] as? [String: Any]
print("Sending at \(send?["outgoingBitrate"] ?? 0) kbps")
}

captureImage()​

  • captureImage() is used to capture an image of the participant's current webcam video. It is async throws and returns the image as a base64 string.
  • It works for the local participant, and for a remote participant whose webcam video this device receives.

Parameters​

  • width : CGFloat (Optional) - the maximum width of the image, in pixels.
  • height : CGFloat (Optional) - the maximum height of the image, in pixels.
  • flash : CaptureFlash (Optional) - .ON lights the scene before the image is captured, which adds about half a second. It uses the camera's torch. On a front camera without a torch, it uses the screen flash set with VideoSDK.setScreenFlash(_:), such as WhiteOverlayScreenFlash. With neither, the image is captured unlit. It works only for the local participant. Default: .OFF.

The image is scaled down to fit within width and height, keeping its aspect ratio. It is never enlarged. Without them, the image has the size of the video.

Returns​

  • String - the image as a base64-encoded JPEG.

Throws​

  • ERROR_WEBCAM_NOT_ENABLED (3062) when the participant's webcam is off, or this device does not receive it.
  • ERROR_CAPTURE_IMAGE_FAILED (3069) when the capture fails, when flash is .ON for a remote participant, or while another capture with flash is running. This error is also sent to onError().

Example​

Task {
do {
let base64Image = try await participant.captureImage(width: 1280, height: 720)
if let data = Data(base64Encoded: base64Image) {
imageView.image = UIImage(data: data)
}
} catch {
print("Capture failed: \(error)")
}
}

To light the scene, pass flash. For front cameras without a torch, set a screen flash first:

VideoSDK.setScreenFlash(WhiteOverlayScreenFlash(window: view.window))

Task {
do {
let base64Image = try await room.localParticipant.captureImage(flash: .ON)
print("Captured image: \(base64Image.count) characters")
} catch {
print("Capture failed: \(error)")
}
}

addEventListener()​

  • addEventListener() is used to add a listener that receives the participant's events.
  • Add it to each participant, for example in onParticipantJoined(), and to room.localParticipant for your own streams.
  • The participant holds the listener weakly. Keep a strong reference to it, for example by using your view controller as the listener.
  • Streams the participant already has are not reported again. Read streams for those.

Parameters​

  • listener: ParticipantEventListener

Returns​

  • Void

Example​

extension RoomViewController: RoomEventListener {
func onParticipantJoined(_ participant: Participant) {
participant.addEventListener(self)
}
}

removeEventListener()​

  • removeEventListener() is used to remove a listener that was added with addEventListener().

Parameters​

  • listener: ParticipantEventListener

Returns​

  • Void

Example​

participant.removeEventListener(self)

removeAllEventListeners()​

  • removeAllEventListeners() is used to remove all the listeners of this participant.

Returns​

  • Void

Example​

participant.removeAllEventListeners()

Got a Question? Ask us on discord