web-dev-qa-db-ja.com

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通知を受け取るにはどうすればよいですか?

18

これは、AVフレームワークコンポーネントを使用するすべてのアプリに影響する広範な問題です(ネイティブiOSアプリでも同じです)。

のオーディオの中断に関するドキュメント で説明されているように、実際にInterruptionTypeEndedは上記のシナリオで適用する必要があります。

ユーザーが中断を却下すると、システムはコールバックメソッドを呼び出し、中断が終了したことを示します。

ただし、InterruptionTypeEndedがまったく呼び出されない可能性があることも示されています。

開始の中断に終了の中断があるという保証はありません。

したがって、上記のシナリオでは別のアプローチが必要です。


音楽の中断の処理に関しては、問題は長くは続きません。 iOS 9は、アプリのオーディオハンドラーが呼び出されている間、外部のオーディオソースが使用されるのを効果的に防ぎます。

メディアの中断の正確な問題を処理する方法は、このスタックオーバーフローの質問に示されているように、MPMusicPlayerControllerplaybackStateを聞くことです。 音楽が再生されているかどうかを検出していますか?


中断の問題を処理するより直接的な方法は、次のいずれかです。

InterruptionTypeBeganの時点でオーディオコンポーネントを再度呼び出すことにより、外部のオーディオ割り込みを完全にブロックします。

または、外部メディアソースがオーディオセッションを中断したことをUIに示すことによって(たとえば、非アクティブなマイクを表示する)。


うまくいけば、が問題のより良い解決策を思い付くでしょうが、それまでの間、これは中断の問題を解決するためのいくつかのオプションを提供するはずです。

6