如何在 CVImageBuffer 中实时叠加每个捕获帧的视图,而不是 post 过程

How to superimpose views over each captured frame inside CVImageBuffer, realtime not post process

我已经成功设置了一个基本的 AVCaptureSession,它可以使用 AVCaptureFileOutputRecordingDelegate 录制视频并将其保存在设备上。我一直在搜索文档以了解我们如何在正在录制的视频之上添加统计叠加层。

如上图所示。我在视频预览层之上有多个叠加层。现在,当我保存我的视频输出时,我也想将这些视图合成到视频中。

到目前为止我尝试了什么?

我在寻找什么?

  1. 方向。
  2. 没有直接的解决方案
  3. 文档 link 和 class 名称我应该阅读更多关于创建它的内容。

到目前为止的进度:

我已经明白我需要从 CMSampleBuffer 获取 CVImageBuffer 并在其上绘制文本。我仍然不清楚是否有可能以某种方式将 MapView 覆盖在正在录制的视频上。

帮助您实现目标的最佳方式是使用 Metal 框架。使用 Metal 摄像头有助于最大限度地减少对设备有限计算资源的影响。如果您正在尝试实现对相机传感器的最低开销访问,使用 AVCaptureSession 将是一个非常好的开始。

您需要从 CMSampleBuffer 中获取每一帧数据(您是对的),然后将一帧转换为 MTLTextureAVCaptureSession 将通过委托回调从设备的相机不断向我们发送帧。

所有可用的叠加层也必须转换为 MTLTextures。然后你可以用over操作合成所有MTLTextures层。

因此,在这里您可以找到 四部分 Metal Camera 系列.[=23= 中的所有必要信息]

这里是 link 到 博客About Compositing in Metal

此外,我想发布代码摘录(在 Metal 中使用 AVCaptureSession):

import Metal

guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
    // Handle an error here.
}

// Texture cache for converting frame images to textures
var textureCache: CVMetalTextureCache?

// `MTLDevice` for initializing texture cache
var metalDevice = MTLCreateSystemDefaultDevice()

guard
    let metalDevice = metalDevice
    where CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, metalDevice, nil, &textureCache) == kCVReturnSuccess
else {
    // Handle an error (failed to create texture cache)
}

let width = CVPixelBufferGetWidth(imageBuffer)
let height = CVPixelBufferGetHeight(imageBuffer)

var imageTexture: CVMetalTexture?
let result = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache.takeUnretainedValue(), imageBuffer, nil, pixelFormat, width, height, planeIndex, &imageTexture)

// `MTLTexture` is in the `texture` variable now.
guard
    let unwrappedImageTexture = imageTexture,
    let texture = CVMetalTextureGetTexture(unwrappedImageTexture),
    result == kCVReturnSuccess
else {
    throw MetalCameraSessionError.failedToCreateTextureFromImage
}

And here you can find a final project on a GitHub: MetalRenderCamera