AVPlayer 帧动画

AVPlayer frame animation

提问人:rkyr 提问时间:8/20/2015 最后编辑:Communityrkyr 更新时间:7/26/2023 访问量:2334

问:

我正在开发一个应用程序,其中包括播放带有每帧动画的视频的功能。 您可以看到此类功能的示例

我已经尝试添加到子层并遇到一些麻烦CAKeyFrameAnimationAVSynchronizedLayer

我也已经尝试过用 预渲染视频,它运行良好。但它非常缓慢。渲染此类视频最多需要 3 分钟。AVAssetExportSession

也许还有其他方法可以做到这一点?

更新:

这就是我实现动画的方式:AVSynchronizedLayer

let fullScreenAnimationLayer = CALayer()
fullScreenAnimationLayer.frame = videoRect
fullScreenAnimationLayer.geometryFlipped = true

values: [NSValue] = [], times: [NSNumber] = []

// fill values array with positions of face center for each frame
values.append(NSValue(CATransform3D: t))

// fill times with corresoinding time for each frame
times.append(NSNumber(double: (Double(j) / fps) / videoDuration)) // where fps = 25 (according to video file fps)

...

let transform = CAKeyframeAnimation(keyPath: "transform")
transform.duration = videoDuration
transform.calculationMode = kCAAnimationDiscrete
transform.beginTime = AVCoreAnimationBeginTimeAtZero
transform.values = values
transform.keyTimes = times
transform.removedOnCompletion = false
transform.fillMode = kCAFillModeForwards
fullScreenAnimationLayer.addAnimation(transform, forKey: "a_transform")

...

if let syncLayer = AVSynchronizedLayer(playerItem: player.currentItem) {
    syncLayer.frame = CGRect(origin: CGPointZero, size: videoView.bounds.size)
    syncLayer.addSublayer(fullScreenAnimationLayer)
    videoView.layer.addSublayer(syncLayer)
}
iOS Swift 视频 AVFafoundation

评论

1赞 TheLivingForce 9/16/2015
在黑暗中拍摄:您是否尝试过将计算模式更改为线性计算?也许线性插值可以抵消帧速率的差异。
0赞 rkyr 9/16/2015
@TheLivingForce,是的,我已经尝试了所有类型的预定义模式(以防万一)。我尝试了不同类型的预定义计算函数,并实现了很少的自定义。上面的代码产生最佳结果。
1赞 HHK 6/8/2017
你有没有试过在你的?customVideoCompositorAVPlayerItem
0赞 Pranav Kasetti 1/6/2021
更改为 .values: [NSValue]values: [Any]
0赞 Pranav Kasetti 1/6/2021
此外,将 的设置为较高的值。zIndexsyncLayer

答:

-1赞 Bomi Chen 6/16/2022 #1

这是我的意见,

将 AVPlayer 图层属性(AVPlayerLayer 类)添加到子图层到 UIView 图层,然后操作视图动画。

例如

AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:blahURL options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:urlAsset];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = yourFrame;

UIView *videoView = [UIView new];
[videoView addSublayer:playerLayer];

然后

为 videoView 提供动画