2014-10-04 185 views
10

我有一个应用程序可以播放来自SHOUTcast服务器的流音频。当应用程序位于前台且禁用自动锁定时,一切正常。然而,该应用程序也能够在后台播放音频,该功能在iOS 6和iOS 7上一直运行良好。但现在,我的用户报告说,在升级到iOS 8后大约10分钟后,背景音频会停止。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; 
} 
+0

请分享修复,如果你找到一个。我的用户也在报告这个问题。我无法复制它。 – RawMean 2014-10-06 14:42:00

+0

由于所有流式链接均未出现问题,因此我也无法首先重现该问题。然而,我的代码中的流在10分钟后总是停止,而它在iOS 7上正常工作。 真的很烦人,因为这个流是我的应用程序的主要功能,我现在用一星级的评论和来自用户的抱怨不知所措。尽快设置这个问题的赏金,但恐怕这是苹果方面的一个错误。 我真的希望我可以自己修复它..虽然我的应用程序基本上依赖于此功能。 – s1m0n 2014-10-06 17:26:01

+0

嗨,大家好,我遇到了同样的问题。对我来说就像苹果公司搞砸了它。在我的情况下,直到河流停止播放的时间差异很大(5分钟到12分钟)。看起来流突然失去连接,然后播放,直到它用完缓冲数据。 App在前台以及在后台时会发生。处理它的唯一方法是观察AVPlayerItem的状态。我会将其作为答案发布。 – Hendrik 2014-10-07 08:03:19

回答

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集。

由于我经历了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重新启动。

UPDATE iOS 8.1接缝的发布解决了问题。

5

我也遇到了同样的问题,并测试了在iPhone 5S运行iOS 8.0.2和iPad的迷你视网膜运行的iOS 8.1 beta 2版本,这意味着这不是固定在即将到来的测试版。大约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日:苹果已经关闭了我的错误报告以及此状态:重复18152675(已关闭)。

4

看起来是固定的iOS 8.1

+0

是的,我在问题中运行了示例代码,并且流式传输持续了30分钟(之后我手动停止了它)。我想知道为什么这个iOS 8.0的bug不会影响潘多拉和Spotify。 – RawMean 2014-10-21 01:23:35

0

这个问题似乎已经固定iOS8.1更新。我昨天更新了它,并能够流45分钟,而在更新之前,它将在10-15分钟内崩溃。