I am working on a video application that plays a number of videos one after another. The videos are stored in an array of AVPlayerItem
s. AVQueuePlayer
is initialized with those AVPlayerItems
and it automatically plays the videos from that array.
The issue is when it changes to play the next video it gets stuck for a fraction of a second or it creates a jerk at the time it transitions from one to another. I want to improve this transition with some kind of animation such as Fade In and Fade Out while the video is changed.
My code for AVQueuePlayer
:
AVQueuePlayer *mediaPlayer = [[AVQueuePlayer alloc] initWithItems:arrPlayerItems];
playerLayer=[AVPlayerLayer playerLayerWithPlayer:mediaPlayer];
playerLayer.frame=self.bounds;
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
playerLayer.needsDisplayOnBoundsChange = NO;
[self.layer addSublayer:playerLayer];
self.layer.needsDisplayOnBoundsChange = YES;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(itemPlayEnded:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[mediaPlayer currentItem]];
I tried to create a new layer at the time of the transition and animate the old layer by decreasing its opacity and increasing the opacity of the new layer (to create the desired fade in fade out effect), but it is not working as desired.
The code for the custom transition:
-(void)TransitionInVideos {
if (roundf(CMTimeGetSeconds(mediaPlayer.currentTime))==roundf(CMTimeGetSeconds(mediaPlayer.currentItem.duration))) {
[self.layer addSublayer:playerLayerTmp];
//Animation for the transition between videos
[self performSelector:@selector(FadeIn) withObject:nil afterDelay:0.3];
[self performSelector:@selector(FadeOut) withObject:nil afterDelay:0.3];
}
}
-(void)FadeIn {
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeAnim.fromValue = [NSNumber numberWithFloat:1.0];
fadeAnim.toValue = [NSNumber numberWithFloat:0.0];
fadeAnim.duration = 2.0;
[playerLayer addAnimation:fadeAnim forKey:@"opacity"];
[self performSelector:@selector(HideLayer) withObject:nil afterDelay:2.0];
}
-(void)FadeOut {
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeAnim.fromValue = [NSNumber numberWithFloat:0.0];
fadeAnim.toValue = [NSNumber numberWithFloat:1.0];
fadeAnim.duration = 1.0;
[playerLayerTmp addAnimation:fadeAnim forKey:@"opacity"];
[self performSelector:@selector(ShowLayer) withObject:nil afterDelay:1.0];
}
-(void)HideLayer {
playerLayer.opacity=0.0;
}
-(void)ShowLayer {
playerLayerTmp.opacity=1.0;
}
How can a transition be applied to videos in the AVQueuePlayer
?
We can set the opacity for AVMutableVideoCompositionLayerInstruction
that will be add to the video while exporting or AVPlayer
as VideoComposition property and that will create the fade in and fade out effect.
[layerInstruction setOpacityRampFromStartOpacity:1.0 toEndOpacity:0.0 timeRange:CMTimeRangeMake(CMTimeSubtract([mutableComposition duration], CMTimeMake(Transition_Time, 1)), [mutableComposition duration])];
[layerInstruction setOpacityRampFromStartOpacity:0.0 toEndOpacity:1.0 timeRange:CMTimeRangeMake(kCMTimeZero, CMTimeMake(1, 1))];
this are the code for giving the effect.
More complete examples: