我有一个可以从SHOUTcast服务器播放流音频的应用。当应用程序位于前台并且禁用自动锁定时,一切正常。该应用程序也可以在后台播放音频,此功能在iOS 6和iOS 7上一直运行良好。但现在我的用户报告说,在升级到iOS 8后大约10分钟后,背景音频停止。/ p>
我能够通过在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 :(得分: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方法中,尝试以下操作之一:
目前这是我知道如何处理它的唯一方式。问题是为什么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分钟内崩溃。