IOS: Play sound while app in background

lskov picture lskov · Apr 26, 2013 · Viewed 10.3k times · Source

I working on a little app where i want the phone to play a sound file on an event from my location controller. The problem is when the App is in Background mode the AVAudioPlayer not start the Audio file but the code is scheduled, getting NSLog output. Another thing is it works in the simulator but not on the phone.

Whys not?

This is my code to play the file:

- (void)tryPlayTaleSound:(NSString*)fileName {

    NSString *backgroundMusicPath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"];
    NSURL *backgroundMusicURL = [NSURL fileURLWithPath:backgroundMusicPath];
    NSError *error;

    backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];

    // Check to see if iPod music is already playing
    //UInt32 propertySize = sizeof(otherMusicIsPlaying);
    //AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &otherMusicIsPlaying);

    // Play the music if no other music is playing and we aren't playing already
    //if (otherMusicIsPlaying != 1 && !backgroundMusicPlaying) {
    //[backgroundMusicPlayer prepareToPlay];
    [backgroundMusicPlayer play];
    backgroundMusicPlaying = YES;
    //}
    NSLog(@"%s - ", __FUNCTION__);
}

In the log Im getting this.

Apr 26 13:57:48 iPhone CommCenter[58] <Notice>: Client [com.apple.persistentconnection[dataaccessd,85]] is telling PDP context 0 to go active.
Apr 26 13:57:50 iPhone Herning100[1467] <Warning>: Playing audiofile - filename is Fil03
Apr 26 13:57:50 iPhone mediaserverd[39] <Warning>: 13:57:50.653 <AudioControl> WARNING translating CMSession error: -12985 
Apr 26 13:57:50 iPhone mediaserverd[39] <Warning>: 13:57:50.656 <AudioControl> WARNING translating CMSession error: -12985 
Apr 26 13:57:50 IPhone mediaserverd[39] <Error>: 13:57:50.734 <AudioControl> AudioQueue: Error -12985 from AudioSessionSetClientPlayState(1467)
Apr 26 13:57:50 iPhone Herning100[1467] <Warning>: -[AppDelegate tryPlayTaleSound:] - 
Apr 26 13:57:50 iPhone com.apple.debugserver-199[1465] <Warning>: 9 +28.832083 sec [05b9/0303]: error: ::mach_vm_region_recurse ( task = 0x1603, address => 0xfffffffe, size => 0, nesting_depth => 1024, info => 0x2fd7fe48, infoCnt => 12) addr = 0xfffffffe  err = (os/kern) invalid address (0x00000001)
Apr 26 13:57:51 iPhone com.apple.debugserver-199[1465] <Warning>: 10 +0.187961 sec [05b9/0303]: error: ::mach_vm_region_recurse ( task = 0x1603, address => 0xfffffffe, size => 0, nesting_depth => 1024, info => 0x2fd7fe48, infoCnt => 12) addr = 0xfffffffe  err = (os/kern) invalid address (0x00000001)

Is there a difference if I use the AVAudioPlayer or the AVAudioSession.?

Hope someone can help.

/Lasse

Answer

glebd picture glebd · Apr 18, 2014

In addition to having background mode audio in your Info.plist you need to set the shared audio session to the correct mode for your app and activate it just before playing your sound in the background:

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
NSLog(@"Activating audio session");
if (![audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error]) {
    NSLog(@"Unable to set audio session category: %@", error);
}
BOOL result = [audioSession setActive:YES error:&error];
if (!result) {
    NSLog(@"Error activating audio session: %@", error);
}
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

Don't forget to deactivate the audio session when you are done playing sounds:

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
NSLog(@"Deactivating audio session");
BOOL result = [audioSession setActive:NO error:&error];
if (!result) {
    NSLog(@"Error deactivating audio session: %@", error);
}