Reputation: 264
AVAudioPlayer
plays audio on the background and user pauses it either through headset controls or lock screen controls.
If user does it for under 30 seconds and tries to resume - everything works fine.
If user tries to resume it in over 30 seconds - audio starts playing, but a second later audioSessionInterruptionNotification
from AVAudioSessionDelegate
is triggered, with AVAudioSessionInterruptionWasSuspendedKey
YES.
After that the app stops reacting for remote controls events completely. Events are being triggered, but AVAudioPlayer
does not react to any commands. In fact, [[self audioplayer] isAudioPlaying]
returns NO while playback continues.
If I try to handle it the following way - it helps (so I set AVAudioSession to not active, and then playHelper method activates it and plays audio), but there is a glitch, because notification is being triggered after it starts playing.
- (void)audioSessionInterruptionNotification:(NSNotification *)interruption {
UInt8 interruptionType = [[interruption.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue];
NSLog(@"Session interrupted > --- %s ---\n", interruptionType == AVAudioSessionInterruptionTypeBegan ? "Begin Interruption" : "End Interruption");
NSDictionary *notificationUserInfo = [interruption userInfo];
if (interruptionType == AVAudioSessionInterruptionTypeBegan) {
if ([notificationUserInfo valueForKey:AVAudioSessionInterruptionWasSuspendedKey]) {
[[AVAudioSession sharedInstance] setActive:false error:nil];
[self playHelper];
} else {
[self interruptionStarted];
}
} else if (interruptionType == AVAudioSessionInterruptionTypeEnded) {
[self interruptionEnded:(NSUInteger)[notificationUserInfo objectForKey:AVAudioSessionInterruptionOptionKey]];
}
}
Please advise what could be causing this.
Upvotes: 3
Views: 825
Reputation: 1913
The AVAudioSessionInterruptionWasSuspendedKey
notification is thrown because you should deactivate your audio session whenever your app goes to background and nothing is playing. If your player is playing when user pauses from lock screen you don't have to deactivate the session.
You should listen for the notifications when your app is being sent to background and when it becomes active, the code in Swift should look like this.
NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification, object: nil, queue: .main) { sender in
guard self.player.isPlaying == false else { return }
self.setSession(active: false)
}
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: .main) { sender in
guard self.player.isPlaying else { return }
self.setSession(active: true)
}
func setSession(active: Bool) -> Bool {
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(.playback, mode: .default)
try session.setActive(active)
return true
} catch let error {
print("*** Failed to activate audio session: \(error.localizedDescription)")
return false
}
}
Upvotes: 1