ios - 通过 AVExportSession 导出带有隐式动画的 CALayer
<p><p>我正在尝试通过 AVExportSession 为我的自定义 CALayer 导出一个带有自定义属性的动画,请在下面找到设置:</p>
<pre><code>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)")
}
}
</code></pre>
<p>这是导出 session 的预设置:</p>
<pre><code>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 = ;
videoComposition.frameDuration = CMTimeMake(1, 30);
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer);
....
}
</code></pre>
<p>问题是生成的视频中的 <code>brightness</code> 值在没有动画的情况下从 1 变为 0。如果我尝试为 <code>CALayer</code> 的原生属性设置动画,例如<code>opacity</code> - 导出的动画视频完全没问题,不透明度从1平滑渐变到0。</p>
<p>我对自定义属性做错了吗?</p>
<p>我考虑过的事情:</p>
<ul>
<li>将显式动画包装到 <code>CATransaction</code> 以禁用隐式操作</li>
<li>根据“<a href="http://docs.huihoo.com/apple/wwdc/2010/session_407__editing_media_with_av_foundation.pdf" rel="noreferrer noopener nofollow">Editing Media with AV Foundation</a>” session 将动画开始时间设置为 <code>AVCoreAnimationBeginTimeAtZero</code> 并将 <code>isRemovedOnCompletion</code> 设置为 false(Core Animation Gotchas 部分)</li>
</ul>
<p>我对原生 CALayer 属性的动画效果有点困惑,因此导出 session 设置似乎是正确的。 </p>
<p>除此之外,如果我将自定义图层添加到 View 并为 <code>brightness</code> 属性设置动画 - 它的动画效果也很好。所以这个问题似乎特定于使用 AVExportSession 渲染自定义属性动画。</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>我不完全确定您为什么在 <code>parentLayer?</code> 中同时添加了类 <code>videoLayer</code> 和 <code>animationLayer</code>。</p>
<pre><code>parentLayer.addSublayer(videoLayer);
parentLayer.addSublayer(animationLayer);
</code></pre>
<p>使用以下代码希望对你有所帮助!</p>
<pre><code>parentLayer.addSublayer(videoLayer);
videoLayer.addSublayer(animationLayer);
</code></pre></p>
<p style="font-size: 20px;">关于ios - 通过 AVExportSession 导出带有隐式动画的 CALayer,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/47181365/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/47181365/
</a>
</p>
页:
[1]