【发布时间】:2019-10-24 10:12:36
【问题描述】:
在我的 iOS 应用程序的 UI 中,我显示了 CALayers 的复杂层次结构。其中一个层是AVPlayerLayer,它显示一个实时应用CIFilters 的视频(使用AVVideoComposition(asset:, applyingCIFiltersWithHandler:))。
现在我想将此图层合成导出到视频文件。 AVFoundation 中有两个工具似乎很有帮助:
A:AVVideoCompositionCoreAnimationTool 允许在(可能是动画的)CALayer 层次结构中渲染视频
B:AVVideoComposition(asset:, applyingCIFiltersWithHandler:),我也在 UI 中使用,将 CIFilters 应用于视频资产。
但是,这两个工具不能同时使用:如果我启动一个结合这些工具的AVAssetExportSession,AVFoundation 会抛出一个NSInvalidArgumentException:
期望视频合成仅包含
AVCoreImageFilterVideoCompositionInstruction
我尝试按如下方式解决此限制:
解决方法 1
1) 使用AVAssetReader 和AVAssetWriter 设置导出
2) 从资产读取器获取样本缓冲区并应用CIFilter,将结果保存在CGImage。
3) 将CGImage设置为图层层次结构中视频图层的content。现在图层层次结构“看起来像”最终视频的一帧。
4) 使用 CVPixelBufferGetBaseAddress 从资产编写器获取每个帧的 CVPixelBuffer 的数据,并使用该数据创建一个 CGContext。
5) 使用 CALayer.render(in ctx: CGContext) 将我的图层渲染到该上下文。
此设置有效,但速度极慢 - 导出 5 秒视频有时需要一分钟。看起来CoreGraphics 调用是这里的瓶颈(我猜这是因为使用这种方法,合成发生在 CPU 上?)
解决方法 2
另一种方法是分两步执行此操作:首先,将源视频与应用到文件中的过滤器一起保存,如 B,然后使用该视频文件嵌入视频在 A 中的图层组合中。但是,由于它使用两次传递,我想这可能没有那么有效。
总结
将此视频导出到文件的好方法是什么,最好是一次性完成?如何同时使用CIFilters 和AVVideoCompositionCoreAnimationTool?有没有一种本地方法可以在 AVFoundation 中设置结合这些工具的“管道”?
【问题讨论】:
标签: ios avfoundation cifilter avasset core-video