Adding a AVPlayerLayer as a sublayer of the current view does not work on an iPhone 5

1.4k views Asked by At

I have a login screen that I wanted a video background for. It plays while the user taps the signup or login buttons. Standard thing you see in apps nowdays.

Here is what I am doing:

- (void)addPlayerLayer {

    NSString *moviePath = [[NSBundle mainBundle] pathForResource:@"login_signup_pink-girl" ofType:@"mp4"];
    NSURL *movieURL = [NSURL fileURLWithPath:moviePath];

    AVPlayer *player = [[AVPlayer alloc] initWithURL:movieURL];
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    playerLayer.frame = CGRectMake(0,0,self.view.frame.size.width+self.screenShift, self.view.frame.size.height);
    playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    self.playerView = [[UIView alloc] initWithFrame:self.view.bounds];
    self.playerViewFrame = self.playerView.frame;
    [self.playerView.layer addSublayer:playerLayer];
    self.playerView.alpha = 0;
    [self.view insertSubview:self.playerView atIndex:0];
    [playerLayer.player play];

    [UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.playerView.alpha = 1.0;
    } completion:nil];

    [UIView animateWithDuration:0.6 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

        self.loginButton.alpha = 1.0;
        self.createAccountButton.alpha = 1.0;
        self.skipStepButton.alpha = 1.0;
        self.mainSTbackgroundImageView.alpha = 0.0;

    } completion:nil];

}

It works great in the iOS Simulator on iPhone 5, but when testing it on a real device, the video never loads, I just get a black background. It also works correctly on my iPhone 6 (physical, not simulator).

This is a curious problem, which leads me to ask:

  • Why would the video not load on iPhone 5?
  • Should I be pre-loading the video somehow? (5.7MB .mp4)
  • Is there a way to know when the video has been loaded and is ready to be displayed? Sometimes on the iPhone 5 simulator there is a bit of delay, which reveals the black background.
2

There are 2 answers

0
TheM00s3 On BEST ANSWER

Just because you have added a player layer its ready to play. You want to add an observer to the player itself, and observe its status for when it changes to ReadyToPlay. What could be happening is that on the simulator your on wi-fi whilst on the phone your using your connection which can be slower than being on a wi-fi or even a landline.

0
Nic Hubbard On

I took @TheM00s3 advice and did the following:

- (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) {

            // Fade in top logo
            [UIView animateWithDuration:0.4 delay:0.2 options:UIViewAnimationOptionCurveEaseInOut animations:^{

                self.mainSTLogoTop.alpha = 1.0;

            } completion:nil];

            // Fade in video and out logo and text
            [UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

                self.mainSTLogo.alpha = 0.0;
                self.animatedSequence.alpha = 0.0;

            } completion:^(BOOL finished) {

                // Add the video player
                [self.player play];

            }];

            [self.player removeObserver:self forKeyPath:@"status"];

        } else if (self.player.status == AVPlayerStatusFailed) {
            // something went wrong. player.error should contain some information
            NSLog(@"Error: %@", self.player.error);
            [self.player removeObserver:self forKeyPath:@"status"];
        }
    }
}