Adding AVPlayerLayer as a sub-layer of the current view doesn't work on iPhone 5
I have a login screen that I need a background video for. It plays when the user enters the registration or login buttons. The standard thing you see in apps nowadays.
That's what I'm 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 fine in iOS Simulator on iPhone 5, but when tested 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 that makes me ask:
- Why won't videos load on iPhone 5?
- Should I preload videos? (5.7MB.mp4)
- Is there a way to find out when the video has been loaded and is ready to be displayed? Sometimes there is a slight delay on the iPhone 5 simulator which shows a black background.
source to share
Simply because you added a player layer that he is ready to play. You want to add an observer to the player itself and watch its status when it goes to ReadyToPlay. What can happen is that on the simulator, your Wi-Fi on the phone will use your connection, which can be slower than Wi-Fi or even landline.
source to share
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"];
}
}
}
source to share