在应用程序进入后台后启动时,无法让AVQueuePlayer
开始播放声音队列。
基本问题是:如何从背景中新创建的AVQueuePlayer
实例启动声音?
对于类似navi的应用程序,需要在时机成熟时播放具有适当方向的组合声音。大多数时候应用程序在后台工作......
详情如下......
当我从活动应用程序启动它时播放效果很好,即使应用程序转到后台也能播放声音。
到目前为止我做了什么:
在AppDelegate
内didFinishLaunchingWithOptions
我添加了:
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&sessionError];
// Change the default output audio route
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);
应用程序启动后,我点击了主页按钮,以便应用程序进入后台。
当时间到了,这个代码执行了(应用程序仍在后台,但请注意,我已启用音频和AirPlay后台模式):
-(void)playTrainingFinishedSound
{
NSMutableArray *queue = [NSMutableArray array];
[queue addObject:[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"alertkoniectreningu" withExtension:@"m4a"]]];
[self initializeAudioPlayerWithQueue:queue];
[self.appDelegate.audioPlayer play];
}
-(void)initializeAudioPlayerWithQueue:(NSArray *)queue
{
self.appDelegate.audioPlayer = [[AVQueuePlayer alloc] initWithItems:queue];
self.appDelegate.audioPlayer.actionAtItemEnd = AVPlayerActionAtItemEndAdvance;
}
不幸的是,此代码没有发出任何声音,与应用程序处于前台时的情况相反。
答案 0 :(得分:0)
天啊,AppDelegate中只丢失了一行didFinishLaunchingWithOptions
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
所以现在看起来像:
audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
if (audioSession) [audioSession setActive:YES error:nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
// Change the default output audio route
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);
答案 1 :(得分:0)
AVPlayer失败的原因是因为当应用程序在后台时您无法创建/初始化音频单元,这就是AVPlayer试图在幕后进行的操作。此规则的例外当然是音频播放应用程序,它们可以通过操作系统内置的“播放”按钮启动/恢复,而它们在后台。因此,订阅远程控制事件的应用程序能够在后台启动音频单元,这就是为什么订阅这些事件似乎可以解决问题。
目前尚不清楚Apple是否可以通过这种方式使用API功能。