AudioSessionSetActive Error After Interruption

I tried to figure out what was actually going on for several weeks, and I have no idea why I canโ€™t continue playing after the break, so maybe you guys know the answer. AudioSessionSetActive (TRUE) always returns โ€œ! Catโ€, which is kAudioSessionIncompatibleCategory when re-activated if my application is playing in the background and I enter another application. Although it works fine and continues to play if I caught an interrupt while in my application.

The source code actually has all the AudioSession and AudioQueue calls wrapped in macros that print OSStatus if that means an error, but I deleted it for better readability. In addition, [self pause] just toggles the pause, so basically it calls AudioQueueStart (audioQueue, NULL), but this does not work if AudioSession does not work.

Audio Initialization Code:

AudioSessionInitialize(NULL, NULL, _audioSessionInterruptionListener, self); UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback; AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory); AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, _audioSessionPropertyListener, self); AudioSessionSetActive(TRUE); 

Interrupt 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 somehow helps to solve the problem.

+8
objective-c iphone audioqueue
source share
6 answers

If you use the AudioQueue API, you need to take a few extra steps, which depend on a specific factor. I have never done this, so I will leave an explanation for the expert:
There is a video on this topic on the Apple Developer website that covers this exact issue. WWDC 2010 Session 412 Audio Development for iPhone OS part 1 around the 45th minute you have a pretty good explanation on this.

+3
source share

I had a problem, when the alarm clock appears during the launch of the application, the user simply presses the deviceโ€™s power button to sleep. Then, after resuming sleep, my AudioSessionSetActive fails with something like " this audiosession type can't be used ". I tried adding the set audiosession property to AudioSessionSetActive(true) in the Interruptlistener, but no luck. Finally i added

 retry(~1000 times :) 

ftw)

 AudioSessionSetActive(true), 

and he solved my problem.

+2
source share

Try activating AudioSession in else if as follows:

 AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *error = nil; [session setCategory: AVAudioSessionCategoryPlayback error: &error]; if (error != nil) NSLog(@"Failed to set category on AVAudioSession"); // AudioSession and AVAudioSession calls can be used interchangeably OSStatus result = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, RouteChangeListener, self); if (result) NSLog(@"Could not add property listener! %d\n", result); BOOL active = [session setActive: YES error: nil]; if (!active) NSLog(@"Failed to set category on AVAudioSession"); 

But I believe that this may not work, because in my case, what happened when I was in the background, he did not receive any session. But try to analyze the aurioTouch Apple example and just go through the AppDelegate file and try to AppDelegate the (void)rioInterruptionListener , which explains the same problem.

Do you use streaming audio? then I would recommend you read my question where the problem of the beginning of the queue is solved by handling the error, as indicated in my answer.

Hope this can be helpful for you.

0
source share

kAudioSessionEndInterruption may or may not hit your code, this is not a reliable way to control your playback states, just do not turn off the audio session in your code, it will resume the session as soon as it can gain control again, in your case, just comment out that AudioSessionSetActive ( FALSE) will help you.

0
source share

If you look at the Listing 7-16 An interruption listener callback function in the cookbook section on programming audio recordings , the sample code (which seems compatible with your situation using kAudioSessionCategory_MediaPlayback) does not actually execute

 AudioSessionSetActive(FALSE); 

in case of kAudioSessionBeginInterruption , and

 AudioSessionSetActive(TRUE); 

call in case of kAudioSessionEndInterruption . I really don't think you should do this. This post also seems to illustrate this issue (getting kAudioSessionIncompatibleCategory). What happens if you comment on both of these calls?

The reason the problem occurs when your application is in the background rather than in the foreground is a mystery. Perhaps you should keep track of the state (as you seem to be doing with NX_STATE_PLAY), and then have two different methods ([self pause] and [self play]), since maybe [self pause] (switched play state) gets call an unexpected number of times.

0
source share

I have some ways of working for me, you can try your own risk.

In function

 void _audioSessionInterruptionListener(void *inClientData, UInt32 inInterruptionState) 

remove

 [(NxAudioStreamer*)inClientData handleInterruptionChangeToState:inInterruptionState]; 

there is no need to call handleInterruptionChangeToState when you can directly handle it in audioSessionInterruptionListener , because audioSessionInterruptionListener has inInterruptionState as a parameter. So make changes to the audioSessionInterruptionListener

 void _audioSessionInterruptionListener(void *inClientData, UInt32 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");  } } 
0
source share

All Articles