Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add transition between videos when using AVQueuePlayer?

I am working on a video application that plays a number of videos one after another. The videos are stored in an array of AVPlayerItems. 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?

like image 952
Parvez Belim Avatar asked Nov 07 '13 06:11

Parvez Belim


Video Answer


1 Answers

I was able to achieve the desired effect by using two separate AVPlayer objects playing back to back. The players are using different views to play on.

The idea is to fade in the second video player's view before the first video is going to finish.

The demo project can be found here: IHLoopingVideoPlayerView

It loops the same video over and over but the same idea can be applied to any number of videos.

like image 189
Ishan Handa Avatar answered Nov 01 '22 19:11

Ishan Handa