Room Class Methods - iOS
- Most
Roommethods areasync throws. Call them withtry awaitfrom aTaskor anotherasynccontext. - When a call is refused or fails, it throws a
VideoSDKError. Catch it withcatch let error as VideoSDKErrorand readcode,nameandmessage. Most of these errors are not sent toonError. - 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 throwERROR_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 calljoin().- Add your listener with
addEventListener()before you calljoin(), so you do not miss the first events. join()returns before the mic and camera frommicEnabled/camEnabledstart. Wait foronStreamEnabledbefore you treat local media as on.- If
leave()is called while the join is still running, the join is cancelled andjoin()returns without throwing. TreatonRoomJoinedas the sign that you are in the room.
Events associated with join():
- Local Participant will receive an
onRoomJoinedevent, when successfully joined. - Remote Participant will receive an
onParticipantJoinedevent with the newly joinedParticipantobject from the event callback. - If the join fails, the local participant receives
onRoomStateChangedwithFAILED, andjoin()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 callingjoin(). Participants having the permissionallow_joinreceive theonEntryRequestedevent. - After the decision, the
onEntryRespondedevent 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 toonError.
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():
- Local participant will receive an
onRoomLeftevent. - All remote participants will receive an
onParticipantLeftevent with theParticipantwho left.
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 calljoin().
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():
- All participants and localParticipant will receive the
onRoomLeftevent.
Returns
Void
Throws
- A
VideoSDKErrorif 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.
onStreamEnabledevent will be emitted withstreamobject 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, fromcreateRoomor 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_ENDEDtoonErrorand turns on the default camera instead.
- A custom camera track to use instead of the default camera. Create it with
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 isRECV_ONLYorSIGNALLING_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
- It is used to disable self camera.
onStreamDisabledevent will be emitted withstreamobject from the event callback, inside that participant object.
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
onStreamDisabledand thenonStreamEnabledare emitted. - If the webcam is off,
changeCam(deviceId:)only selects the camera. The nextenableCam()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 toenableCam(). If the call fails, the SDK stops the track.
switchWebcam() was removed in 4.0.0. Call changeCam() with no argument instead.
Parameters
- deviceId:
String?- The
deviceIdof aCameraDeviceInfofromVideoSDK.getCameras(), ornilto use the next camera. It is not the camera name. - An unknown ID changes nothing. The error is thrown and also sent to
onError.
- The
- customCameraTrack:
CustomStreamTrack- A track created with
VideoSDK.createCameraVideoTrack().
- A track created with
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 matchesdeviceId, 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) fromchangeCam(customCameraTrack:)if your mode isRECV_ONLYorSIGNALLING_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.
onStreamEnabledevent will be emitted withstreamobject 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_ENDEDtoonErrorand turns on the default microphone instead.
- A custom microphone track to use instead of the default microphone. Create it with
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 isRECV_ONLYorSIGNALLING_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
- It is used to disable self microphone.
onStreamDisabledevent will be emitted withstreamobject from the event callback, inside that participant object.
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
-
It is used to start room recording.
-
All participants and localParticipant will receive the
RECORDING_STARTINGstate in theonRecordingStateChangedevent. -
webhookUrlwill be called when the recording is completed and stored. Read more about webhooks here.
Parameters
-
webhookUrl:
String?- Default value:
nil
- Default value:
-
awsDirPath:
String? -
config:
RecordingConfig?- Create it with
RecordingConfig(layout:theme:mode:quality:orientation:). Every field is optional. A field you leavenilis left to the server. - layout:
ConfigLayout?, created withConfigLayout(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
- Create it with
-
transcription:
PostTranscriptionConfig?, created withPostTranscriptionConfig(enabled:summary:modelId:)- PostTranscriptionConfig.enabled:
Bool - PostTranscriptionConfig.summary:
SummaryConfig?- Created with
SummaryConfig(enabled:prompt:) - SummaryConfig.enabled:
Bool - SummaryConfig.prompt:
String?
- Created with
- PostTranscriptionConfig.modelId:
String?
- PostTranscriptionConfig.enabled:
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
- It is used to stop room recording.
- All participants and localParticipant will receive the
RECORDING_STOPPINGstate in theonRecordingStateChangedevent.
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
RTMPstreaming. - All participants and localParticipant will receive the
LIVESTREAM_STARTINGstate in theonLivestreamStateChangedevent. - If the server accepts the request but the livestream has not started 20 seconds later, for example because the RTMP destination cannot be reached,
onErrorreceivesSTART_LIVESTREAM_FAILED(4013).
Parameters
- outputs:
[LivestreamOutput]- Each
LivestreamOutputhas aurland astreamKey.
- Each
- config:
LivestreamConfig?- Create it with
LivestreamConfig(layout:theme:recording:). Every field is optional. A field you leavenilis left to the server. - layout:
ConfigLayout? - theme:
ConfigTheme?- .DARK | .LIGHT | .DEFAULT - recording:
LivestreamRecordingConfig?- Setenabled: trueto also record the livestream. niluses the server defaults.
- Create it with
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.
onErroralso receivesSTART_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
- It is used to stop room livestreaming.
- All participants and localParticipant will receive the
LIVESTREAM_STOPPINGstate in theonLivestreamStateChangedevent.
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.
onErroralso receivesSTOP_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.
-
modechooses whether HLS streams both video and audio, or only audio. When you leave itnil, the server streams video and audio. -
qualityis only applicable to video-and-audio. -
All participants and localParticipant will receive the
HLS_STARTINGstate in theonHlsStateChangedevent.
Parameters
-
config:
HLSConfig?- Create it with
HLSConfig(layout:theme:mode:quality:orientation:). Every field is optional. A field you leavenilis left to the server. - layout:
ConfigLayout?, created withConfigLayout(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
- Create it with
-
transcription:
PostTranscriptionConfig?, created withPostTranscriptionConfig(enabled:summary:modelId:)- PostTranscriptionConfig.enabled:
Bool - PostTranscriptionConfig.summary:
SummaryConfig?- Created with
SummaryConfig(enabled:prompt:) - SummaryConfig.enabled:
Bool - SummaryConfig.prompt:
String?
- Created with
- PostTranscriptionConfig.modelId:
String?
- PostTranscriptionConfig.enabled:
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.
onErroralso receivesSTART_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
stopHLS()is used to stop the HLS streaming.- All participants and localParticipant will receive the
HLS_STOPPINGstate in theonHlsStateChangedevent.
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.
onErroralso receivesSTOP_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_STARTINGevent state andonTranscriptionTextevent. -
config: TranscriptionConfig: webhookURLwill be triggered when the state of realtime transcription is changed. Read more about webhooks here. -
config: TranscriptionConfig: summary : SummaryConfigsets the summary config for the transcription.SummaryConfig: enabledindicates whether to generate a summary when the room ends.SummaryConfig: promptis the prompt the summary is written from.
Parameters
- config:
TranscriptionConfig?, created withTranscriptionConfig(webhookURL:summary:modelConfig:)- TranscriptionConfig.webhookURL:
String? - TranscriptionConfig.summary:
SummaryConfig?- Created with
SummaryConfig(enabled:prompt:) - SummaryConfig.enabled:
Bool - SummaryConfig.prompt:
String?
- Created with
- TranscriptionConfig.modelConfig:
[String: Any]?- Model settings. Use only values that can be converted to JSON.
- TranscriptionConfig.webhookURL:
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) ifmodelConfigcannot 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
- It is used to stop realtime transcription.
- All participants and localParticipant will receive
TRANSCRIPTION_STOPPINGevent state.
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
- It is used to start realtime translation.
- All participants, including the local participant, receive the
onTranslationStateChangedevent. - Translated text arrives through
onTranslationText, only for participants who set a translation language with thetranslationLanguageparameter ofcreateRoom()or withchangeTranslationLanguage(). - See Realtime Translation for a step-by-step guide.
Parameters
- config:
[String: Any]?- Translation settings, sent to the server as they are.
niluses the server defaults.
- Translation settings, sent to the server as they are.
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
onTranslationStateChangedevent.
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
onTranslationLanguageChangedis emitted. Until then,onTranslationTextkeeps 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_ONLYorSIGNALLING_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 leftSEND_AND_RECV. If you joined inRECV_ONLYorSIGNALLING_ONLY, it turns on the devices you set withmicEnabledandcamEnabledincreateRoom(). UseonStreamEnabledto see what came back, and callunmuteMic()orenableCam()only for a device that stays off. For a device that is already on, they throwERROR_ALREADY_IN_REQUESTED_STATE.
Parameters
- mode:
ModeSEND_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.
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():
- Every participant will receive the
onParticipantModeChangedevent.
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) andRTCAppGroupIdentifier(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
isScreenSharingto 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_15fpsor.h1080p_30fps. - Default value:
.h720p_15fps
- The screen-share encoder profile, separate from the camera profile:
- customTrack:
CustomStreamTrack?- A track created with
VideoSDK.createScreenShareVideoTrack(encoderConfig:multiStream:withAudio:), so you can create the profile once and reuse it.niluses the default profile.
- A track created with
Events associated with enableScreenShare():
onStreamEnabledevent will be emitted with the screen-sharestream.
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 isRECV_ONLYorSIGNALLING_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.onStreamDisabledevent will be emitted with the screen-sharestream.
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
changeMicmethod is used to change the microphone.- If the microphone is on, it is turned off and on again with the new device, so
onStreamDisabledand thenonStreamEnabledare emitted. - If the microphone is off,
changeMic(deviceId:)only selects the device. The nextunmuteMic()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 tounmuteMic(). If the call fails, the SDK stops the track.
Parameters
- deviceId:
String?- The
deviceIdof aMicrophoneDeviceInfofromVideoSDK.getMics(), ornilto use the next microphone. - An unknown ID changes nothing. The error is thrown and also sent to
onError.
- The
- customMicrophoneTrack:
CustomStreamTrack- A track created with
VideoSDK.createMicrophoneAudioTrack().
- A track created with
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) fromchangeMic(customMicrophoneTrack:)if your mode isRECV_ONLYorSIGNALLING_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 withdeviceId"Speaker"routes the audio to the loudspeaker. Any other device selects that microphone and its matching output. - It is not
async. Call it withtry. - A failure changes nothing. The error is thrown and also sent to
onError.
Parameters
- device:
MicrophoneDeviceInfo- A device fromVideoSDK.getMics().
Returns
Void
Throws
ERROR_NO_MICROPHONE_DEVICE_FOUND(3059) ifdeviceis 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
nilto remove it.
Parameters
- listener:
((MicrophoneDeviceInfo?, [MicrophoneDeviceInfo]) -> Void)?- selected: The selected device, or
nil. - available: Every device from
VideoSDK.getMics().
- selected: The selected device, or
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:
StringorData- The content to send. - reliable:
Booltrueresends the message until it is delivered and keeps the order.falsesends it once, which suits data that a newer message replaces, such as cursor positions.- Default value:
true
Events associated with send():
- Other participants receive the
onDataReceivedevent.
Returns
Void
Throws
- A
VideoSDKErrorif the message could not be sent, for exampleERROR_PAYLOAD_TOO_LARGE(3072) for a message larger than 15 KiB. Some failures are also sent toonError.
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
uploadBase64Filemethod 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) ifbase64Data,tokenorfileNameis 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
fetchBase64Filemethod retrieves a file from VideoSDK's temporary storage and returns it in the form of a Base64 String.
Parameters
- url:
String- The URL string of the file to be retrieved, as returned by
uploadBase64File().
- The URL string of the file to be retrieved, as returned by
- 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) ifurlortokenis 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?)
setVideoProcessormethod 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 callremoveVideoProcessor(), to remove the processor. - See Video Processor for
VideoSDKVideoProcessorandVideoSDKBackgroundProcessor.
Parameters
- processor:
VideoSDKVideoProcessor?- An instance of a processor class that conforms to the
VideoSDKVideoProcessorprotocol, such asVideoSDKBackgroundProcessorfor a virtual background.
- An instance of a processor class that conforms to the
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
-
startWhiteboardmethod starts the whiteboard session. -
All participants and localParticipant will receive
onWhiteboardStartedevent along with the url of the whiteboard.
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 toonError.
Example
Task {
do {
try await room?.startWhiteboard()
} catch {
print("Failed to start whiteboard: \(error)")
}
}
stopWhiteboard()
func stopWhiteboard() async throws
-
stopWhiteboardmethod stops the whiteboard session. -
All participants and localParticipant will receive
onWhiteboardStoppedevent.
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 toonError.
Example
Task {
do {
try await room?.stopWhiteboard()
} catch {
print("Failed to stop whiteboard: \(error)")
}
}
pauseAllStreams()
func pauseAllStreams(_ kind: StreamKind? = nil) async throws
-
The
pauseAllStreamsmethod pauses active media streams within the room. -
Specifies the type of media stream to be paused:
.AUDIO,.VIDEOor.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
onPausedAllStreamsevent.
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
-
resumeAllStreamsmethod resumes media streams that have been paused. -
Specifies the type of media stream to be resumed:
.AUDIO,.VIDEOor.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
onResumedAllStreamsevent.
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 thatParticipant.
Parameters
- quality:
VideoQuality-.high,.mediumor.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.
appliedisfalsewhen the camera is not publishing, for example afterdisableCam().
Returns
[String: Any]?- A dictionary with the keyswidth,height,frameRate,facingMode,codecandapplied, ornilif 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, ornilwhen 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
onSpeakerChangedevent.
Returns
String?- The participant ID, ornilwhen 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.
nilreuses 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.
- Possible values:
Events associated with requestMediaRelay():
- Participants in the destination room receive the
onMediaRelayRequestReceivedevent. - The local participant receives the
onMediaRelayRequestResponseevent with the decision, andonMediaRelayStartedonce the relay starts.
Returns
Void
Throws
ERROR_INVALID_PARAMETER(3073) ifdestinationRoomIdis 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():
- The local participant receives the
onMediaRelayStoppedevent.
Returns
Void
Throws
ERROR_INVALID_PARAMETER(3073) ifdestinationRoomIdis 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.
idchanges 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.
nilreuses this room's token.
Events associated with switchTo():
- The local participant receives
onRoomJoined(switchRoomId:)with the new room ID once the switch is complete.
Returns
Void
Throws
ERROR_INVALID_PARAMETER(3073) ifroomIdis 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 becauseroomIdhas no live session. The message carries the server's reason. This error is not sent toonError, 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
allowanddenyclosures ofonEntryRequestedcall it for you, but they ignore any error it throws. CallrespondEntry()yourself when you need to handle the error. onEntryRespondedis emitted with the decision.
Parameters
- participantId:
String- The ID of the participant who asked to join. - decision:
EntryDecision-.ALLOWEDto let the participant join, or.DENIEDto 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)
- It removes a listener that you added with
addEventListener().
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

