Nic Hubbard
Nic Hubbard

Reputation: 42139

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

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:

Upvotes: 3

Views: 1478

Answers (2)

Nic Hubbard
Nic Hubbard

Reputation: 42139

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"];
        }
    }
}

Upvotes: 0

TheM00s3
TheM00s3

Reputation: 3711

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.

Upvotes: 1

Related Questions