iOS背景audio没有播放

我有一个使用CoreBluetooth背景模式的应用程序。 当某个事件发生时,我需要发出警报声。 在前台一切工作正常,所有的蓝牙function在后台工作正常。 我也有它工作的地方在后台安排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)文件中添加一个名为必需背景模式的键。

如下图

在这里输入图像说明 你可以得到帮助吗

并在其中添加以下代码

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设置,你必须修改应用程序委托。

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

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

除了设置背景模式的过程之外,您还必须正确设置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] 

那就是你必须让你的应用的audio会话高于其他。

默认情况下, 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]; 

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

 @property (strong, nonatomic) AVAudioPlayer *player; 

我希望这有帮助,

干杯,吉姆