ios - 如何从两个视频和一个包含框架中的 imageView 创建一个新视频?
问题描述
我有一个父视图,其中包含两个带有 AVPlayerLayers 的视图和一个 UIImageView。我想将所有这些组合成一个新视频,该视频将捕获父视图的所有内容。
我查看了 ReplayKit,但没有捕获 AVPlayer 的内容;它不允许我访问视频;它捕获整个屏幕而不是特定的视图或框架。
我的一般方法是逐帧遍历视频,捕获帧的图像,将它们设置在我覆盖在 playerLayer 上的 imageView 中,然后使用UIGraphicsGetImageFromCurrentImageContext
-- 捕获父视图的图像,然后制作视频在所有这些图像中。
我尝试了一些 AVFoundation 选项,但总体而言它们的性能并不是那么好。以下是我尝试过的一些选项,总是尝试上述模式。
只需使用
videoPlayer.seek(to: frame)
-- 设置视频帧,但这种方法非常慢:每 15 秒视频大约需要 42 秒才能以这种方式遍历每一帧。与 异步获取所有视频帧
AVAssetImageGenerator.generateCGImagesAsynchronously
,然后遍历上述模式中的那些。这是非常占用内存的,因为我对两个视频的每一帧都有一个图像。我可以分块工作以避免内存崩溃,但总体而言,这种方法仍然相当慢,而且这种批处理复杂性并不比第一种方法好多少。同时使用 获取每个帧
AVAssetImageGenerator.copyCGImage(at: frame, actualTime: nil)
,但这并不比第一个选项快。使用 an
AVAssetReader
并使用 -- 遍历每一帧copyNextSampleBuffer
,对上述任何选项都没有真正的改进。
我可能会做一些事情来优化处理,但我认为它们不能解决上面提到的基本问题。例如,我可能会降低视频质量,或者修剪它,因为某些视频在其帧中不可见,或者降低帧速率,但如果可能的话,我宁愿避免这些。
在这一点上,我想我可能不得不使用 Metal。有什么建议么?
解决方案
这会很困难,因为您要做的是添加一个钩子,通过从视图中实时捕获原始图像缓冲区的流,来抓取已经渲染的 GPU 的合成结果。这在 CPU/GPU 或内存使用方面几乎没有效率。如果您能以某种方式访问 GPU 的本机 API 以更直接的方式获取合成的原始缓冲区,您可能会成功,但这很尴尬。
更自然的做法是——在获得所需材料(视频、图像等)后立即进行正确的视频合成,然后将处理后的结果显示给用户并根据需要进行操作(转储)数据作为文件等)。
总之,尝试谷歌“ios 视频合成”。AFAIK,AVFoundation 提供相关功能。您可能还想研究一些这样的库,以减少自己编写所有低级代码的麻烦。
推荐阅读
- javascript - 切换类重叠
- azure - 查询以从 Cosmos DB 获取详细信息
- python - 是否可以从 OPEN Libreoffice Calc 文件中读取数据?
- javascript - 如何组合 2 个 css 文件以避免两者之间的冲突?
- java - 如何在intellij中创建jar文件
- reactjs - 我的警报功能应该清除以前的搜索结果,然后显示新的
- java - 将文件写入器类中的路径复制到文件类中
- python - 有什么区别吗?
- google-apps-script - Google Sheets 脚本 - 代码优化 - 一个脚本,两个工作表,同一个工作簿
- vue.js - v-show 在我挂载 Vue 之前不会隐藏元素