Ios 通过AVExportSession导出带有隐式动画的CALayer

Ios 通过AVExportSession导出带有隐式动画的CALayer,ios,animation,calayer,avmutablecomposition,Ios,Animation,Calayer,Avmutablecomposition,我正在尝试通过AVExportSession为我的自定义CALayer导出带有自定义属性的动画,请查找以下设置: class CustomAnimatable: CALayer { @NSManaged var brightness: CGFloat override init(layer: Any) { super.init(layer: layer); if let l = layer as? CustomAnimatable {

我正在尝试通过AVExportSession为我的自定义CALayer导出带有自定义属性的动画,请查找以下设置:

class CustomAnimatable: CALayer
{
    @NSManaged var brightness: CGFloat

    override init(layer: Any) {
        super.init(layer: layer);

        if let l = layer as? CustomAnimatable {
            self.brightness = l.brightness;
        }
    }

    override func action(forKey event: String) -> CAAction?
    {
        if event == "brightness" {
            let animation = CABasicAnimation(keyPath: event);
            animation.fromValue = presentation()?.brightness ?? self.brightness;
            return animation;
        }

        return super.action(forKey: event);
    }

    override class func needsDisplay(forKey key: String) -> Bool
    {
        if key == "brightness" {
            return true;
        }

        return super.needsDisplay(forKey: key);
    }

    override func display()
    {
        print("\(self) \(presentation()?.brightness) \(self.brightness)")
    }
}
以下是导出会话预设置:

func render()
{
     ......

    let parentLayer = CALayer();
    let videoLayer = CALayer();
    let animationLayer = CustomAnimatable()

    parentLayer.frame = frame;
    videoLayer.frame = frame;
    animationLayer.frame = frame;

    parentLayer.addSublayer(videoLayer);
    parentLayer.addSublayer(animationLayer);

    CATransaction.begin()
    CATransaction.setAnimationDuration(2.2);
    CATransaction.setDisableActions(true);
    CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear))

    let anim = CABasicAnimation(keyPath: "brightness");

    anim.fromValue = 1.0;
    anim.fillMode = kCAFillModeBoth;
    anim.beginTime = AVCoreAnimationBeginTimeAtZero;
    anim.repeatCount = 1;
    anim.toValue = 0.0;
    anim.isRemovedOnCompletion = false;

    animationLayer.add(anim, forKey: "anim")

    CATransaction.commit()


    let videoComposition = AVMutableVideoComposition();

    videoComposition.renderSize = CGSize(width: width, height: height);
    videoComposition.instructions = [mainInstruction];
    videoComposition.frameDuration = CMTimeMake(1, 30);
    videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer);

     ....
}
问题是生成的视频中的
亮度值在没有动画的情况下从1变为0。如果我尝试为
CALayer
的本机属性设置动画,例如
不透明度
-导出的动画视频完全正常,不透明度从1平滑衰减到0

我对海关财产做得不对吗

我考虑过的事情:

  • 将显式动画包装到
    CATransaction
    中以禁用隐式动作
  • 根据“”会话将动画开始时间设置为
    avcoreanimationbegintimezero
    isRemovedOnCompletion
    设置为false(核心动画获取部分)
原生CALayer属性的动画效果很好,因此导出会话设置似乎是正确的,这让我有点困惑


除此之外,如果我将自定义层添加到视图中,并设置
亮度
属性的动画,则动画效果也很好。因此,这个问题似乎特定于使用AVExportSession渲染自定义属性动画。

我不完全清楚为什么您在
父层?
中同时添加了class
videoLayer
animationLayer

parentLayer.addSublayer(videoLayer);
parentLayer.addSublayer(animationLayer);
使用以下代码希望对您有所帮助

parentLayer.addSublayer(videoLayer);
videoLayer.addSublayer(animationLayer);

我以与苹果示例相同的方式构建了图层组合(其他教程建议采用相同的方法)。无论如何,请参见此处更改动画层的父级不会更改结果-本机CALayer
不透明度
渲染良好,自定义属性不会设置动画。