我在背景中使用AVPlayer播放音频,在AppDelegate播放前景。在添加观察者检查播放后,当应用从播放音频时播放到前台时发生崩溃
崩溃:“一个AVPlayerItem类的实例被释放,而键值观察者仍然注册了它”
许多线程解释了删除观察者,以便我们可以避免崩溃。但是在移动到不同的viewControllers的情况下。我希望保持音频在前台和后台播放。
有人可以帮我解决这个问题吗?
这是我的代码:
case AudioLocation:{
audioUrl = [NSURL URLWithString:[responseDictionary
objectForKey:@"result"]];
if(!([[[NSUserDefaults
standardUserDefaults]objectForKey:@"audioURL"] isEqual:
[responseDictionary objectForKey:@"result"]]))
{
playerItem = [AVPlayerItem playerItemWithURL:audioUrl];
player = [AVPlayer playerWithPlayerItem:playerItem];
player = [AVPlayer playerWithURL:audioUrl];
player.automaticallyWaitsToMinimizeStalling = false;
[player.currentItem addObserver:self forKeyPath:@"status"
options:0 context:nil];
[player addObserver:self forKeyPath:@"rate" options:0
context:nil];
[player play];
isPlaying = YES;
}
-(void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context {
if ([keyPath isEqualToString:@"status"]) {
if (player.status == AVPlayerStatusFailed) {
}
}else if ([keyPath isEqualToString:@"rate"]) {
if (player.rate == 0 && //if player rate dropped to 0
CMTIME_COMPARE_INLINE(player.currentItem.currentTime, >,
kCMTimeZero) &&
CMTIME_COMPARE_INLINE(player.currentItem.currentTime, <,
player.currentItem.duration) &&isPlaying)
[self handleStalled];
}
}
-(void)handleStalled {
NSLog(@"Handle stalled. Available: %lf", [self availableDuration]);
if (player.currentItem.playbackLikelyToKeepUp || //
[self availableDuration] -
CMTimeGetSeconds(player.currentItem.currentTime) > 10.0) {
[player play];
} else {
[self performSelector:@selector(handleStalled) withObject:nil
afterDelay:0.5]; //try again
}
}
- (NSTimeInterval) availableDuration
{
NSArray *loadedTimeRanges = [[player currentItem] loadedTimeRanges];
CMTimeRange timeRange = [[loadedTimeRanges objectAtIndex:0]
CMTimeRangeValue];
Float64 startSeconds = CMTimeGetSeconds(timeRange.start);
Float64 durationSeconds = CMTimeGetSeconds(timeRange.duration);
NSTimeInterval result = startSeconds + durationSeconds;
return result;
}