iOS background audio not playing

前端 未结 5 2094
悲哀的现实
悲哀的现实 2020-11-27 05:51

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

相关标签:
5条回答
  • 2020-11-27 06:33

    Apart from plist settings you have to modify app delegate.

    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    }
    

    Also in your controller write the following code.

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    [[AVAudioSession sharedInstance] setActive: YES error: nil];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    
    0 讨论(0)
  • 2020-11-27 06:43

    This (hopefully) may be as simple as retaining the audio. If you could check where you have set the player property that it is strong.

    @property (strong, nonatomic) AVAudioPlayer *player;
    

    I hope this helps,

    Cheers, Jim

    0 讨论(0)
  • 2020-11-27 06:45

    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);
        }
    
    0 讨论(0)
  • 2020-11-27 06:48

    Maybe you should make your app's audio session higher than others.

    Besides the process to setting background mode, you must set AudioSession correctly.

    Sometimes just doing this is not enough

    [[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
    

    because in Help document there is a discussion about setActive

    Discussion
    If another active audio session has higher priority than yours (for example, a phone call), and neither audio session allows mixing, attempting to activate your audio session fails. Deactivating your session will fail if any associated audio objects (such as queues, converters, players, or recorders) are currently running.
    

    So, setActive:withOptions:error: is needed. Just like this

    [audioSession setCategory :AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error]  
    

    That is you must make your app's audio session higher than others.

    0 讨论(0)
  • 2020-11-27 06:50

    By default, AVAudioPlayer uses the AVAudioSessionCategorySoloAmbient category, which is silenced by the ringer switch. The AVAudioSessionCategoryPlayback category is more appropriate for your situation, since it is not silenced by the switch, and will continue to play in the background:

    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                        pathForResource:soundName
                                        ofType:@"caf"]];
    
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    [player setCategory:AVAudioSessionCategoryPlayback error:nil];
    player.numberOfLoops = -1;
    [player setVolume:1.0];
    
    0 讨论(0)
提交回复
热议问题