我有一个要求,我的应用程序连接到国家/地区频道(美国)并开始播放来自频道的记录。这基本上是一个由用户运行的频道,用户将他们的记录上传到频道,然后逐个播放。连接到频道的用户,他们开始收听频道。
服务器向iOS应用程序发送需要通过套接字播放的记录的URL,iOS应用程序创建AVQueuePlayer
以逐个播放URL(使用AVPlayerItems
)。
如果我将应用程序保留在后台,当通道充满了大约1天左右的记录时,应用程序会继续运行并继续逐个播放所有记录。我知道AVQueuePlayer
负责运行应用程序,而不会因为接收到要玩的新玩家项目而被杀死。
但是如果频道中没有记录,并且如果用户连接到频道,那么如果应用的空闲时间超过10分钟,则app不会在后台播放记录。
我编写了带有后台任务标识符的代码,这使得我的套接字连接保持打开状态,以便始终可以接收新的记录URL。
我在设备中看到了"AppName(my app) has active assertions beyond permitted time"
我可以知道这里发生了什么错误。
我也在发布后台任务代码
- (void)keepBroadcastPersistentConnection {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if(self._bgTaskIdentifier)
self._bgTaskIdentifier = UIBackgroundTaskInvalid;
self._bgTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
[[UIApplication sharedApplication] endBackgroundTask:self._bgTaskIdentifier];
self._bgTaskIdentifier = UIBackgroundTaskInvalid;
CGLog(@"========================================end bg task at time %@", [NSDate date]);
CGLog(@"Time taken by app to run in bg is %f seconds", [[NSDate date] timeIntervalSinceDate:self.date]);
}];
[[BroadcastSocketConnecter sharedSocketConnecter].socketIO sendHeartbeat]; // this keep the socket alive
self.date = [NSDate date];
CGLog(@"========================================begin bg task at time %@", self.date);
});
}
由于
答案 0 :(得分:4)
来自音频会话节目指南:
<强> Why a Default Audio Session Usually Isn’t What You Want 强>
场景3.您编写了一个使用音频的流媒体广播应用 用于播放的队列服务。当用户正在收听时,打个电话 按预期到达并停止您的声音。用户选择忽略 通话和解除警报。用户再次点击播放以恢复 音乐流,但没有任何反应。要恢复播放,请用户 必须退出您的应用程序并重新启动它。
要正常处理音频队列的中断,请执行 委托方法或写一个音频会话回调函数来允许 你的应用程序继续自动播放或允许 用户手动恢复播放。请参阅“Responding to Audio Session Interruptions。”
很快,解决方案是实施AVAudioSessionDelegate协议'beginInterruption
和endInterruption
方法。但是,{6}中不推荐使用delegate
类的AvAudioSession
属性,而应使用Notifications。即,您对AVAudioSessionInterruptionNotification
解决方案。根据这个故事,如果播放停止,那么您应该再次明确激活音频会话,以防止您的应用被终止。
以下是委托实现的来源,但逻辑对通知没有太大变化,所以我觉得它仍然是一个很好的信息来源。
- (void) beginInterruption {
if (playing) {
playing = NO;
interruptedWhilePlaying = YES;
[self updateUserInterface];
}
}
NSError *activationError = nil;
- (void) endInterruption {
if (interruptedWhilePlaying) {
BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError];
if (!success) { /* handle the error in activationError */ }
[player play];
playing = YES;
interruptedWhilePlaying = NO;
[self updateUserInterface];
}
}
旧的回复仍然有效但不是优雅的解决方案
您无法在后台开始播放音频。这个答案解释了我在上面评论中提到的内容:https://stackoverflow.com/a/16568437/768935使用AudioSession
进行操作似乎对此政策没有影响。
作为解决方案,您需要继续播放音频。如果队列中没有项目,则插入“静音”音轨。但是,我怀疑使用此技巧的应用程序将在App Store中被接受。如果应用程序再次启动,最好通知用户音频播放将恢复。