AVAudioSession endInterruption() returns an NSOSStatusErrorDomain
-
04-12-2019 - |
Question
I'm trying to solve an AVAudioSession problem since many hours ago and didn't get success!!
I found lots of guys talking about problems with endInterruption but none of them talking about this error:
Unable to reactivate the audio session after the interruption ended: Error Domain=NSOSStatusErrorDomain Code=560161140 "The operation couldn’t be completed. (OSStatus error 560161140.)"
I tried converting this code to ASCII to check the Audio Code Results, but there is nothing related to this number.
My code to init the session:
- (void) setupAudioSession {
mySession = [AVAudioSession sharedInstance];
[mySession setDelegate: self];
NSError *audioSessionError = nil;
[mySession setCategory: AVAudioSessionCategoryPlayback error: &audioSessionError];
if (audioSessionError != nil) {
NSLog (@"Error setting audio session category: %@", [audioSessionError description]);
return;
}
// Activate the audio session
[mySession setActive: YES error: &audioSessionError];
if (audioSessionError != nil) {
NSLog (@"Error activating audio session during initial setup: %@", [audioSessionError description]);
return;
}
// Prepare audio file to play
NSBundle *mainBundle = [NSBundle mainBundle];
NSURL *bgSoundURL = [NSURL fileURLWithPath:[mainBundle pathForResource:@"bg_sound" ofType:@"aif"]];
bgPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:bgSoundURL error:&audioSessionError];
if (!bgPlayer) {
NSLog(@"No bgPlayer: %@", [audioSessionError description]);
}
[bgPlayer setNumberOfLoops:-1];
[bgPlayer prepareToPlay];
}
And the code of endInterruption method:
- (void) endInterruptionWithFlags: (NSUInteger) flags {
if (flags & AVAudioSessionInterruptionFlags_ShouldResume) {
NSError *endInterruptionError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &endInterruptionError];
if (endInterruptionError != nil) {
NSLog (@"Unable to reactivate the audio session after the interruption ended: %@", [endInterruptionError description]);
return;
} else {
NSLog (@"Audio session reactivated after interruption.");
if (interruptedWhilePlaying) {
self.interruptedWhilePlaying = NO;
// Resume playback by sending a notification to the controller object, which
// in turn invokes the playOrStop: toggle method.
NSString *MixerHostAudioObjectPlaybackStateDidChangeNotification = @"MixerHostAudioObjectPlaybackStateDidChangeNotification";
[[NSNotificationCenter defaultCenter] postNotificationName: MixerHostAudioObjectPlaybackStateDidChangeNotification object: self];
}
}
}
}
A big part of this code was extracted from Apple Mixer Host Sample. And it's weird that the sample works fine!
Can you guys figure out what is wrong?
Thanks.
Solution
I solved the problem changing the way to design my audio code. Instead of use AVAudioSession and its delegate methods, I change to the C style to work with audio.
I implemented the function:
void interruptionListenerCallback (void *inUserData, UInt32 interruptionState) {}
And it was initialized with:
AudioSessionInitialize (NULL, NULL, interruptionListenerCallback, self);
inside my -(id) init method.
Hope it helps you also. Best.
OTHER TIPS
"If this delegate method receives the AVAudioSessionInterruptionFlags_ShouldResume constant in its flags parameter, the audio session is immediately ready to be used."
You didn't handle the callback correctly. When you receive AVAudioSessionInterruptionFlags_ShouldResume, your audio session is ALREADY ready to use. You need to call setActive when you get a DIFFERENT flag.
Hope it helps...
Using @Trinca answer that what I did on "ARC'ed" project:
AudioSessionInitialize (NULL, NULL, interruptionListenerCallback, (__bridge void *)(self.player));
Were self.player is your player instance that you pass to the callback function.
Then implement the callback:
void interruptionListenerCallback (void *inUserData, UInt32 interruptionState) {
NSLog(@"itnerp state %li",interruptionState);
NSLog(@"inUserData %@",inUserData);
AVAudioPlayer *pl = (__bridge AVAudioPlayer*)inUserData;
switch (interruptionState) {
case 0:
[pl play];
break;
case 1:
[pl pause];
break;
}
}
GOOD LUCK
Shani
use audiosession.setmode if it is voip