Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Audio playing while app in background iOS

I have an app mostly based around Core Bluetooth. When something specific happens, the app is woken up using Core Bluetooth background modes and it fires off an alarm, however I can't get the alarm working when the app is not in the foreground.

I have an Alarm Singleton class which initialises AVAudioPlayer like this:

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                    pathForResource:soundName
                             ofType:@"caf"]];

self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[self.player prepareToPlay];
self.player.numberOfLoops = -1;
[self.player setVolume:1.0];

NSLog(@"%@", self.player);

This is the method that is called when my alarm code is called:

-(void)startAlert
{
    NSLog(@"%s", __FUNCTION__);

    playing = YES;
    [self.player play];
    NSLog(@"%i", self.player.playing);

    if (vibrate) {
        [self vibratePattern];
    }
}

Now when the app is in the foreground, self.player.playing returns 1 however when the app is in the background self.player.playing returns 0. Why would this be? All the code is being called, so the app is awake and functioning. The vibrate works perfectly which uses AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Any idea why this sound won't play?

Thanks

like image 748
Darren Avatar asked Apr 25 '14 14:04

Darren


2 Answers

Apple has a nice Technical Q&A article about this in its documentation (see also Playing and Recording Background Audio).

I think one big thing missing is that you haven't activated the Audio Background Mode in the Xcode settings: enter image description here

Maybe also adding [self.player prepareToPlay] in your alert method is helpful.

like image 134
Michael Dorner Avatar answered Oct 21 '22 12:10

Michael Dorner


I was also facing the same problem, but i was only facing it only during initial time when i was trying to play a sound while app was in background, once the app comes in foreground and i play the sound once than it works in background also.

So as soon as app is launched/ login is successful in my case, i was running this code:

[self startRingcall];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self stopRingcall];
    });
- (void)startRingcall
{
    if( self.audioPlayer )
        [self.audioPlayer stop];
    NSURL* musicFile = [NSURL fileURLWithPath:[[[UILayer sharedInstance] getResourceBundle] pathForResource:@"meetcalling" ofType:@"caf"]];
    NSError *error;
    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:&error];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    [[AVAudioSession sharedInstance] setActive: YES error: nil];
    if (error != nil) {
        NSLog(@"meetringer sound error -> %@",error.localizedDescription);
    }
    self.audioPlayer.volume = 0;
    [self.audioPlayer play];
    self.audioPlayer.numberOfLoops = 1;
}

- (void)stopRingcall
{
    if( self.audioPlayer )
        [self.audioPlayer stop];
    self.audioPlayer = nil;
}
like image 40
Gitesh Agarwal Avatar answered Oct 21 '22 12:10

Gitesh Agarwal