在使用AVQueuePlayer时如何在视频之间添加转场效果?

13

我正在开发一个视频应用程序,它可以播放一系列视频。这些视频存储在一个 AVPlayerItem 数组中。AVQueuePlayer 使用这些 AVPlayerItem 进行初始化,并自动从该数组中播放视频。

问题在于当它切换到播放下一个视频时,会卡顿片刻或者在转换时出现抖动。我想通过某种动画来改善这个转换,例如淡入淡出,使视频变化更加平滑。

我的 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]];

我尝试在过渡时创建一个新图层,并通过降低旧图层的不透明度和提高新图层的不透明度来动画显示旧图层(以创建所需的淡入淡出效果),但它没有按预期工作。

自定义过渡的代码:

-(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;
}

如何在 AVQueuePlayer 中为视频应用过渡效果?


如果你找到了解决方案,请在这里发布,这将有助于其他人。 - Anand Suthar
如果有帮助的话,Apple 提供了使用队列播放器进行无缝过渡的示例代码:https://developer.apple.com/library/content/samplecode/avloopplayer/Introduction/Intro.html - iwasrobbed
3个回答

5

我们可以为 AVMutableVideoCompositionLayerInstruction 设置不透明度,该指令将在导出视频时添加,或作为 AVPlayer 的 VideoComposition 属性,这将创建淡入淡出效果。

 [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))];

这是实现特效的代码。
更完整的示例:

3
你有更完整的例子吗?我似乎无法理解这个。 - Justin Time
你能提供更多细节展示你是如何实现所需效果的吗?完整的代码示例将不胜感激。 - Jordan H
示例:https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos - iwasrobbed

2

我之前看过这个示例代码。它只是更改视频,而且在此过程中黑色部分会出现几秒钟。我想要的是在从一个视频转换到另一个视频时添加一些效果。非常感谢您的关注和帮助!!! - Parvez Belim
我确定我们和你一样遇到了同样的问题——我们需要播放两个视频,一个接一个。使用标准的AvPlayer控制,我们会出现短暂的暂停和/或黑屏闪烁。使用上面文章中介绍的技术帮助我们解决了这个问题——现在两个视频像一个视频一样播放。我将尝试从我们的团队中获取更多关于具体操作的信息。 - avs099

2
我通过使用两个单独的AVPlayer对象连续播放来实现所需的效果。播放器使用不同的视图进行播放。
其思想是在第一个视频即将完成之前淡入第二个视频播放器的视图。
演示项目可以在这里找到:IHLoopingVideoPlayerView 它重复播放同一段视频,但是相同的思想可以应用于任意数量的视频。

@iwasrobbed,提醒一下,该链接需要登录。那些不在该Slack频道中的人无法访问它。 - RonLugge
@RonLugge 很抱歉,这是苹果提供的示例代码:https://developer.apple.com/library/content/samplecode/avloopplayer/Introduction/Intro.html - iwasrobbed
这是一个很好的解决方案!我为了适应我的目的不得不进行了一些重构,但总的来说你为我节省了很多时间。谢谢! - horseshoe7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接