I am developing an application that include functionality to play video with per-frame animation. You can see an example of such functionality.
I already tried to add CAKeyFrameAnimation
to sublayer of AVSynchronizedLayer
and have some troubles with it.
I also already tried to pre-render video with AVAssetExportSession
, and it is working perfectly. But it's very slow. It needa up to 3 minutes to render such video.
Maybe there are other approaches to make it?
Update:
This is how I implement animation with 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)
}
customVideoCompositor
on yourAVPlayerItem
?