Reputation: 382
I was wondering is there's a way to capture stereo audio using an AVCaptureSession. iOS 14 adds support for stereo audio for AVAudioRecorder, but so far I have been unsuccessful is capturing stereo audio through an AVCaptureSession.
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
[audioSession setActive:YES error:NULL];
NSArray *portDescriptions = audioSession.availableInputs;
AVAudioSessionPortDescription *builtInMicPort = nil;
for (AVAudioSessionPortDescription *port in portDescriptions) {
if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
builtInMicPort = port;
break;
}
} // end input iteration
[audioSession setPreferredInput:builtInMicPort error:nil];
NSArray *supportedPolarPatterns = audioSession.preferredInput.dataSources.firstObject.supportedPolarPatterns;
[audioSession.preferredInput.dataSources.firstObject setPreferredPolarPattern:AVAudioSessionPolarPatternStereo error:nil];
[audioSession.preferredInput setPreferredDataSource:audioSession.preferredInput.dataSources.firstObject error:nil];
[audioSession setPreferredInputOrientation:AVAudioStereoOrientationPortrait error:nil];
device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionBack];
deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if([videoSession canAddInput:deviceInput]){
[videoSession addInput:deviceInput];
}
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
if([videoSession canAddInput:audioDeviceInput]){
[videoSession addInput:audioDeviceInput];
}
Upvotes: 0
Views: 1162
Reputation: 563
Here is the Swift 5 version. The device must support stereo. The older iPhones only support Omnidirectional or Cardioid, so it won't work.
// STEREO AUDIO RECORDING
do {
let audioSession : AVAudioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playAndRecord, options: .defaultToSpeaker)
try audioSession.setActive(true)
// select the built-in Back mic if available
let portDescriptions : [AVAudioSessionPortDescription] = audioSession.availableInputs ?? []
var builtInMicPort : AVAudioSessionPortDescription?
for port in portDescriptions {
if port.portType == AVAudioSession.Port.builtInMic {
print("builtInMic")
builtInMicPort = port
}
}
try audioSession.setPreferredInput(builtInMicPort)
var frontDataSource : AVAudioSessionDataSourceDescription?
print("builtInMicPort: \(builtInMicPort)")
for source in builtInMicPort?.dataSources ?? [] {
print("source: \(source)")
if source.orientation == AVAudioSession.Orientation.front {
print("front")
frontDataSource = source
}
}
var supportedPolarPatterns = frontDataSource?.supportedPolarPatterns
print("SUPPORTED POLAR PATTERNS: \(String(describing: supportedPolarPatterns))")
var isStereoSupported : Bool = supportedPolarPatterns?.contains(AVAudioSession.PolarPattern.stereo) ?? false
print("isStereoSupported: \(isStereoSupported)")
if (isStereoSupported == true) {
if #available(iOS 14.0, *) {
try frontDataSource?.setPreferredPolarPattern(AVAudioSession.PolarPattern.stereo)
try audioSession.preferredInput?.setPreferredDataSource(frontDataSource)
if #available(iOS 14.0, *) {
try audioSession.setPreferredInputOrientation(AVAudioSession.StereoOrientation.portrait)
}
// video
self.captureSession?.usesApplicationAudioSession = true
self.captureSession?.automaticallyConfiguresApplicationAudioSession = false
} else {
// default to capture device audio
let audioInput = AVCaptureDevice.default(for: .audio)
if captureSession.canAddInput(try AVCaptureDeviceInput(device: audioInput!)) {
try captureSession.addInput(AVCaptureDeviceInput(device: audioInput!))
}
}
} else {
// default to capture device audio
let audioInput = AVCaptureDevice.default(for: .audio)
if captureSession.canAddInput(try AVCaptureDeviceInput(device: audioInput!)) {
try captureSession.addInput(AVCaptureDeviceInput(device: audioInput!))
}
}
} catch {
// default to capture device audio
print("No audio")
let audioInput = AVCaptureDevice.default(for: .audio)
if captureSession.canAddInput(try AVCaptureDeviceInput(device: audioInput!)) {
try captureSession.addInput(AVCaptureDeviceInput(device: audioInput!))
}
}
Upvotes: 1
Reputation: 382
Here's the working code:
//STEREO AUDIO RECORDING
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
[audioSession setActive:YES error:NULL];
// select the built-in Back mic if available
NSArray *portDescriptions = audioSession.availableInputs;
AVAudioSessionPortDescription *builtInMicPort = nil;
for (AVAudioSessionPortDescription *port in portDescriptions) {
if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
builtInMicPort = port;
break;
}
} // end input iteration
[audioSession setPreferredInput:builtInMicPort error:nil];
AVAudioSessionDataSourceDescription* frontDataSource = nil;
for (AVAudioSessionDataSourceDescription* source in builtInMicPort.dataSources)
{
if ([source.orientation isEqual:AVAudioSessionOrientationFront])
{
frontDataSource = source;
break;
}
} // end data source iteration
NSArray *supportedPolarPatterns = frontDataSource.supportedPolarPatterns;
NSLog(@"SUPPORTED POLAR PATTERNS : %@", supportedPolarPatterns);
BOOL isStereoSupported = [supportedPolarPatterns containsObject:@"Stereo"];
if(isStereoSupported == YES){
if(@available(iOS 14.0, *)) {
[frontDataSource setPreferredPolarPattern:AVAudioSessionPolarPatternStereo error:nil];
} else {
// Fallback on earlier versions
}
}
[audioSession.preferredInput setPreferredDataSource:frontDataSource error:nil];
if(@available(iOS 14.0, *)) {
[audioSession setPreferredInputOrientation:AVAudioStereoOrientationPortrait error:nil];
}
videoSession = [[AVCaptureSession alloc] init];
//STEREO AUDIO RECORDING
videoSession.usesApplicationAudioSession = YES;
videoSession.automaticallyConfiguresApplicationAudioSession = NO;
Upvotes: 1
Reputation: 26
Try this:
videoSession.usesApplicationAudioSession = true
videoSession.automaticallyConfiguresApplicationAudioSession = false
I was able to get stereo working in iOS 14 with this added.
Upvotes: 1