AVAudioSession AVAudioSessionCategoryPlayAndRecord сбой

Я хотел бы записывать видео с аудио с помощью AVCaptureSession. Для этого мне нужна AudioSessionCategory AVAudioSessionCategoryPlayAndRecord, так как мое приложение также воспроизводит видео со звуком.

Я хочу, чтобы звук звучал из динамика по умолчанию, и я хочу, чтобы он смешивался с другим звуком. Поэтому мне нужны параметры AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers.

Если во время воспроизведения другого звука я делаю следующее: в звуке из другого приложения есть явный слышимый сбой:

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

Есть ли способ избавиться от этой ошибки?

Похоже, что там, где a AVAudioSessionRouteChangeReasonRouteConfigurationChange уведомлено AVAudioSessionRouteChangeReasonCategoryChange без микрофонного входа, на микрофонный вход.

Изменение конфигурации (и сбой) также происходит, когда приложение переходит на задний план (с отключением или без отключения аудио сессии). При возврате с фона без деактивации аудио сессии глюки начинают возникать при изменении конфигурации AVCaptureSession, т.е. когда камера переключается спереди назад. В этом случае маршрутизация звука не затрагивается, и это происходит только при возврате из фона без деактивации аудио сессии. Уведомление о том, что изменение маршрута запускается дважды. Однажды отключите микрофон и один раз, чтобы включить его снова.

Обратите внимание, что это поведение легко воспроизводится при загрузке примера Apple AVCamManual. Добавьте в viewDidLoad из AAPLCameraViewController.m следующее:

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

Некоторые другие странные вещи, которые могут быть связаны:

Сначала установите категорию звука AVAudioSessionCategoryAmbient и активируйте ее:

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

а затем измените категорию:

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

другой звук останавливается, несмотря на флаг опций. Ошибок не возникает.

Ответ 1

Как отмечалось в комментариях @Cbas, Apple Staff подтвердил, что при переключении с выходных только на вход + выходные маршруты есть глюк, и что для этого не существует обходного пути, возможным обходным путем является полное исключение переключения от выходных только до маршрутов ввода-вывода, всегда используйте категорию AVAudioSessionCategoryPlayAndRecord, даже если приложение не записывает. Кроме того, не устанавливайте категорию аудиосеанса еще раз, если она уже установлена ​​в AVAudioSessionCategoryPlayAndRecord или произойдет сбой.

Ответ 2

[self.captureSession startRunning];
[[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
[[AVAudioSession sharedInstance] setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

Когда capureSession запускается, отключает текущую аудиосессию и возобновляет работу другого прерванного музыкального приложения в фоновом режиме, используйте эту опцию AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation.

Сбросьте категорию AVAudioSessionCategoryPlayAndRecord с текущей аудиосессией и снова выполните avtive.

Я надеюсь, что это работает для вас.