AVAudioSessionDelegate called at endInterruption, but beginInterruption not called
Asked Answered
H

5

12

I'm setting up an AVAudioSession when the app launches and setting the delegate to the appDelegate. Everything seems to be working (playback, etc) except that beginInterruption on the delegate is not being called when the phone receives a call. When the call ends endInterruption is being called though.

The only thought I have is that the audio player code I'm using used to be based on AVAudioPlayer, but is now using AVPlayer. The callbacks for the AVAudioPlayer delegate for handling interrupts are still in there, but it seems odd that they would conflict in any way.

Hight answered 26/7, 2012 at 19:42 Comment(7)
I'm hitting the same situation, Andrew, were you able to solve it?Foolproof
Are you seeing the problem in iOS 5.x?Hight
I'm seeing the same thing in iOS 6 only. Just upgraded, but it doesn't work. Let me know if you solved it.Mares
As noted in my answer, this seems to be fixed in iOS 6.1. Not 6.0.1 however..Acus
I am still seeing issues with this in 6.1.2. When the interrupt actually begins, no notification is posted. When the interrupt actually ends, both the Began and Ended notifications are posted.Hight
Can anyone explain to me what the AVAudioSessionDidBeginInterruptionNotification notification mentioned in the docs is? I doesn't seem like I can actually register for it (undeclared identifier)Hight
Ok this is interesting, I seem to be seeing the correct behavior (in 6.1.2) when audio is actively playing when the interrupt occurs. The problem is when audio in my session is paused and an interrupt occurs, it's not posting the Began notification until the interrupt ends.Hight
M
9

Looking at the header, in iOS6, it looks like AVAudioSessionDelegate is now deprecated.

Use AVAudioSessionInterruptionNotification instead in iOS6.

Update: That didn't work. I think there's a bug in the framework.

Yes, in my experience, beginInterruption, nor the newly documented AVAudioSessionInterruptionNotification work properly. What I had to do was track the status of the player using a local flag, then handle the endInterruption:withFlags: method in order to track recovery from interruptions.

With iOS 6, the resuming from an interruption will at least keep your AudioPlayer in the right place, so there was no need for me to store the last known play time of my AVAudioPlayer, I simply had to hit play.

Here's the solution that I came up with. It seems like iOS 6 kills your audio with a Media Reset if an AVPlayer stays resident too long. What ends up happening, is the AVPlayer plays, but no sound comes out. The rate on the AVPlayer is 1, but there's absolutely no sound. To add pain to the situation, there's no error on either the AVAudioSession setActive, nor the AVPlayer itself that indicates that there's a problem.

Add to the fact that you can't depend on appWillResignActive, because your app may already be in the background if you're depending on remote control gestures at all.

The final solution I implemented was to add a periodic observer on the AVPlayer, and record the last known time. When I receive the event that I've been given back control, I create a new AVPlayer, load it with the AVPlayerItem, and seekToTime to the proper time.

It's quite an annoying workaround, but at least it works, and avoids the periodic crashes that were happening.

Mares answered 14/9, 2012 at 21:53 Comment(1)
Agreed. Neither AVAudioSessionInterruptionNotification nor AVAudioSessionRouteChangeNotification seems to work! I've filed a bug with Apple, and recommend others do the same in hopes of having this API fixed in 6.1. bugreport.apple.com/cgi-bin/WebObjects/RadarWeb.woa/wa/signInSibella
A
4

I can confirm that using the C api, the interruption method is also not called when the interruption begins; only when it ends

(AudioSessionInitialize (nil, nil, interruptionListenerCallback, (__bridge void *)(self));

I've also filed a bug report with apple for the issue.

Edit: This is fixed in iOS 6.1 (but not iOS 6.0.1)

Acus answered 4/10, 2012 at 21:49 Comment(4)
Not sure if there is a problem with your code setup, but I am seeing the audio session interruption callback getting called when the interruption begins on an iOS 6 device.Maye
Interesting - I have uploaded the example I sent to apple - Could you give it a go and see if the NSLog gets printed to notify the beginning of an interruption? It would be interesting to know if you are setting your audio sessions up differently?Acus
The project I mentioned above works correctly on ios 6.1 betaAcus
when using remote io to record directly to AAC using extAudioFile, I am seeing this behavior on both ios 6.0.1 and the 6.1 beta 4. It appears to not be fixed on the 6.x code at allEvanesce
N
2

Just call:

[[AVAudioSession sharedInstance] setDelegate: self];
Niemann answered 1/2, 2013 at 19:15 Comment(1)
That will trigger beginInterruption?Hight
M
0

I just checked on my iPhone 5 (running iOS 6.0) by setting a breakpoint in the AudioSessionInterruptionListener callback function that was declared in AudioSessionInitialize(), and this interrupt callback does, in fact, get called when the app has an active audio session and audio unit and is interrupted with an incoming phone call (Xcode shows the app stopped at the breakpoint at the beginning of the interruption, which I then continue from).

I have the app then stop its audio unit and de-activate its audio session. Then, on the end interruption callback, the app re-activates the audio session and restarts the audio unit without problems (the app is recording audio properly afterwards).

Maye answered 31/10, 2012 at 23:29 Comment(1)
The problem only seems to surface for me if we encode directly to mpeg4aac. Any other codec and things work fine. What were you using as the file format?Evanesce
O
0

I built a brand new audio streaming (AVPlayer) application atop iOS 6.0.x and found the same problem.

Delegates are now deprecated and we have to use notifications, that's great, however here's my findings:

  1. During an incoming phone call I get only AVAudioSessionInterruptionTypeEnded in my handler, along with AVAudioSessionInterruptionOptionShouldResume. Audio session gets suspended automatically (audio fades) and I just need to resume playback of AVPlayer.
  2. However when attempting to launch a game, such as CSR Racing, I oddly get the dreaded AVAudioSessionInterruptionTypeBegan but no sign when my application can resume playback, not even killing the game.

Now, this may depend on other factors, such as my audio category (in my case AVAudioSessionCategoryPlayback) and the mixing settings of both applications (kAudioSessionProperty_OverrideCategoryMixWithOthers), I'm not sure, but definitely I see something out of place.

Hopefully others reported that on 6.1beta this is fixed and I yet have to upgrade, so we'll see.

Obi answered 1/1, 2013 at 18:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.