iOS 8在10分钟后停止在后台播放音频

时间:2014-10-04 18:14:37

标签: ios cocoa-touch audio ios8 avfoundation

我有一个可以从SHOUTcast服务器播放流音频的应用。当应用程序位于前台并且禁用自动锁定时,一切正常。该应用程序也可以在后台播放音频,此功能在iOS 6和iOS 7上一直运行良好。但现在我的用户报告说,在升级到iOS 8后大约10分钟后,背景音频停止。

我能够通过在iOS 8上运行应用程序来自己重现问题。由于应用程序本身非常复杂,我已经做了一个简单的演示来显示问题。我使用Xcode 6和Base SDK设置为iOS 8.我已将音频添加到我的Info.plist中的 UIBackgroundModes 。有人知道下面的代码有什么问题吗?

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSURL *streamingURL = [NSURL URLWithString:@"http://www.radiofmgold.be/stream.php?ext=pls"];

    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:streamingURL];
    [self setPlayerItem:playerItem];

    AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
    [player setAllowsExternalPlayback:NO];

    [self setPlayer:player];
    [player play];

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

    return YES;
}

4 个答案:

答案 0 :(得分:6)

我在iOS 8.0.2下遇到了同样的问题。我的远程音频源以mp3播放。 似乎内部错误导致AVAudioSession重新启动。您可以通过不同方式处理:

您可以观察AVPlayerItem的状态。

void* YourAudioControllerItemStatusContext = "YourAudioControllerItemStatusContext";
...
@implementation YourAudioController
...
- (void)playStream {
    ...
    AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:streamUrl];
    [item addObserver:self forKeyPath:@"status" options:0 context:MJAudioControllerItemStatusContext];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (context == YourAudioControllerItemStatusContext) {
        AVPlayerItem *item = object;
        if (item.status == AVPlayerItemStatusFailed) {
            [self recoverFromError];
        }
    }

这种方式似乎不可靠,因为在AVPlayerItem的状态发生变化之前可能存在巨大的时间延迟 - 如果它发生了变化。

我通过 observeValueForKeyPath 进行了调试,发现AVPlayerItem的状态变为 AVErrorMediaServicesWereReset ,并且设置了错误代码 -11819 。 / p>

由于我遇到了AVErrorMediaServicesWereReset错误,我研究了导致此错误的原因 - 这是AVAudioSession疯了。参考Apple的Technical Q&A,您应该注册AVAudioSessionMediaServicesWereResetNotifications。把它放在代码中的某个地方:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionWasReset:) name:AVAudioSessionMediaServicesWereResetNotification object:nil];

然后添加此方法:

- (void)audioSessionWasReset:(NSNotification *)notification {
    [self recoverFromError];
}

在recoverFromError方法中,尝试以下操作之一:

  • 显示一个警报,描述iOS 8下的问题并且需要重新启动流
  • 通过再次设置AVAudioSession并重新启动流并使用新的AVPlayerItem实例化新的AVPlayer实例

目前这是我知道如何处理它的唯一方式。问题是为什么AudioSession重新启动。

<强>更新 iOS 8.1接缝的发布已经解决了这个问题。

答案 1 :(得分:5)

我也遇到了同样的问题,并且在运行iOS 8.0.2的iPhone 5s和运行 iOS 8.1 beta 2 的iPad Mini Retina上进行了测试,这意味着即将推出测试大约30分钟后,两人都停止播放音频。

当AVPlayer.status == AVPlayerItemStatusFailed时,您可以注销AVPlayer.status以获取有关错误的更多详细信息。我收到:

Error Domain=AVFoundationErrorDomain Code=-11819 "Cannot Complete Action" UserInfo=0x178a75bc0 {NSLocalizedDescription=Cannot Complete Action, NSLocalizedRecoverySuggestion=Try again later.}

即使在尝试捕获并停止并启动我的播放器时,我也会收到致命错误,告诉我AVPlayer已被解除分配。此时,可能值得尝试按照Hendrik的建议重新初始化新的AVPlayer实例。这仍然无法解决当您尝试重新初始化时音频将临时切断的事实。您的AVPlayer也可能会在重新初始化之前收到通知,这意味着您将收到致命错误;这远非永久性解决方案。

也许其他人会有更多运气,可以提供更具体的解决方案。与此同时,我也向Apple报告了这个错误。

2014年10月15日更新:Apple以此状态关闭了我的错误报告:重复18152675(已关闭)。

答案 2 :(得分:4)

看起来它已在iOS 8.1中修复

答案 3 :(得分:0)

iOS8.1更新似乎修复了此问题。我昨天更新了它,能够流过45分钟,而在更新之前,它会在10-15分钟内崩溃。