3

我有一个要求,我的应用程序连接到国家频道(美国)并开始从该频道播放记录。这基本上是一个由用户运营的频道,用户将他们的记录上传到频道并逐一播放。连接到频道的用户开始收听频道。

服务器向 iOS 应用程序发送需要通过套接字播放的记录的 URL,iOS 应用程序创建以一一AVQueuePlayer播放 URL(使用)。AVPlayerItems

如果我在频道充满记录近 1 天左右时将应用程序保持在后台,该应用程序将继续运行并继续一一播放所有记录。我知道它AVQueuePlayer会一直运行应用程序而不会杀死它,因为它会收到新的播放器项目来玩。

但是如果频道中没有记录,并且如果用户连接到频道,那么如果应用程序的空闲时间超过 10 分钟,则应用程序不会在后台播放记录。

我编写了带有后台任务标识符的代码,它使我的套接字连接保持打开状态,以便可以一直接收新的记录 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);
});
}

谢谢

4

1 回答 1

4

从音频会话编程指南:

为什么默认音频会话通常不是您想要的

场景 3。您编写了一个流式广播应用程序,该应用程序使用音频队列服务进行播放。正如预期的那样,当用户正在收听时,一个电话到达并停止了您的声音。用户选择忽略呼叫并解除警报。用户再次点击播放以恢复音乐流,但没有任何反应。要恢复播放,用户必须退出您的应用程序并重新启动它。

要优雅地处理音频队列的中断,请实现委托方法或编写音频会话回调函数以允许您的应用程序继续自动播放或允许用户手动恢复播放。请参阅“<a href="https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Cookbook/Cookbook.html#//apple_ref/doc/uid/TP40007875-CH6-SW7”相关="nofollow noreferrer">响应音频会话中断。”</p>

很快,解决方案将是实现AVAudioSessionDelegate协议beginInterruptionendInterruption方法。但是,该类的delegate属性AvAudioSession在 iOS6 中已弃用,应改为使用通知。也就是说,您对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 使用 tricks 进行技巧AudioSession似乎对此政策没有影响。

作为解决方案,您需要继续播放音频。如果队列中没有项目,则插入“静音”音轨。但是,我怀疑具有此技巧的应用程序是否会在 App Store 中被接纳。如果再次启动应用程序,最好通知用户将恢复音频播放。

于 2013-09-18T13:40:05.150 回答