How to handle AVPlayerItem observer when app goes foreground from background?

Viewed 350

I play audio using AVPlayer in the background and foreground from AppDelegate.After adding observer to check the play, a crash occurs when app goes to foreground from background while audio is playing

Crash : "an instance of class AVPlayerItem was deallocated while key value observers were still registered with it"

Many threads explains to remove observer so that we could avoid the crash.But thats in the case of moving to different viewControllers.I want to keep the audio playing in foreground and background.

Can someone help me to solve this?

This is my code:

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;

}
0 Answers
Related