I need to know when AVPlayer
has completely finished loading a video asset so there is no video lag/freeze. When I begin to play the video, it plays half way through and then freezes. If I exit and open again, it plays the rest of the video and will repeat the video smoothly. First I load the asset:
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
NSString *tracksKey = @"tracks";
[asset loadValuesAsynchronouslyForKeys:@[tracksKey] completionHandler:
^{
// Completion handler block.
dispatch_async(dispatch_get_main_queue(),
^{
NSError *error;
AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error];
if (status == AVKeyValueStatusLoaded) {
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
// Set Key-Observers
}
});
}];
I set three key-observers on the item and set the player with the item
[item addObserver:self forKeyPath:@"status"
options:NSKeyValueObservingOptionNew context:&ItemStatusContext];
[item addObserver:self forKeyPath:@"playbackLikelyToKeepUp"
options:NSKeyValueObservingOptionNew context:&playbackLikelyToKeepUp];
[item addObserver:self forKeyPath:@"playbackBufferFull"
options:NSKeyValueObservingOptionNew context:&playbackBufferFull];
self.player = [AVPlayer playerWithPlayerItem:item];
Next, I check to see if the player/item are ready to play and also if playBackLikelyToKeepUp is true.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ((context == &ItemStatusContext) || (context == &playbackLikelyToKeepUp)) {
dispatch_async(dispatch_get_main_queue(),
^{
if ((self.player.currentItem != nil) &&
([self.player.currentItem status] == AVPlayerItemStatusReadyToPlay) && (self.player.currentItem.playbackLikelyToKeepUp == YES) && (self.player.status == AVPlayerStatusReadyToPlay)) {
NSLog(@"CALLED TO PLAY");
[self prerollVideoPlayer];
}
else {
[self.spinner startAnimating];
}
});
return;
}
else if (context == &playbackBufferFull){
if ((self.player.currentItem.playbackBufferFull) && (self.player.status == AVPlayerStatusReadyToPlay)) {
NSLog(@"Full Play");
[self prerollVideoPlayer];
}
return;
}
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
return;
}
Finally I call preroll
and begin playing when finished.
-(void)prerollVideoPlayer{
[self.player prerollAtRate:1.0 completionHandler:^(BOOL finished){
if (finished) {
[self.spinner stopAnimating];
[self.player play];
}
}];
}
But I still get video lag and the AVPlayer
freezes half way through. Im trying to find out when the player has fully loaded, or at least enough so the video can begin without a pause halfway through. Thanks for the help.