Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS background audio not playing

I have an app that uses CoreBluetooth background modes. When a certain event happens I need to play an alarm sound. Everything works fine in the foreground and all bluetooth functionality works fine in the background. I also have it working where it schedules UILocalNotification's in the background to sound the alarm, however I don't like the lack of volume control with these so want to play the alarm sound using AVAudioPlayer.

I've added the background mode audio to my .plist file but can't get the sound to play properly.

I am using a singleton class for the alarm and initialise the sound like this:

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

player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
player.numberOfLoops = -1;
[player setVolume:1.0];

I start the sound like this:

-(void)startAlert
{
    playing = YES;
    [player play];
    if (vibrate)
        [self vibratePattern];
}

and use this for the vibration:

-(void)vibratePattern
{
    if (vibrate && playing) {
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
        [self performSelector:@selector(vibratePattern) withObject:nil afterDelay:0.75];
    }
}

The vibration works fine in the background, but no sound. If I use Systemsound to play the sound like this, it plays fine (But no volume control):

AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &_sound);
AudioServicesPlaySystemSound(_sound);

So what could be the reason why the AVAudioPlayer is not playing the sound file?

Thanks

EDIT -------

The sound will play if it's already playing when the app is backgrounded. However making it start to play whilst backgrounded is not working.

like image 846
Darren Avatar asked Mar 23 '14 13:03

Darren


1 Answers

add a key named Required background modes in property list (.plist) file ..

as following picture..

enter image description here may you get help..

and add following code in

AppDelegate.h

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

AppDelegate.m

in application didFinishLaunchingWithOptions

[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

UInt32 size = sizeof(CFStringRef);
CFStringRef route;
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &route);
NSLog(@"route = %@", route);

If you want changes as per events you have to add following code in AppDelegate.m

- (void)remoteControlReceivedWithEvent:(UIEvent *)theEvent {

    if (theEvent.type == UIEventTypeRemoteControl)  {
        switch(theEvent.subtype)        {
            case UIEventSubtypeRemoteControlPlay:
                [[NSNotificationCenter defaultCenter] postNotificationName:@"TogglePlayPause" object:nil];
                break;
            case UIEventSubtypeRemoteControlPause:
                [[NSNotificationCenter defaultCenter] postNotificationName:@"TogglePlayPause" object:nil];
                break;
            case UIEventSubtypeRemoteControlStop:
                break;
            case UIEventSubtypeRemoteControlTogglePlayPause:
                [[NSNotificationCenter defaultCenter] postNotificationName:@"TogglePlayPause" object:nil];
                break;
            default:
                return;
        }
    }
}

based on notification have to work on it..

code.tutsplus.com provides a tutorial.

for HandsetBluetooth you have to add following code in AppDelegate

UInt32 size = sizeof(CFStringRef);
    CFStringRef route;
    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &route);
    NSLog(@"route = %@", route);
    NSString *routeString=[NSString stringWithFormat:@"%@",route];
    if([routeString isEqualToString:@"HeadsetBT"]){
        UInt32 allowBluetoothInput = 1;
        AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (allowBluetoothInput),&allowBluetoothInput);
    }
like image 195
Ashish Kakkad Avatar answered Sep 19 '22 02:09

Ashish Kakkad