如何判断AVPlayer何时完全加载了视频

Pet*_*ter 5 nsurl ios avplayer avasset

我需要知道何时AVPlayer完全加载了视频资产,因此没有视频延迟/冻结.当我开始播放视频时,它播放一半然后冻结.如果我退出并再次打开,它将播放视频的其余部分,并将平滑地重复播放视频.首先我加载资产:

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
                        }
                      });
       }];
Run Code Online (Sandbox Code Playgroud)

我在项目上设置了三个关键观察者,并为玩家设置项目

 [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];
Run Code Online (Sandbox Code Playgroud)

接下来,我检查播放器/项目是否准备好播放,以及playBackLikelyToKeepUp是否为真.

- (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;
}
Run Code Online (Sandbox Code Playgroud)

最后我打电话,preroll并在完成后开始播放.

-(void)prerollVideoPlayer{
   [self.player prerollAtRate:1.0 completionHandler:^(BOOL finished){
    if (finished) {
        [self.spinner stopAnimating];
        [self.player play];
    }
   }];
}
Run Code Online (Sandbox Code Playgroud)

但是我仍然会遇到视频延迟和AVPlayer冻结的一半.我试图找出播放器何时完全装满,或者至少足以让视频在没有中途停顿的情况下开始播放.谢谢您的帮助.