Skip to contentSkip to navigationSkip to topbar
On this page

Configuring Audio, Video Input and Output devices - iOS


(warning)

Warning

This documentation is for reference only. We are no longer onboarding new customers to Programmable Video. Existing customers can continue to use the product until December 5, 2026(link takes you to an external page).

We recommend migrating your application to the API provided by our preferred video partner, Zoom. We've prepared this migration guide(link takes you to an external page) to assist you in minimizing any service disruption.

In this guide, we'll show you how to configure Audio and Video input and output devices from your Twilio Video application. Taking advantage of the ability to control input and output devices lets you build a better end user experience.


Selecting a specific Video Input

selecting-a-specific-video-input page anchor

The CameraSource class captures from an AVCaptureDevice, and provides frames to a LocalVideoTrack.

Add selected video source to local track

1
// The default initializer will succeed if the front camera is available.
2
3
if let camera = CameraSource(delegate: self),
4
let videoTrack = LocalVideoTrack(source: camera) {
5
6
// VideoView is a VideoRenderer and can be added to any VideoTrack.
7
let renderer = VideoView(frame: view.bounds)
8
9
// Add renderer to the video track
10
videoTrack.addRenderer(renderer)
11
12
self.localVideoTrack = videoTrack
13
self.camera = camera
14
self.view.addSubview(renderer)
15
} else {
16
print("Couldn't create CameraSource or LocalVideoTrack")
17
}
18
19
20
// Select between the front and back camera.
21
func flipCamera() {
22
var newDevice: AVCaptureDevice?
23
24
if let camera = self.camera, let captureDevice = camera.device {
25
if captureDevice.position == .front {
26
newDevice = CameraSource.captureDevice(position: .back)
27
} else {
28
newDevice = CameraSource.captureDevice(position: .front)
29
}
30
31
if let newDevice = newDevice {
32
camera.selectCaptureDevice(newDevice) { (captureDevice, videoFormat, error) in
33
if let error = error {
34
print("Error selecting capture device.\ncode = \((error as NSError).code) error = \(error.localizedDescription)")
35
}
36
}
37
}
38
}
39
}

Optionally set VideoEncodingMode in ConnectOptions

VideoEncodingMode represents the modes of behavior of the videoEncodingMode property in ConnectOptions. The videoEncodingMode API is mutually exclusive with existing codec management APIs EncodingParameters.maxVideoBitrate and preferredVideoCodecs. The default value is unset.

auto - In this mode, the SDK selects the video codecs and manages encodings automatically.

1
let connectOptions = ConnectOptions(token: accessToken) { (builder) in
2
builder.roomName = "my-room"
3
builder.videoEncodingMode = .auto
4
}
5
var room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)

Selecting specific Audio routes

selecting-specific-audio-routes page anchor

Typically, the audio input and output route is chosen by the end user in Control Center. By default TwilioVideo will manage the application's AVAudioSession and configure it for video conferencing use cases. If you wish to modify audio behavior, including session configuration, you can create your own DefaultAudioDevice(link takes you to an external page) and provide it as an option before connecting to a Room.

1
// Override the device before creating any Rooms or Tracks.
2
self.audioDevice = DefaultAudioDevice()
3
TwilioVideoSDK.audioDevice = self.audioDevice
4
5
let localAudioTrack = LocalAudioTrack()
6
let connectOptions = ConnectOptions(token: accessToken) { (builder) in
7
builder.roomName = "my-room"
8
9
if let audioTrack = localAudioTrack {
10
builder.audioTracks = [ audioTrack ]
11
}
12
}
13
var room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)

To configure the AVAudioSession, DefaultAudioDevice executes the kDefaultAVAudioSessionConfigurationBlock by default. You can alter the AVAudioSession configuration for your application by providing a block to the DefaultAudioDevice. For example, the input and output audio routes can be overwritten by altering the AVAudioSession configuration in the block that you provide to DefaultAudioDevice.

The following example demonstrates how to configure AVAudioSession for voice chat scenarios. This will prefer using the device's receiver and bottom microphone like a voice call in the Phone app.

1
// Change the audio route after connecting to a Room.
2
self.audioDevice.block = {
3
do {
4
DefaultAudioDevice.DefaultAVAudioSessionConfigurationBlock()
5
6
let audioSession = AVAudioSession.sharedInstance()
7
try audioSession.setMode(.voiceChat)
8
} catch let error as NSError {
9
print("Fail: \(error.localizedDescription)")
10
}
11
}
12
13
self.audioDevice.block();

You must use your own AVAudioEngineDevice audio device that uses the kAudioUnitSubType_RemoteIO componentSubType of the AudioComponentDescription in order to change microphone orientations.

The next Objective-C example demonstrates how to select the back microphone. This might be useful if your subject is behind the phone, and being captured with the back camera.

1
2
// Change this to `AVAudioSessionOrientationFront` if you wish to use the front microphone.
3
NSString *microphone = AVAudioSessionOrientationBack;
4
5
typeof(self) __weak weakSelf = self;
6
self.audioDevice.block = ^ {
7
kTVIDefaultAVAudioSessionConfigurationBlock();
8
[weakSelf setMicrophoneInUse:microphone];
9
};
10
self.audioDevice.block();
11
12
- (void)setMicrophoneInUse:(NSString *)nextDataSource {
13
NSError *theError = nil;
14
BOOL result = YES;
15
16
AVAudioSession *session = [AVAudioSession sharedInstance];
17
18
result = [session setActive:YES error:&theError];
19
20
// Get the set of available inputs. If there are no audio accessories attached, there will be
21
// only one available input -- the built in microphone.
22
NSArray *inputs = [session currentRoute].inputs;
23
24
// Locate the Port corresponding to the built-in microphone.
25
AVAudioSessionPortDescription *builtInMicPort = nil;
26
for (AVAudioSessionPortDescription *port in inputs) {
27
if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
28
builtInMicPort = port;
29
break;
30
}
31
}
32
33
if ([builtInMicPort.preferredDataSource.orientation isEqualToString:nextDataSource]) {
34
return;
35
}
36
37
// loop over the built-in mic's data sources and attempt to locate the specified microphone
38
AVAudioSessionDataSourceDescription *theDataSource = nil;
39
for (AVAudioSessionDataSourceDescription *source in builtInMicPort.dataSources) {
40
if ([source.orientation isEqual:nextDataSource]) {
41
theDataSource = source;
42
break;
43
}
44
} // end data source iteration
45
46
if (theDataSource) {
47
theError = nil;
48
if ([theDataSource.orientation isEqualToString:AVAudioSessionOrientationBack]) {
49
result = [theDataSource setPreferredPolarPattern:AVAudioSessionPolarPatternSubcardioid error:&theError];
50
if (!result) {
51
NSLog (@"Failed to set AVAudioSessionPolarPatternSubcardioid failed");
52
}
53
} else if ([theDataSource.orientation isEqualToString:AVAudioSessionOrientationFront]) {
54
result = [theDataSource setPreferredPolarPattern:AVAudioSessionPolarPatternCardioid error:&theError];
55
if (!result) {
56
NSLog (@"Failed to set AVAudioSessionPolarPatternCardioid failed");
57
}
58
}
59
60
// Set a preference for the front data source.
61
theError = nil;
62
result = [builtInMicPort setPreferredDataSource:theDataSource error:&theError];
63
if (!result) {
64
// an error occurred. Handle it!
65
NSLog(@"setPreferredDataSource failed");
66
}
67
}
68
69
// Make sure the built-in mic is selected for input. This will be a no-op if the built-in mic is
70
// already the current input Port.
71
theError = nil;
72
result = [session setPreferredInput:builtInMicPort error:&theError];
73
if (!result) {
74
// an error occurred. Handle it!
75
NSLog(@"setPreferredInput failed");
76
}
77
}

Need some help?

Terms of service

Copyright © 2024 Twilio Inc.