Skip to main content
Version: 4.x.x

Manage Audio and Video Devices - iOS

This feature allows hosts to switch their microphone or camera during a live stream. Only hosts (in SEND_AND_RECV mode) can change input devices. Audience members (in RECV_ONLY mode) keep receiving the broadcast.

Changing Audio Input Device​

getMics()​
  • The getMics() method of VideoSDK class returns the audio devices as an array of MicrophoneDeviceInfo. Each entry has a label and a deviceId.

  • returns [MicrophoneDeviceInfo]

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

Example​

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

// the microphones you can pass to changeMic()
let mics = devices.filter { $0.label != "Speaker" }
changeMic()​
  • The host 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 the host gets onStreamDisabled and then onStreamEnabled for their audio stream, and the audience briefly stops hearing them. 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

Pass only 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, the host can switch the mic to a custom audio track during the live stream.

  • 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.

Example​

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)")
}
}
setAudioDevice()​
  • By using setAudioDevice(_:) method of Room class, the host can route audio to a device from VideoSDK.getMics(). Pass the Speaker entry to play audio on the loudspeaker, or a microphone to use it with its matching output.

  • It throws, so call it with try. If the device is not available, it throws ERROR_NO_MICROPHONE_DEVICE_FOUND and nothing changes.

  • To know when a headset or Bluetooth device is plugged in or removed, register a closure with setAudioDeviceChangeListener(_:). It is called at once with the current state, then on every change, always on the main queue.

Example​

// play audio on the loudspeaker
if let speaker = VideoSDK.getMics().first(where: { $0.label == "Speaker" }) {
do {
try self.room?.setAudioDevice(speaker)
} catch {
print("Could not change the audio device: \(error)")
}
}

// keep your device picker up to date
self.room?.setAudioDeviceChangeListener { selected, available in
print("Selected: \(selected?.label ?? "none"), available: \(available.map(\.label))")
}

Changing Camera Input Device​

changeCam()​
  • By using changeCam() function of Room class, a host can stream from front / rear camera during the live stream.

  • 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().

  • 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 the host gets onStreamDisabled and then onStreamEnabled for their video stream, and the audience sees the video stop and start. 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 host 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 in your picker, a deviceId, and a facingMode (.front or .back).

// the cameras on the device; show each camera's label in your camera picker
let cameras = VideoSDK.getCameras()

// call this with the camera the host 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 utilized in this guide are provided below.

Got a Question? Ask us on discord