How add AVCaptureDeviceInput to AVCaptureSession f

2019-09-02 17:53发布

问题:

I need to record a video with AVCaptureSession in an iOS app.

When I add AVCaptureDeviceInput to my current AVCaptureSession, it always adds the iphone microphone. I have the bluetooth microphone connected to the device. But it is not recording from the external microphone.

I'm doing this:

- (BOOL)prepareAudioSession {

// deactivate session
BOOL success = [[AVAudioSession sharedInstance] setActive:NO error: nil];
if (!success) {
    NSLog(@"deactivationError");
}

// Bluetooth support enable
UInt32 allowBluetoothInput = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (allowBluetoothInput),&allowBluetoothInput);
// set audio session category AVAudioSessionCategoryPlayAndRecord options AVAudioSessionCategoryOptionAllowBluetooth

success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowBluetooth|AVAudioSessionCategoryOptionMixWithOthers error:nil];
//success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];

if (!success) {
    NSLog(@"setCategoryError");
}

// activate audio session
success = [[AVAudioSession sharedInstance] setActive:YES error: nil];
if (!success) {
    NSLog(@"activationError");
}
return success;
}

But it's still not working. Anyone have any idea? Thanks

回答1:

I think there is a problem with how you are forming the AVCaptureSession while setting the category with options. Try something like this to make AVCaptureSession:

    // create and set up the audio session
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setDelegate:self];
[audioSession setCategory: AVAudioSessionCategoryPlayAndRecord error: nil];
[audioSession setActive: YES error: nil];

// set up for bluetooth microphone input
UInt32 allowBluetoothInput = 1;
OSStatus stat = AudioSessionSetProperty (
                         kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,
                         sizeof (allowBluetoothInput),
                         &allowBluetoothInput
                        );
NSLog(@"status = %x", stat);    // problem if this is not zero

// check the audio route
UInt32 size = sizeof(CFStringRef);
CFStringRef route;
OSStatus result = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &route);
NSLog(@"route = %@", route);    
// if bluetooth headset connected, should be "HeadsetBT"
// if not connected, will be "ReceiverAndMicrophone"

// now, play a quick sound we put in the bundle (bomb.wav)
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef        soundFileURLRef;
SystemSoundID   soundFileObject;
soundFileURLRef  = CFBundleCopyResourceURL (mainBundle,CFSTR ("bomb"),CFSTR ("wav"),NULL);

NSError *error = nil;

audioRecorder = [[AVAudioRecorder alloc]
                 initWithURL:soundFileURLRef
                 settings:recordSettings
                 error:&error];
if (error)
{
    NSLog(@"error: %@", [error localizedDescription]);
} else {
    [audioRecorder prepareToRecord];
}

I took the code from here because it always works for me.

NOTE: This code will re route the audio while playing back to your headset itself. To use speaker while playing back, look at the comment section of accepted answer.



回答2:

The solution is this:

In your AppDelegate

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];

in your AVCaptureSession after add your AVCaptureDeviceInput

self.captureSession.usesApplicationAudioSession = true;
    self.captureSession.automaticallyConfiguresApplicationAudioSession = false;

My setup for Audio:

/* Audio */
    AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];


    audioIn = [[AVCaptureDeviceInput alloc] initWithDevice:audioDevice error:nil];
    if ( [_captureSession canAddInput:audioIn] ) {
        [_captureSession addInput:audioIn];
    }

    audioOut = [[AVCaptureAudioDataOutput alloc] init];
    // Put audio on its own queue to ensure that our video processing doesn't cause us to drop audio
    dispatch_queue_t audioCaptureQueue = dispatch_queue_create( "com.apple.sample.capturepipeline.audio", DISPATCH_QUEUE_SERIAL );
    [audioOut setSampleBufferDelegate:self queue:audioCaptureQueue];


    if ( [self.captureSession canAddOutput:audioOut] ) {
        [self.captureSession addOutput:audioOut];
    }
    _audioConnection = [audioOut connectionWithMediaType:AVMediaTypeAudio];

    //AVAudioSessionRouteDescription *current =[[AVAudioSession sharedInstance] currentRoute];*/
    if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")){
        self.captureSession.usesApplicationAudioSession = true;
        self.captureSession.automaticallyConfiguresApplicationAudioSession = false;
        //[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
    }