Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resume AVAudioPlayer after interrupted in background

I am playing music using AVAudioPlayer in background. The problem is: if there is a incoming calling interrupts the player, it will never resume unless switch to foreground and do it manually.

The code is simple, to play it in background:

[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord  error: nil];
[[AVAudioSession sharedInstance]  setActive: YES error: nil];

url = [[NSURL alloc] initFileURLWithPath:...];

audio_player = [[AVAudioPlayer alloc] initWithContentsOfURL: url error:NULL];
audio_player.delegate = self;
bool ret = [audio_player play];

delegate to handle interruptions:

-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
    //tried this, not working [[AVAudioSession sharedInstance]  setActive: NO error: nil]; 
    NSLog(@"-- interrupted --");
}


//----------- THIS PART NOT WORKING WHEN RUNNING IN BACKGROUND ----------
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player
{
    NSLog(@"resume!");
    //--- tried, not working: [[AVAudioSession sharedInstance] setCategory:             AVAudioSessionCategoryPlayAndRecord  error: nil];
    //--- tried, not working: [[AVAudioSession sharedInstance]  setActive: YES error: nil];
    //--- tried, not working: [audio_player prepareToPlay];
    [audio_player play];
}

Can any one help me?

like image 686
Paul Avatar asked Dec 30 '11 05:12

Paul


1 Answers

Found the solution! I had the same problem, my app was resuming the audio nicely after an interruption, only if my app was open. When it was on the background it failed ro resume playing the audio after an interruption.

I fixed this by adding the following lines of code:

Add this line whenever your app start playing audio.[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

And on the endInterruption method, wait 1 or 2 seconds before resume playing the audio. This to allow the OS to stop using the audio channel.

- (void)endInterruptionWithFlags:(NSUInteger)flags {
    // Validate if there are flags available.
    if (flags) {
        // Validate if the audio session is active and immediately ready to be used.
        if (AVAudioSessionInterruptionFlags_ShouldResume) {
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1), dispatch_get_main_queue(), ^{
                    // Resume playing the audio.
                });
        }
    }
}

You can also add this line when your app stops (not pause) playing audio. But is not required. [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

like image 157
Paul N Avatar answered Nov 14 '22 20:11

Paul N