繁体   English   中英

iOS背景音频无法播放

[英]iOS background audio not playing

我有一个使用CoreBluetooth背景模式的应用程序。 当某个事件发生时,我需要发出警报声。 一切都在前台工作正常,所有蓝牙功能在后台工作正常。 我也有它在后台安排UILocalNotification的工作,以发出警报,但我不喜欢这些音量控制不足,所以想用AVAudioPlayer播放闹钟声音。

我已将背景模式audio添加到我的.plist文件中,但无法正常播放声音。

我正在使用单例类进行警报并初始化声音如下:

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

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

我开始这样的声音:

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

并用它来振动:

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

振动在背景中工作正常,但没有声音。 如果我使用Systemsound播放这样的声音,它可以正常播放(但没有音量控制):

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

那么AVAudioPlayer没有播放声音文件的原因是什么?

谢谢

编辑-------

当应用程序背景时,声音将播放。 然而,在背景下开始播放是行不通的。

在属性列表(.plist)文件中添加一个名为Required background modes的键。

如下图

在此输入图像描述 你可以得到帮助..

并添加以下代码

AppDelegate.h

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

AppDelegate.m

在应用程序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);

如果您希望根据事件进行更改,则必须在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;
        }
    }
}

基于通知必须工作..

code.tutsplus.com提供了一个教程

对于HandsetBluetooth,您必须在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);
    }

除了plist设置,您还必须修改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];
}

同样在您的controller编写以下代码。

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

也许你应该让你的应用程序的音频会话高于其他人。

除了设置后台模式的过程外,您还必须正确设置AudioSession。

有时这样做是不够的

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

因为在帮助文档中有关于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.

所以,setActive:withOptions:error:是必需的。 像这样

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

那就是你必须使你的应用程序的音频会话高于其他人。

默认情况下, AVAudioPlayer使用AVAudioSessionCategorySoloAmbient类别,该类别由振铃开关静音。 AVAudioSessionCategoryPlayback类别更适合您的情况,因为它不会被交换机静音,并将继续在后台播放:

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];

这(希望)可能就像保留音频一样简单。 如果你可以检查你在哪里设置了强大的玩家属性。

@property (strong, nonatomic) AVAudioPlayer *player;

我希望这有帮助,

干杯,吉姆

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM