I was trying to figure out what actually happens for weeks and I have no idea why I cannot continue playback after interruption, so probably you guys know an answer. AudioSessionSetActive(TRUE) always returns '!cat' which is kAudioSessionIncompatibleCategory while re-activation if my app plays in background and I am in different app. Although it works fine and continues playback if I caught interruption while being in my app.
Original code actually has all AudioSession and AudioQueue calls wrapped in macros which prints OSStatus if it means error, but I removed it for better readability. Also, [self pause] just toggles pause, so basically it calls AudioQueueStart(audioQueue, NULL) on upause but it doesn't work ofcourse if AudioSession fails.
Audio Session initialization code:
AudioSessionInitialize(NULL, NULL, _audioSessionInterruptionListener, self);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, _audioSessionPropertyListener, self);
AudioSessionSetActive(TRUE);
Interruption handler code:
- (void)handleInterruptionChangeToState:(AudioQueuePropertyID)inInterruptionState
{
if(inInterruptionState == kAudioSessionBeginInterruption)
{
NSLog(@"+Interruption");
if(self.state == NX_STATE_PLAY)
{
[self pause];
AudioSessionSetActive(FALSE);
isPausedByInterruption = YES;
}
}
else if(inInterruptionState == kAudioSessionEndInterruption)
{
if(isPausedByInterruption)
{
AudioSessionSetActive(TRUE);
[self pause];
isPausedByInterruption = FALSE;
}
NSLog(@"-Interruption");
}
}
This streamer source code can be found here https://bitbucket.org/and/amaudiostreamer/src/122de41fe6c0/AMAudioStreamer/AMAudioStreamer/Classes/NxAudioStreamer.m if it's gonna help somehow to resolve an issue..
If you look at
Listing 7-16 An interruption listener callback function
in the Audio Session Programming Guide cookbook section, the code sample (which seems to be compatible with your situation, using kAudioSessionCategory_MediaPlayback) doesn't actually perform thecall in the case of
kAudioSessionBeginInterruption
, and thecall in the case of
kAudioSessionEndInterruption
. I really don't think you should be doing this. This post seems to illustrate this problem also (getting a kAudioSessionIncompatibleCategory). What happens if you comment out both these calls?The reason why the problem occurs when your app in the background, not the foreground is a mystery. You should perhaps track the state (as you seem to be doing with NX_STATE_PLAY), then have two different methods ([self pause] and [self play]), as perhaps the [self pause] (toggling play state) is getting called an unexpected number of times.