Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVAudioSession AVAudioSessionCategoryPlayAndRecord glitch

I would like to record videos with audio using AVCaptureSession. For this I need the AudioSessionCategory AVAudioSessionCategoryPlayAndRecord, since my app also plays back video with sound.

I want audio to be audible from the default speaker and I want it to mix with other audio. So I need the options AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers.

If I do the following while other audio is playing there is a clear audible glitch in the audio from the other app:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];

Is there a way to get rid of this glitch?

It seems to occur when the there's a AVAudioSessionRouteChangeReasonRouteConfigurationChange as notified by AVAudioSessionRouteChangeReasonCategoryChange from no mic input, to mic input.

The configuration change (and glitch) also occurs when the app goes to the background (with or without deactivating the audio session). When returning from the background without deactivating the audio session, the glitches start to occur when the AVCaptureSession configuration is changed i.e. when the camera is switched from front to back. In this case the audio routing is not touched, and it only occurs when returning from the background without deactivating the audio session. The notification that the route changes is fired twice. Once to disable the mic, and once to enable it again.

Note that this behavior is easily reproducible by downloading Apple's AVCamManual example. Add the following to the viewDidLoad of AAPLCameraViewController.m:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
…
session.usesApplicationAudioSession = YES;
session.automaticallyConfiguresApplicationAudioSession = NO;

Some other weird thing, which might be related:

Set the audio category to AVAudioSessionCategoryAmbient first and activate it:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient withOptions:0 error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];

and then change the category:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];

other audio stops playing despite the options flag. No errors are thrown.

like image 715
Jorn van Dijk Avatar asked Dec 23 '14 00:12

Jorn van Dijk


1 Answers

As pointed out by @Cbas in the comments, an Apple Staff has confirmed there is glitch when switching from output-only to input+output routes and that there is no workaround for that issue, a possible workaround is to totally avoid switching from output-only to input-output routes by always use the AVAudioSessionCategoryPlayAndRecord category even when the app is not recording. Also, don't set the audio session category again if it has already be set to AVAudioSessionCategoryPlayAndRecord or the glitch will occur.

like image 108
Thanh Pham Avatar answered Sep 20 '22 18:09

Thanh Pham