AV Foundation: Difference between current readiness for playback and the [AVPlayer readyForDisplay] property?

I came across a strange situation with my video player, the main code of which has not changed much from what worked in the earlier application that I made. Here's the problem: I insert "_loadingLayer" (a CATextLayer that says the video is loading) and then watching the status property of the current AVPlayer ID to find out when to remove the "_loadingLayer" and replace it with my actual "_playerLayer", here is my KVO code for of this:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

if ((object == _playerLayer) && (_playerLayer.player.currentItem.status == AVPlayerItemStatusReadyToPlay)) {

    [CATransaction setAnimationDuration:1.8];

    _loadingLayer.opaque = NO;

    if (_playerLayer.readyForDisplay) {

        NSLog(@"Should be ready now.");

    }

    [self addPlayerLayerToLayerTree];

}

}

, , - . NSLog , , : , currentItem "AVPlayerItemStatusReadyToPlay", . - . -, , ?

, _playerLayer , .

, , , .... :

PSsetwindowlevel, (1000) CGSSetIgnoresCycle: 1000

. Apple Dev.

+5
1

, ​​iOS 5.1 (, , ). iOS 6.0. , , .

AVPlayerItem AVPlayerStatusReadyToPlay , AVPlayerLayer , AVPlayer , readyForDisplay.

, :

self.player = [AVPlayer playerWithPlayerItem:self.playerItem];

, :

self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 

, - .

, 100% 100% . , , , , , PlayerItem AVPlayerStatusReadyToPlay.

, . (.. , ) iOS 5.1. loadPlayerLayer, loadPlayer, .

: , . - , , playerLayer AVStatusReadyToPlay. : , , , / HLS. AVStatusReadyToPlay , , PlayerLayer , AVStatusReadyToPlay.

, HLS Apple:

-(void)loadPlayer
{
  NSLog(@"loadPlayer invoked");

  NSURL *url = [NSURL URLWithString:@"https://devimages.apple.com.edgekey.net/resources/http-streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8"];
  self.playerItem = [AVPlayerItem playerItemWithURL:url];
  [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:&kPlayerContext];
  self.player = [AVPlayer playerWithPlayerItem:self.playerItem];

}

-(void)loadPlayerLayer
{
  NSLog(@"starting player layer");
  self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 
  [self.playerLayer addObserver:self forKeyPath:@"readyForDisplay" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:&kPlayerLayerContext];
  [self.playerLayer setFrame:[[self view] bounds]];
  [[[self view] layer] addSublayer:self.playerLayer];
}

-(void)observeValueForKeyPath:(NSString*)path ofObject:(id)object change:(NSDictionary*)change context:(void*) context
{
  if(context == &kPlayerContext){
    if([self.player status] == AVPlayerStatusReadyToPlay){
      NSLog(@"Player is ready to play");
      //Robert: Never works if after AVPlayerItem reports AVPlayerStatusReadyToPlay
      if(!self.startedPlayerLayer){
        self.startedPlayerLayer = YES;
        [self loadPlayerLayer];
      }
    }
  }

  if(context == &kPlayerLayerContext){
    if([self.playerLayer isReadyForDisplay] == YES){
      NSLog(@"PlayerLayer says it ready to display now");
      [self playTheVideoIfReady];
    }
  }
}
+3

All Articles