Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
352 views
in Technique[技术] by (71.8m points)

avfoundation - iOS AVAudioSession interruption notification not working as expected

I want to know when my AVAudioRecorder is inaccessible (e.g when music starts playing).

As audioRecorderEndInterruption will be deprecated with iOS 9 I am focusing on AVAudioSession's interruption notification (but neither is working as expected).

The issue is that the interruption notification is never called if the app was and remains in the foreground when the interruption occurs.

E.g: The user starts and stops playing music without moving the application into the background.

To detect any interruptions I am using:

[[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");
        }
    }
}

I get InterruptionTypeBegan as expected, but InterruptionTypeEnded isn't called if the app is still in the foreground (meaning it won't be called until the app is placed in the background and back into the foreground).

How may I receive InterruptionTypeEnded notification when the interruption occurs while the app is in the foreground?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is a widespread problem affecting any app using AV framework components (the same goes for native iOS apps).

As explained in ?'s documentation on the subject of audio interruptions, the InterruptionTypeEnded should actually be applied in the scenario mentioned:

If the user dismisses the interruption ... the system invokes your callback method, indicating that the interruption has ended.

However, it also states that the InterruptionTypeEnded might not be called at all:

There is no guarantee that a begin interruption will have an end interruption.

Therefore, a different approach is needed in the scenario mentioned.


When it comes to handling music interruptions, the issue won't be around for long. iOS 9 effectively prevents outside audio sources to be used while the app's audio handler is invoked.

A way to handle the exact issue of media interruption could be to listen to MPMusicPlayerController's playbackState, as shown in this stackoverflow question: Detecting if music is playing?.


A more direct way to handle the issue of interruptions would be to either:

Block outside audio interruptions completely by re-invoking your audio component at the time of InterruptionTypeBegan.

Or by giving a UI indication that an outside media source has interrupted the audio session (for example showing an inactive microphone).


Hopefully ? will come up with a better solution to the problem, but in the meantime this should give you some options to solve the interruption issue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...