Search code examples
iosavplayeravplayerlayer

AVPlayer with AVPlayerLayer 'ready to play' status no work for the real videoView display


I have a AVPlayer with remote video source. using observeValueForKeyPath:ofObject:change:context: to detect the readyToPlay status is on and set the AVPlayerLayer to myVideoContainerView's layer for display.

the problem is: after the readyToPlay status is trigger. it delay for 1-2 seconds for the video showed on screen for real.

I have tried to set AVPlayerLayer before and after the readyToPlay state is on. but non of them works.

the problem only occurs when I use AVPlayer+AVPlayerLayer. using AVPlayerViewController is fine. but I still need to solve this condition in my project.

thanks for any suggestion!

     @property (weak, nonatomic) IBOutlet UIView *myVideoContainter;
     @property AVPlayer *player;
     @property AVPlayerLayer *layer;

-(void)viewDidLoad{
     self.player = [AVPlayer playerWithUR:videoURL];
     [self.player addObserver:self forKeyPath:@"status" options:0 context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                    change:(NSDictionary *)change context:(void *)context {
if (object == self.player && [keyPath isEqualToString:@"status"]) {
    if (self.player.status == AVPlayerStatusReadyToPlay) {
        NSLog(@"Ready To Play");
        self.layer = [AVPlayerLayer playerLayerWithPlayer:self.player];
        self.layer.frame = self.mainContentView.bounds;
        [self.mainContentView.layer addSublayer:self.layer];
        }
    }
}

Solution

  • problem sovled.

    don't know why but player.currentItem.status is more accurate then player.status.

    [self.player.currentItem addObserver:self forKeyPath:@"status" options:0 context:nil];
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                    change:(NSDictionary *)change context:(void *)context {
        if(self.player.currentItem.status == AVPlayerItemStatusReadyToPlay){
            //do something        
        }
    }
    

    note. some action will change AVPlayerItem.status. should handling looping issue this way.