Skip to main content
Version: 4.x.x

Room Class Methods - iOS

info
  • Most Room methods are async throws. Call them with try await from a Task or another async context.
  • When a call is refused or fails, it throws a VideoSDKError. Catch it with catch let error as VideoSDKError and read code, name and message. Most of these errors are not sent to onError.
  • Most methods called before the room is joined, or after you have left it, throw ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED. While the room is reconnecting, they throw ERROR_ROOM_RECONNECTING.
Task {
do {
try await room?.enableCam()
} catch let error as VideoSDKError {
print("\(error.name) (\(error.code)): \(error.message)")
} catch {
print("Failed: \(error)")
}
}

join()​

func join() async throws

  • It is used to join a room.
  • VideoSDK.createRoom() returns a new instance of Room. However by default, it will not automatically join the room. Hence, to join the room you should call join().
  • Add your listener with addEventListener() before you call join(), so you do not miss the first events.
  • join() returns before the mic and camera from micEnabled / camEnabled start. Wait for onStreamEnabled before you treat local media as on.
  • If leave() is called while the join is still running, the join is cancelled and join() returns without throwing. Treat onRoomJoined as the sign that you are in the room.

Events associated with join():​

  • Local Participant will receive an onRoomJoined event, when successfully joined.
  • Remote Participant will receive an onParticipantJoined event with the newly joined Participant object from the event callback.
  • If the join fails, the local participant receives onRoomStateChanged with FAILED, and join() throws the error.

Participant having ask_join permission inside token​

  • If a token contains the permission ask_join, the participant does not join the room directly after calling join(). Participants having the permission allow_join receive the onEntryRequested event.
  • After the decision, the onEntryResponded event is emitted with the decision.

Returns​

  • Void

Throws​

  • ERROR_OPERATION_IN_PROGRESS (3055) if a join is already running.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if the room is already joined.
  • The join error, if the join fails, for example ERROR_UNABLE_TO_JOIN_ROOM (3047). It is also sent to onError.

Example​

Task {
do {
try await room?.join()
} catch {
print("Failed to join: \(error)")
}
}

leave()​

func leave() async throws

  • It is used to leave the current room.
  • It also works while the room is reconnecting. Called while a join is still running, including while you wait for entry approval, it cancels that join.

Events associated with leave():​

Returns​

  • Void

Throws​

  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if the room has already ended or you have already left it.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) if you have not joined the room and no join is running, for example before you call join().

Neither error is sent to onError.

Example​

Task {
do {
try await room?.leave()
} catch {
print("Failed to leave: \(error)")
}
}

end()​

func end() async throws

  • It is used to end the current running session.
  • By calling end(), all joined participants including localParticipant of that session will leave the room.
  • To leave without ending the session for everyone else, call leave() instead.

Events associated with end():​

Returns​

  • Void

Throws​

  • A VideoSDKError if the room could not be ended. You then stay in the room.

Example​

Task {
do {
try await room?.end()
} catch {
print("Failed to end the room: \(error)")
}
}

enableCam()​

func enableCam(customCameraTrack: CustomStreamTrack? = nil) async throws

  • It is used to enable self camera.
  • onStreamEnabled event will be emitted with stream object from the event callback, inside that participant object.
  • The method returns before the camera opens. If the camera then fails to open, for example because access was denied or the camera is in use, the error is sent only to onError.

Parameters​

  • customCameraTrack: CustomStreamTrack?
    • A custom camera track to use instead of the default camera. Create it with VideoSDK.createCameraVideoTrack().
    • When nil, the SDK uses the last track settings you selected, from createRoom or an earlier call.
    • If the call is refused, the SDK stops the track you passed. If the track has already ended, the SDK reports ERROR_CUSTOM_VIDEO_TRACK_ENDED to onError and turns on the default camera instead.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_OPERATION_IN_PROGRESS (3055) while another webcam enable or disable is running, or while a mode change is running.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if the webcam is already enabled.
  • ERROR_ACTION_NOT_SUPPORTED_IN_MODE (3066) if your mode is RECV_ONLY or SIGNALLING_ONLY.
  • ERROR_NO_WEBCAM_DEVICE_FOUND (3051) if the device has no camera.

Example​

Task {
do {
try await room?.enableCam()
} catch {
print("Failed to enable camera: \(error)")
}
}

disableCam()​

func disableCam() async throws

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting. The camera stays on.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_OPERATION_IN_PROGRESS (3055) while another webcam enable or disable is running.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if the webcam is already disabled.

Example​

Task {
do {
try await room?.disableCam()
} catch {
print("Failed to disable camera: \(error)")
}
}

changeCam()​

func changeCam(deviceId: String? = nil) async throws

func changeCam(customCameraTrack: CustomStreamTrack) async throws

  • It is used to switch the webcam to another camera. Call it with no argument to move to the next camera, for example from the front camera to the back one.
  • If the webcam is on, it is turned off and on again with the new camera, so onStreamDisabled and then onStreamEnabled are emitted.
  • If the webcam is off, changeCam(deviceId:) only selects the camera. The next enableCam() uses it.
  • If the switch fails, the SDK goes back to the previous camera and throws the error.
  • changeCam(customCameraTrack:) switches to a custom track. If the webcam is off, it turns the webcam on with that track. The SDK keeps the track for later calls to enableCam(). If the call fails, the SDK stops the track.
note

switchWebcam() was removed in 4.0.0. Call changeCam() with no argument instead.

Parameters​

  • deviceId: String?
    • The deviceId of a CameraDeviceInfo from VideoSDK.getCameras(), or nil to use the next camera. It is not the camera name.
    • An unknown ID changes nothing. The error is thrown and also sent to onError.
  • customCameraTrack: CustomStreamTrack

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_NO_WEBCAM_DEVICE_FOUND (3051) if no camera matches deviceId, or the device has no camera.
  • ERROR_OPERATION_IN_PROGRESS (3055) while another webcam enable or disable is running.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if the webcam was already on when the switch tried to turn it on.
  • ERROR_ACTION_NOT_SUPPORTED_IN_MODE (3066) from changeCam(customCameraTrack:) if your mode is RECV_ONLY or SIGNALLING_ONLY.

Example​

Task {
do {
// No argument: the next camera, for example front to back
try await room?.changeCam()

// Or pick a camera by its deviceId
let cameras = VideoSDK.getCameras()
try await room?.changeCam(deviceId: cameras.last?.deviceId)
} catch {
print("Failed to change camera: \(error)")
}
}

unmuteMic()​

func unmuteMic(customMicrophoneTrack: CustomStreamTrack? = nil) async throws

  • It is used to enable self microphone.
  • onStreamEnabled event will be emitted with stream object from the event callback, inside that participant object.
  • The method returns before the microphone opens. If the microphone then fails to open, for example because access was denied, the error is sent only to onError.

Parameters​

  • customMicrophoneTrack: CustomStreamTrack?
    • A custom microphone track to use instead of the default microphone. Create it with VideoSDK.createMicrophoneAudioTrack().
    • Its noise settings apply at once. Its audio encoder profile (encoderConfig) applies from the next join, not during the current session.
    • If the call is refused, the SDK stops the track you passed. If the track has already ended, the SDK reports ERROR_CUSTOM_AUDIO_TRACK_ENDED to onError and turns on the default microphone instead.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_OPERATION_IN_PROGRESS (3055) while another microphone enable or disable is running, or while a mode change is running.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if the microphone is already enabled.
  • ERROR_ACTION_NOT_SUPPORTED_IN_MODE (3066) if your mode is RECV_ONLY or SIGNALLING_ONLY.
  • ERROR_NO_MICROPHONE_DEVICE_FOUND (3059) if no microphone is available.

Example​

Task {
do {
try await room?.unmuteMic()
} catch {
print("Failed to unmute mic: \(error)")
}
}

muteMic()​

func muteMic() async throws

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting. The microphone stays on.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_OPERATION_IN_PROGRESS (3055) while another microphone enable or disable is running.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if the microphone is already disabled.

Example​

Task {
do {
try await room?.muteMic()
} catch {
print("Failed to mute mic: \(error)")
}
}

startRecording()​

func startRecording(webhookUrl: String? = nil, awsDirPath: String? = nil, config: RecordingConfig? = nil, transcription: PostTranscriptionConfig? = nil) async throws

Parameters​

  • webhookUrl: String?

    • Default value: nil
  • awsDirPath: String?

  • config: RecordingConfig?

    • Create it with RecordingConfig(layout:theme:mode:quality:orientation:). Every field is optional. A field you leave nil is left to the server.
    • layout: ConfigLayout?, created with ConfigLayout(type:priority:gridSize:)
      • type: .GRID | .SPOTLIGHT | .SIDEBAR
      • priority: .SPEAKER | .PIN
      • gridSize: Int? max 4
    • theme: .DARK | .LIGHT | .DEFAULT
    • mode: .VIDEO_AND_AUDIO | .AUDIO
    • quality: .LOW | .MED | .HIGH
    • orientation: .landscape | .portrait
  • transcription: PostTranscriptionConfig?, created with PostTranscriptionConfig(enabled:summary:modelId:)

    • PostTranscriptionConfig.enabled: Bool
    • PostTranscriptionConfig.summary: SummaryConfig?
      • Created with SummaryConfig(enabled:prompt:)
      • SummaryConfig.enabled: Bool
      • SummaryConfig.prompt: String?
    • PostTranscriptionConfig.modelId: String?

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

If the server refuses the start, for example while a recording is already starting or running, it throws START_RECORDING_FAILED (4011) with the server's reason in the message, and also sends it to onError.

Example​

let webhookUrl = "https://webhook.your-api-server.com"

let awsDirPath = "/room-recordings/"

let config: RecordingConfig = RecordingConfig(
layout: ConfigLayout(
type: .GRID,
priority: .PIN,
gridSize: 4
),
theme: .DARK,
mode: .VIDEO_AND_AUDIO,
quality: .MED,
orientation: .landscape
)

let transcription: PostTranscriptionConfig = PostTranscriptionConfig(
enabled: true,
summary: SummaryConfig(
enabled: true,
prompt: "Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
)
)

Task {
do {
try await room?.startRecording(webhookUrl: webhookUrl, awsDirPath: awsDirPath, config: config, transcription: transcription)
} catch {
print("Failed to start recording: \(error)")
}
}

stopRecording()​

func stopRecording() async throws

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

If the server refuses the stop, for example when no recording is running, it throws STOP_RECORDING_FAILED (4012) with the server's reason in the message, and also sends it to onError.

Example​

Task {
do {
try await room?.stopRecording()
} catch {
print("Failed to stop recording: \(error)")
}
}

startLivestream()​

func startLivestream(outputs: [LivestreamOutput], config: LivestreamConfig? = nil) async throws

  • It is used to start room livestreaming.
  • You can live stream the room to other platforms such as YouTube, Facebook, etc. that support RTMP streaming.
  • All participants and localParticipant will receive the LIVESTREAM_STARTING state in the onLivestreamStateChanged event.
  • If the server accepts the request but the livestream has not started 20 seconds later, for example because the RTMP destination cannot be reached, onError receives START_LIVESTREAM_FAILED (4013).

Parameters​

  • outputs: [LivestreamOutput]
    • Each LivestreamOutput has a url and a streamKey.
  • config: LivestreamConfig?
    • Create it with LivestreamConfig(layout:theme:recording:). Every field is optional. A field you leave nil is left to the server.
    • layout: ConfigLayout?
    • theme: ConfigTheme? - .DARK | .LIGHT | .DEFAULT
    • recording: LivestreamRecordingConfig? - Set enabled: true to also record the livestream.
    • nil uses the server defaults.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • The server's error, if it refuses the request. onError also receives START_LIVESTREAM_FAILED (4013) for it.

Example​

let outputs = [
LivestreamOutput(url: "rtmp://a.rtmp.youtube.com/live2", streamKey: "<STREAM_KEY>")
]

Task {
do {
try await room?.startLivestream(outputs: outputs)
} catch {
print("Failed to start livestream: \(error)")
}
}

stopLivestream()​

func stopLivestream() async throws

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • The server's error, if it refuses the request. onError also receives STOP_LIVESTREAM_FAILED (4014) for it.

Example​

Task {
do {
try await room?.stopLivestream()
} catch {
print("Failed to stop livestream: \(error)")
}
}

startHLS()​

func startHLS(config: HLSConfig? = nil, transcription: PostTranscriptionConfig? = nil) async throws

  • startHLS() will start HLS streaming of your room.

  • You will be able to start HLS and watch the live stream of the room over HLS.

  • mode chooses whether HLS streams both video and audio, or only audio. When you leave it nil, the server streams video and audio.

  • quality is only applicable to video-and-audio.

  • All participants and localParticipant will receive the HLS_STARTING state in the onHlsStateChanged event.

Parameters​

  • config: HLSConfig?

    • Create it with HLSConfig(layout:theme:mode:quality:orientation:). Every field is optional. A field you leave nil is left to the server.
    • layout: ConfigLayout?, created with ConfigLayout(type:priority:gridSize:)
      • type: .GRID | .SPOTLIGHT | .SIDEBAR
      • priority: .SPEAKER | .PIN
      • gridSize: Int? max 25
    • theme: .DARK | .LIGHT | .DEFAULT
    • mode: .VIDEO_AND_AUDIO | .AUDIO
    • quality: .LOW | .MED | .HIGH
    • orientation: .landscape | .portrait
  • transcription: PostTranscriptionConfig?, created with PostTranscriptionConfig(enabled:summary:modelId:)

    • PostTranscriptionConfig.enabled: Bool
    • PostTranscriptionConfig.summary: SummaryConfig?
      • Created with SummaryConfig(enabled:prompt:)
      • SummaryConfig.enabled: Bool
      • SummaryConfig.prompt: String?
    • PostTranscriptionConfig.modelId: String?

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • The server's error, if it refuses the request. onError also receives START_HLS_FAILED (4016) for it.

Example​

let config: HLSConfig = HLSConfig(
layout: ConfigLayout(
type: .GRID,
priority: .SPEAKER,
gridSize: 4
),
theme: .DARK,
mode: .VIDEO_AND_AUDIO,
quality: .HIGH,
orientation: .portrait
)

let transcription: PostTranscriptionConfig = PostTranscriptionConfig(
enabled: true,
summary: SummaryConfig(
enabled: true,
prompt: "Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
)
)

Task {
do {
try await room?.startHLS(config: config, transcription: transcription)
} catch {
print("Failed to start HLS: \(error)")
}
}

stopHLS()​

func stopHLS() async throws

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • The server's error, if it refuses the request. onError also receives STOP_HLS_FAILED (4017) for it.

Example​

Task {
do {
try await room?.stopHLS()
} catch {
print("Failed to stop HLS: \(error)")
}
}

startTranscription()​

func startTranscription(config: TranscriptionConfig? = nil) async throws

  • It is used to start realtime transcription.

  • All participants and localParticipant will receive TRANSCRIPTION_STARTING event state and onTranscriptionText event.

  • config: TranscriptionConfig: webhookURL will be triggered when the state of realtime transcription is changed. Read more about webhooks here.

  • config: TranscriptionConfig: summary : SummaryConfig sets the summary config for the transcription.

    • SummaryConfig: enabled indicates whether to generate a summary when the room ends.
    • SummaryConfig: prompt is the prompt the summary is written from.

Parameters​

  • config: TranscriptionConfig?, created with TranscriptionConfig(webhookURL:summary:modelConfig:)
    • TranscriptionConfig.webhookURL: String?
    • TranscriptionConfig.summary: SummaryConfig?
      • Created with SummaryConfig(enabled:prompt:)
      • SummaryConfig.enabled: Bool
      • SummaryConfig.prompt: String?
    • TranscriptionConfig.modelConfig: [String: Any]? - Model settings. Use only values that can be converted to JSON.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_INVALID_PARAMETER (3073) if modelConfig cannot be converted to JSON.

Example​

let config = TranscriptionConfig(
webhookURL: "YOUR_WEBHOOK_URL",
summary: SummaryConfig(
enabled: true,
prompt: "Write summary in sections like Title, Agenda, Speakers, Action Items, Outlines, Notes and Summary"
)
)

Task {
do {
try await room?.startTranscription(config: config)
} catch {
print("Failed to start transcription: \(error)")
}
}

stopTranscription()​

func stopTranscription() async throws

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.stopTranscription()
} catch {
print("Failed to stop transcription: \(error)")
}
}

startTranslation()​

func startTranslation(config: [String: Any]? = nil) async throws

Parameters​

  • config: [String: Any]?
    • Translation settings, sent to the server as they are. nil uses the server defaults.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.startTranslation()
} catch {
print("Failed to start translation: \(error)")
}
}

stopTranslation()​

func stopTranslation() async throws

  • It is used to stop realtime translation.
  • All participants, including the local participant, receive the onTranslationStateChanged event.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.stopTranslation()
} catch {
print("Failed to stop translation: \(error)")
}
}

changeTranslationLanguage()​

func changeTranslationLanguage(_ language: String) async throws

  • It changes the language in which the local participant receives translations.
  • The change takes effect once the server confirms it, and onTranslationLanguageChanged is emitted. Until then, onTranslationText keeps delivering the previous language.

Parameters​

  • language: String - The language code to receive translations in.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.changeTranslationLanguage("<LANGUAGE_CODE>")
} catch {
print("Failed to change translation language: \(error)")
}
}

changeMode()​

func changeMode(_ mode: Mode) async throws

  • changeMode() is used to change the mode of participant.
  • When you switch to RECV_ONLY or SIGNALLING_ONLY, the SDK stops your screen share and releases the camera and microphone.
  • When you switch back to SEND_AND_RECV, the SDK turns the microphone and camera back on if they were on before you left SEND_AND_RECV. If you joined in RECV_ONLY or SIGNALLING_ONLY, it turns on the devices you set with micEnabled and camEnabled in createRoom(). Use onStreamEnabled to see what came back, and call unmuteMic() or enableCam() only for a device that stays off. For a device that is already on, they throw ERROR_ALREADY_IN_REQUESTED_STATE.

Parameters​

  • mode: Mode
    • SEND_AND_RECV: sends and receives audio and video.
    • RECV_ONLY: receives audio and video, and sends none.
    • SIGNALLING_ONLY: sends and receives no media. It is used only for signalling.
note

Mode.CONFERENCE and Mode.VIEWER were removed in 4.0.0. Use SEND_AND_RECV instead of CONFERENCE, and SIGNALLING_ONLY instead of VIEWER.

Events associated with changeMode():​

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if you are already in that mode.

The first two errors are also sent to onError. If the server refuses the change, the error, for example CHANGE_MODE_FAILED (4065), is thrown and also sent to onError.

Example​

Task {
do {
try await room?.changeMode(.SIGNALLING_ONLY)
} catch {
print("Failed to change mode: \(error)")
}
}

enableScreenShare()​

func enableScreenShare(_ config: CustomScreenShareTrackConfig = .h720p_15fps) async throws

func enableScreenShare(_ customTrack: CustomStreamTrack?) async throws

  • enableScreenShare() is used to share your local screen to the remote participants in the room.
  • Screen capture runs in a Broadcast Upload Extension. This method shows the iOS broadcast picker, and the share starts when the user taps Start Broadcast.
  • Your app's Info.plist must contain RTCScreenSharingExtension (the bundle ID of the extension) and RTCAppGroupIdentifier (the App Group that the app and the extension share).
  • If no broadcast starts within about 30 seconds, the SDK releases the share. The user can also stop the broadcast from Control Center. The SDK then disables the share for you.
  • Read isScreenSharing to know whether a share is active.

Parameters​

  • config: CustomScreenShareTrackConfig
    • The screen-share encoder profile, separate from the camera profile: .h360p_30fps, .h480p_15fps, .h480p_30fps, .h720p_5fps, .h720p_15fps, .h720p_30fps, .h1080p_15fps or .h1080p_30fps.
    • Default value: .h720p_15fps
  • customTrack: CustomStreamTrack?
    • A track created with VideoSDK.createScreenShareVideoTrack(encoderConfig:multiStream:withAudio:), so you can create the profile once and reuse it. nil uses the default profile.

Events associated with enableScreenShare():​

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_ACTION_NOT_SUPPORTED_IN_MODE (3066) if your mode is RECV_ONLY or SIGNALLING_ONLY.
  • ERROR_OPERATION_IN_PROGRESS (3055) while the previous broadcast is still stopping. Try again in a moment.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if screen sharing is already enabled.
  • ERROR_GET_DISPLAY_MEDIA (3013) if the app is not set up for screen sharing: an Info.plist key or the App Group is missing, or there is no window to show the picker.

Example​

Task {
do {
try await room?.enableScreenShare()
// Or choose a profile: try await room?.enableScreenShare(.h1080p_15fps)
} catch {
print("Failed to enable screen share: \(error)")
}
}

disableScreenShare()​

func disableScreenShare() async throws

  • disableScreenShare() is used to stop sharing your local screen.
  • onStreamDisabled event will be emitted with the screen-share stream.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if screen sharing is already disabled, for example after the user stopped it from Control Center.

Example​

Task {
do {
try await room?.disableScreenShare()
} catch {
print("Failed to disable screen share: \(error)")
}
}

changeMic()​

func changeMic(deviceId: String? = nil) async throws

func changeMic(customMicrophoneTrack: CustomStreamTrack) async throws

  • changeMic method is used to change the microphone.
  • If the microphone is on, it is turned off and on again with the new device, so onStreamDisabled and then onStreamEnabled are emitted.
  • If the microphone is off, changeMic(deviceId:) only selects the device. The next unmuteMic() uses it.
  • If the switch fails, the SDK goes back to the previous device and throws the error.
  • changeMic(customMicrophoneTrack:) switches to a custom track. Its noise settings apply at once; its audio encoder profile applies from the next join. If the microphone is off, it turns the microphone on with that track. The SDK keeps the track for later calls to unmuteMic(). If the call fails, the SDK stops the track.

Parameters​

  • deviceId: String?
    • The deviceId of a MicrophoneDeviceInfo from VideoSDK.getMics(), or nil to use the next microphone.
    • An unknown ID changes nothing. The error is thrown and also sent to onError.
  • customMicrophoneTrack: CustomStreamTrack

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_NO_MICROPHONE_DEVICE_FOUND (3059) if the selected microphone is not available, or no microphone is available.
  • ERROR_OPERATION_IN_PROGRESS (3055) while another microphone enable or disable is running.
  • ERROR_ALREADY_IN_REQUESTED_STATE (3054) if the microphone was already on when the switch tried to turn it on.
  • ERROR_ACTION_NOT_SUPPORTED_IN_MODE (3066) from changeMic(customMicrophoneTrack:) if your mode is RECV_ONLY or SIGNALLING_ONLY.

Example​

let mics = VideoSDK.getMics()

Task {
do {
try await room?.changeMic(deviceId: mics.last?.deviceId)
} catch {
print("Failed to change mic: \(error)")
}
}

setAudioDevice()​

func setAudioDevice(_ device: MicrophoneDeviceInfo) throws

  • It routes audio to device. The device with deviceId "Speaker" routes the audio to the loudspeaker. Any other device selects that microphone and its matching output.
  • It is not async. Call it with try.
  • A failure changes nothing. The error is thrown and also sent to onError.

Parameters​

Returns​

  • Void

Throws​

  • ERROR_NO_MICROPHONE_DEVICE_FOUND (3059) if device is not available.
  • ERROR_ACTION_NOT_SUPPORTED (3068) if iOS refuses the output route.

Example​

if let speaker = VideoSDK.getMics().first(where: { $0.deviceId == "Speaker" }) {
do {
try room?.setAudioDevice(speaker)
} catch {
print("Failed to set audio device: \(error)")
}
}

setAudioDeviceChangeListener()​

func setAudioDeviceChangeListener(_ listener: ((_ selected: MicrophoneDeviceInfo?, _ available: [MicrophoneDeviceInfo]) -> Void)?)

  • It sets a closure that is called when a headset or Bluetooth device is plugged in or removed, or when the audio route is overridden.
  • The closure is called once right away with the current state, then on every change. It is always called on the main thread.
  • A new closure replaces the previous one. Pass nil to remove it.

Parameters​

  • listener: ((MicrophoneDeviceInfo?, [MicrophoneDeviceInfo]) -> Void)?

Returns​

  • Void

Example​

room?.setAudioDeviceChangeListener { selected, available in
print("Selected: \(selected?.label ?? "none"), available: \(available.map { $0.label })")
}

send()​

func send(_ message: String, reliable: Bool = true) async throws

func send(_ data: Data, reliable: Bool = true) async throws

  • It sends text or binary data to all other participants over the room's data channel.
  • Unlike PubSub, the message is not stored on the server, so a participant who joins later does not receive it.
  • A message larger than 15 KiB is not sent.
  • See Data Channel for a step-by-step guide.

Parameters​

  • message / data: String or Data - The content to send.
  • reliable: Bool
    • true resends the message until it is delivered and keeps the order. false sends it once, which suits data that a newer message replaces, such as cursor positions.
    • Default value: true

Events associated with send():​

Returns​

  • Void

Throws​

  • A VideoSDKError if the message could not be sent, for example ERROR_PAYLOAD_TOO_LARGE (3072) for a message larger than 15 KiB. Some failures are also sent to onError.

Example​

Task {
do {
try await room?.send("Hello everyone")
} catch {
print("Failed to send message: \(error)")
}
}

uploadBase64File()​

func uploadBase64File(base64Data: String, token: String, fileName: String) async throws -> String

  • uploadBase64File method uploads a file to VideoSDK's temporary storage and returns the corresponding URL string to retrieve the file from the storage system.

Parameters​

  • base64Data: String
    • The Base64 encoded string of the file to be uploaded.
  • token: String
    • The authentication token required to access VideoSDK's storage system.
  • fileName: String
    • The name under which the file will be stored, including its extension.

Returns​

  • String - The URL of the uploaded file.

Throws​

  • ERROR_INVALID_PARAMETER (3073) if base64Data, token or fileName is empty.
  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_FILE_UPLOAD_FAILED (3074) if the upload fails.

All of these except ERROR_INVALID_PARAMETER are also sent to onError.

Example​

let base64Data: String = "<Your-base64-File>"
let token: String = "<Your-Token>"
let fileName: String = "name.jpeg" // Provide file name with extension

Task {
do {
let url = try await room?.uploadBase64File(base64Data: base64Data, token: token, fileName: fileName)
print("url: \(url ?? "")")
} catch {
print("Failed to upload file: \(error)")
}
}

fetchBase64File()​

func fetchBase64File(url: String, token: String) async throws -> String

  • fetchBase64File method retrieves a file from VideoSDK's temporary storage and returns it in the form of a Base64 String.

Parameters​

  • url: String
  • token: String
    • The authentication token required to access VideoSDK's storage system.

Returns​

  • String - The Base64 encoded content of the file.

Throws​

  • ERROR_INVALID_PARAMETER (3073) if url or token is empty.
  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • ERROR_FILE_FETCH_FAILED (3075) if the file cannot be fetched.

All of these except ERROR_INVALID_PARAMETER are also sent to onError.

Example​

let url: String = "<Your FileUrl>" // Provide fileUrl which is returned by uploadBase64File()
let token: String = "<Your-Token>"

Task {
do {
let base64Data = try await room?.fetchBase64File(url: url, token: token)
print("base64: \(base64Data ?? "")")
} catch {
print("Failed to fetch file: \(error)")
}
}

setVideoProcessor()​

func setVideoProcessor(processor: VideoSDKVideoProcessor?)

  • setVideoProcessor method sets the processor that will be used in processing the local video frames.
  • Every camera frame passes through the processor before it is sent. Pass nil, or call removeVideoProcessor(), to remove the processor.
  • See Video Processor for VideoSDKVideoProcessor and VideoSDKBackgroundProcessor.

Parameters​

  • processor: VideoSDKVideoProcessor?
    • An instance of a processor class that conforms to the VideoSDKVideoProcessor protocol, such as VideoSDKBackgroundProcessor for a virtual background.

Returns​

  • Void

Example​

let backgroundSource = URL(string: "https://cdn.videosdk.live/virtual-background/cloud.jpeg")!
let processor = VideoSDKBackgroundProcessor(backgroundSource: backgroundSource)
room?.setVideoProcessor(processor: processor)

removeVideoProcessor()​

func removeVideoProcessor()

  • It removes the processor set with setVideoProcessor(). Camera frames are then sent unprocessed.
  • It does the same as setVideoProcessor(processor: nil).

Returns​

  • Void

Example​

room?.removeVideoProcessor()

startWhiteboard()​

func startWhiteboard() async throws

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • WHITEBOARD_OPERATION_IN_PROGRESS (4056) while another whiteboard start or stop is running.
  • The server's error, if it refuses the request, for example START_WHITEBOARD_FAILED (4054). It is also sent to onError.

Example​

Task {
do {
try await room?.startWhiteboard()
} catch {
print("Failed to start whiteboard: \(error)")
}
}

stopWhiteboard()​

func stopWhiteboard() async throws

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • WHITEBOARD_OPERATION_IN_PROGRESS (4056) while another whiteboard start or stop is running.
  • The server's error, if it refuses the request, for example STOP_WHITEBOARD_FAILED (4055). It is also sent to onError.

Example​

Task {
do {
try await room?.stopWhiteboard()
} catch {
print("Failed to stop whiteboard: \(error)")
}
}

pauseAllStreams()​

func pauseAllStreams(_ kind: StreamKind? = nil) async throws

  • The pauseAllStreams method pauses active media streams within the room.

  • Specifies the type of media stream to be paused: .AUDIO, .VIDEO or .SHARE. If this parameter is provided, only that particular type of media stream will be paused. Otherwise, by default, all media streams (audio, video, and screen share) will be paused.

  • The local participant receives the onPausedAllStreams event.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.pauseAllStreams(.VIDEO)
} catch {
print("Failed to pause streams: \(error)")
}
}

resumeAllStreams()​

func resumeAllStreams(_ kind: StreamKind? = nil) async throws

  • resumeAllStreams method resumes media streams that have been paused.

  • Specifies the type of media stream to be resumed: .AUDIO, .VIDEO or .SHARE. If this parameter is provided, only that particular type of media stream will be resumed. Otherwise, by default, all media streams (audio, video, and screen share) will be resumed.

  • The local participant receives the onResumedAllStreams event.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.resumeAllStreams(.VIDEO)
} catch {
print("Failed to resume streams: \(error)")
}
}

enableAdaptiveSubscription()​

func enableAdaptiveSubscription() async throws

  • It turns on Adaptive Subscription, which adjusts which video streams you receive based on participant visibility and network conditions.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.enableAdaptiveSubscription()
} catch {
print("Failed to enable adaptive subscription: \(error)")
}
}

disableAdaptiveSubscription()​

func disableAdaptiveSubscription() async throws

  • It turns off Adaptive Subscription. All video streams then stay subscribed, whatever the visibility or network conditions.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.disableAdaptiveSubscription()
} catch {
print("Failed to disable adaptive subscription: \(error)")
}
}

setWebcamQuality()​

func setWebcamQuality(_ quality: VideoQuality) async throws

  • It sets the quality that your own webcam sends. To set the quality you receive from another participant, use setQuality() on that Participant.

Parameters​

  • quality: VideoQuality - .high, .medium or .low.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.setWebcamQuality(.low)
} catch {
print("Failed to set webcam quality: \(error)")
}
}

getAppliedVideoConfig()​

func getAppliedVideoConfig() -> [String: Any]?

  • It returns the camera capture settings in use.
  • applied is false when the camera is not publishing, for example after disableCam().

Returns​

  • [String: Any]? - A dictionary with the keys width, height, frameRate, facingMode, codec and applied, or nil if the camera has not been opened yet.

Example​

if let config = room?.getAppliedVideoConfig() {
print("Camera config: \(config)")
}

getActivePresenterId()​

func getActivePresenterId() -> String?

  • It returns the ID of the participant who is sharing their screen. Changes are reported through onPresenterChanged.

Returns​

  • String? - The participant ID, or nil when no one is presenting.

Example​

if let presenterId = room?.getActivePresenterId() {
print("Presenter: \(presenterId)")
}

getActiveSpeakerId()​

func getActiveSpeakerId() -> String?

  • It returns the ID of the participant who is speaking now, from the last onSpeakerChanged event.

Returns​

  • String? - The participant ID, or nil when no one is speaking.

Example​

if let speakerId = room?.getActiveSpeakerId() {
print("Active speaker: \(speakerId)")
}

requestMediaRelay()​

func requestMediaRelay(destinationRoomId: String, token: String? = nil, kinds: [StreamKind]? = nil) async throws

This method starts relaying selected media streams (like camera video, microphone audio, screen share, etc.) from the current room to a specified destination room.

Parameters​

  • destinationRoomId (String) – Required: ID of the target room where media should be relayed.

  • token (String?) – Optional: Authentication token for the destination room. nil reuses this room's token.

  • kinds ([StreamKind]?) – Optional: Array of media types to relay. Audio, video and share are all relayed when it is nil.

    • Possible values:
      • .AUDIO: Relays audio streams.
      • .VIDEO: Relays video streams.
      • .SHARE: Relays screen-sharing video streams.

Events associated with requestMediaRelay():​

Returns​

  • Void

Throws​

  • ERROR_INVALID_PARAMETER (3073) if destinationRoomId is empty.
  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.requestMediaRelay(destinationRoomId: "<DESTINATION-ROOM-ID>", token: "<AUTH-TOKEN>", kinds: [.VIDEO, .AUDIO])
} catch {
print("Failed to request media relay: \(error)")
}
}

stopMediaRelay()​

func stopMediaRelay(destinationRoomId: String) async throws

This method stops the ongoing media relay to a specific destination room.

Parameters​

  • destinationRoomId (String) – Required: ID of the destination room where the media relay should be stopped.

Events associated with stopMediaRelay():​

Returns​

  • Void

Throws​

  • ERROR_INVALID_PARAMETER (3073) if destinationRoomId is empty.
  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.stopMediaRelay(destinationRoomId: "<DESTINATION-ROOM-ID>")
} catch {
print("Failed to stop media relay: \(error)")
}
}

switchTo()​

func switchTo(roomId: String, token: String? = nil) async throws

This method moves the local participant from the current room to another room, without calling leave() and join().

  • The local participant keeps the same ID and mode, and the microphone and camera keep their state.
  • id changes to the new room ID when the switch succeeds.

Parameters​

  • roomId (String) – Required: ID of the new room to switch to.

  • token (String?) – Optional: Authentication token for the new room. nil reuses this room's token.

Events associated with switchTo():​

Returns​

  • Void

Throws​

  • ERROR_INVALID_PARAMETER (3073) if roomId is empty.
  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.
  • SWITCH_ROOM_FAILED (4076) if the server refuses the switch, for example because roomId has no live session. The message carries the server's reason. This error is not sent to onError, and you stay in the current room, still connected.

Example​

Task {
do {
try await room?.switchTo(roomId: "<NEW-ROOM-ID>", token: "<AUTH-TOKEN>")
} catch {
print("Failed to switch room: \(error)")
}
}

respondEntry()​

func respondEntry(participantId: String, decision: EntryDecision) async throws

  • It answers a participant's request to join the room, which you receive in onEntryRequested.
  • The allow and deny closures of onEntryRequested call it for you, but they ignore any error it throws. Call respondEntry() yourself when you need to handle the error.
  • onEntryResponded is emitted with the decision.

Parameters​

  • participantId: String - The ID of the participant who asked to join.
  • decision: EntryDecision - .ALLOWED to let the participant join, or .DENIED to refuse.

Returns​

  • Void

Throws​

  • ERROR_ROOM_RECONNECTING (3065) while the room is reconnecting.
  • ERROR_ACTION_PERFORMED_BEFORE_ROOM_JOINED (3035) before you join the room.

Example​

Task {
do {
try await room?.respondEntry(participantId: "<PARTICIPANT-ID>", decision: .ALLOWED)
} catch {
print("Failed to respond to entry request: \(error)")
}
}

addEventListener()​

func addEventListener(_ listener: RoomEventListener)

  • It adds a listener that receives all room events.
  • The room holds the listener weakly, so the listener must be a class instance that you keep alive, such as your view controller.

Parameters​

  • listener: RoomEventListener

Returns​

  • Void

Example​

room?.addEventListener(self)

removeEventListener()​

func removeEventListener(_ listener: RoomEventListener)

Parameters​

  • listener: RoomEventListener

Returns​

  • Void

Example​

room?.removeEventListener(self)

removeAllEventListeners()​

func removeAllEventListeners()

  • It removes every listener from the room.

Returns​

  • Void

Example​

room?.removeAllEventListeners()

Got a Question? Ask us on discord