Skip to main content
Version: 4.x.x

Change Input/Output Audio Device - iOS

At any point in the room, a participant can switch their audio device using the below mentioned methods.

Changing Input/Output Audio Device​

getMics()​

  • The VideoSDK.getMics() method returns the audio devices as [MicrophoneDeviceInfo]. Each device has a label and a deviceId.

  • The first entry is always the Speaker output, which is not a microphone. The other entries are the microphone inputs, such as iPhone Microphone, Headphones for a wired headset, or the name of a Bluetooth headset.

  • VideoSDK.getSelectedAudioDevice() returns the device in use: Speaker while audio plays on the loudspeaker, otherwise the current microphone. It returns nil when neither is known.

Example​

let devices = VideoSDK.getMics()
for device in devices {
print(device.label) //sample output: Speaker, iPhone Microphone
}

// the microphones you can pass to changeMic(deviceId:)
let mics = devices.filter { $0.deviceId != "Speaker" }

// the device in use now
let selected = VideoSDK.getSelectedAudioDevice()

setAudioDevice()​

  • Participant can switch where the audio goes using the setAudioDevice(_:) method of the Room class. Pass a device from VideoSDK.getMics().

  • Speaker plays the audio on the loudspeaker. Any other device uses that microphone and its matching output, for example a Bluetooth headset.

  • It throws, so call it with try. A failure changes nothing, is thrown, and is also sent to onError(error:):

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

Example​

func selectAudioDevice(_ device: MicrophoneDeviceInfo) {
do {
try self.room?.setAudioDevice(device)
} catch {
print("Could not switch the audio device: \(error)")
}
}

// play the audio on the loudspeaker
if let speaker = VideoSDK.getMics().first(where: { $0.deviceId == "Speaker" }) {
selectAudioDevice(speaker)
}

setAudioDeviceChangeListener()​

  • By using the setAudioDeviceChangeListener(_:) method of the Room class, you are told when a headset or a Bluetooth device is plugged in or removed, or the audio route is changed.

  • The closure receives the selected device (or nil) and every device from VideoSDK.getMics().

  • It is called once right away with the current state, then after each change. It is always called on the main queue.

  • Calling it again replaces the previous closure. Pass nil to remove it.

Example​

self.room?.setAudioDeviceChangeListener { selected, available in
print("Audio device in use: \(selected?.label ?? "none")")
print("Available: \(available.map(\.label))")
// refresh your audio device picker here
}

// stop listening
self.room?.setAudioDeviceChangeListener(nil)

changeMic()​

  • Participant can change the microphone using changeMic(deviceId:) method of Room class.

  • It is async throws, so call it with try await inside a Task.

  • Pass the deviceId of a microphone from VideoSDK.getMics(). If you pass no device, the SDK moves to the next microphone in the list.

  • If the mic is on, it is turned off and on again with the new microphone, so you get onStreamDisabled and then onStreamEnabled for your audio stream. If the mic is off, changeMic() only selects the microphone, and the next unmuteMic() uses it.

  • If the switch fails, the SDK goes back to the previous microphone and throws the error.

Example​

func changeAudioDevice(device: MicrophoneDeviceInfo) {
Task {
do {
try await self.room?.changeMic(deviceId: device.deviceId)
} catch let error as VideoSDKError where error == .ERROR_NO_MICROPHONE_DEVICE_FOUND {
print("Microphone not found: \(device.label)")
} catch {
print("Could not change the mic: \(error)")
}
}
}
caution

deviceId should only be a deviceId from the array that VideoSDK.getMics() returns. For any other value, nothing changes: changeMic() throws ERROR_NO_MICROPHONE_DEVICE_FOUND, and the same error is sent to onError(error:).

changeMic(customMicrophoneTrack:)​

  • By using changeMic(customMicrophoneTrack:) method of Room class, participant can switch the mic to a custom audio track while in the room.

  • If the mic is on, it is turned off and on again with the new track. If the mic is off, it is turned on with the new track.

  • The SDK keeps the track for later calls to unmuteMic(). If the call fails, the SDK stops the track.

Task {
do {
let track = try await VideoSDK.createMicrophoneAudioTrack(encoderConfig: .high_quality)
try await self.room?.changeMic(customMicrophoneTrack: track)
} catch {
print("Could not change the mic: \(error)")
}
}

Changing Camera Input Device​

changeCam()​

  • By using changeCam() function of Room class, a participant can stream from front / rear camera while in the room.

  • Call it with no argument to move to the next camera, for example from the front camera to the rear one. To pick a camera, pass its deviceId from VideoSDK.getCameras(). The deviceId is not the camera name.

  • It is async throws, so call it with try await inside a Task.

  • If the camera is on, it is turned off and on again with the new camera, so you get onStreamDisabled and then onStreamEnabled for your video stream. If the camera is off, changeCam() only selects the camera, and the next enableCam() uses it.

  • If no camera has the deviceId you pass, nothing changes: changeCam() throws ERROR_NO_WEBCAM_DEVICE_FOUND, and the same error is sent to onError(error:).

note

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

Example​

@IBAction func cameraButtonTapped(_ sender: Any) {
Task {
do {
// switch to the next camera, for example from front to back
try await self.room?.changeCam()
} catch {
print("Could not switch the camera: \(error)")
}
}
}

To let the user pick a camera, list the cameras with VideoSDK.getCameras() and pass the deviceId of the one they choose. Each CameraDeviceInfo has a label to show, a deviceId, and a facingMode (.front, .back, or nil). VideoSDK.getSelectedVideoDevice() returns the camera the SDK opens or is using.

// the cameras on the device, to show in your camera picker
let cameras = VideoSDK.getCameras()

// call this with the camera the user picked
func selectCamera(_ camera: CameraDeviceInfo) {
Task {
do {
try await self.room?.changeCam(deviceId: camera.deviceId)
} catch {
print("Could not switch the camera: \(error)")
}
}
}

API Reference​

The API references for all the methods and events utilised in this guide are provided below.

Got a Question? Ask us on discord