Уведомление о прерывании IOS AVAudioSession не работает должным образом
Я хочу знать, когда мой AVAudioRecorder
недоступен (например, когда музыка начинает воспроизводиться).
Поскольку audioRecorderEndInterruption
будет устаревшим с iOS 9, я сосредоточен на уведомлении прерывания AVAudioSession
(но ни один из них не работает как ожидалось).
Проблема в том, что уведомление о прерывании никогда не вызывается, если приложение было и остается на переднем плане, когда происходит прерывание.
Например: пользователь запускает и останавливает воспроизведение музыки, не перемещая приложение в фоновом режиме.
Чтобы обнаружить любые прерывания, которые я использую:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionWasInterrupted:) name:AVAudioSessionInterruptionNotification object:nil];
...
- (void)audioSessionWasInterrupted:(NSNotification *)notification {
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
NSLog(@"Interruption notification");
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
NSLog(@"InterruptionTypeBegan");
} else {
NSLog(@"InterruptionTypeEnded");
}
}
}
Я получаю InterruptionTypeBegan
, как ожидалось, но InterruptionTypeEnded
не вызывается, если приложение все еще находится на переднем плане (это означает, что он не будет вызываться, пока приложение не будет помещено в фоновом режиме и обратно на передний план).
Как я могу получать уведомление InterruptionTypeEnded
, когда прерывание происходит, когда приложение находится на переднем плане?
Ответы
Ответ 1
Это распространенная проблема, затрагивающая любое приложение, использующее компоненты AV
framework (то же самое относится к родным приложениям iOS).
Как объяснено в документации по поводу прерывания звука, InterruptionTypeEnded
должен применяться в упомянутом сценарии:
Если пользователь отклоняет прерывание... система вызывает ваш метод обратного вызова, указывая на то, что прерывание завершено.
Однако он также утверждает, что InterruptionTypeEnded
может вообще не вызываться:
Нет гарантии, что прерывание начала будет иметь прерывание конца.
Поэтому в упомянутом сценарии необходим другой подход.
Когда дело доходит до обработки перерывов в работе, проблема не будет длиться долго. iOS 9 эффективно предотвращает использование внешних источников звука во время вызова обработчика аудио приложения.
Способом обработки точной проблемы прерывания медиа может быть прослушивание MPMusicPlayerController
playbackState
, как показано в этом вопросе stackoverflow: Обнаружение, если музыка играет?.
Более прямой способ справиться с проблемой прерываний будет следующим:
Полностью заблокируйте внешние прерывания звука, повторно используя ваш аудиокомпонент во время InterruptionTypeBegan
.
Или, указав индикацию пользовательского интерфейса, что внешний медиа-источник прервал сеанс аудио (например, неактивный микрофон).
Надеюсь, придумает лучшее решение проблемы, но пока это даст вам некоторые варианты решения проблемы прерывания.
Ответ 2
Если вы еще этого не сделали, попробуйте установить свойство AVCaptureSession
usesApplicationAudioSession
на НЕТ.
Этот вопрос и ответ могут служить хорошей ссылкой, если вы ищете более подробную информацию.
Ответ 3
Я пробую это и обнаруживаю, что InterruptionTypeEnded может вызывать после паузы в музыке в каком-то приложении, но другие не вызываются при паузе.
Мое решение - обновить пользовательский интерфейс, чтобы остановить запись информации о пользователе и выполнить некоторые связанные работы, такие как работа с файлами. Когда прерывание заканчивается, активная AVAudioSession, , если не имеет ошибки, запустите новую запись.
Если вы хотите присоединиться к файлу до и после прерывания, ответ на этот вопрос: AVAudioRecorder записывает только аудио после перерыва, может быть вам полезен.