Как наложить представления на каждый захваченный кадр внутри CVImageBuffer, в реальном времени, а не после обработки
Мне удалось настроить основной AVCaptureSession
который записывает видео и сохраняет его на устройстве с помощью AVCaptureFileOutputRecordingDelegate
, Я искал документы, чтобы понять, как мы можем добавить наложения статистики поверх записываемого видео.
т.е.
Как вы можете видеть на изображении выше. У меня есть несколько оверлеев поверх слоя предварительного просмотра видео. Теперь, когда я сохраняю свой выходной видеосигнал, я хотел бы также объединить эти представления в видео.
Что я пробовал до сих пор?
- Честно говоря, я просто прыгаю в Интернете, чтобы найти авторитетный блог, объясняющий, как это можно сделать. Но найти не удалось.
- Я прочитал несколько мест, где можно создать текстовые слои, как описано в следующем посте, создав
CALayer
и добавив его в качестве подслоя. - Но что делать, если я хочу сделать
MapView
поверх записываемого видео. Также я не ищу снимок экрана. Часть содержимого на экране не будет частью окончательной записи, поэтому я хочу иметь возможность выбрать вид, который будет составлен.
Что я ищу?
- Направление.
- Нет прямого решения
- Ссылка на документацию и имена классов, о которых я должен прочитать, чтобы создать это.
Прогресс на данный момент:
Мне удалось понять, что мне нужно завладеть CVImageBuffer
от CMSampleBuffer
и нарисуйте текст поверх него. Мне все еще неясно, возможно ли как-то наложить MapView поверх записываемого видео.
1 ответ
Лучший способ помочь вам достичь своей цели - это использовать Metal
фреймворк. Используя Metal
Камера хороша для минимизации влияния на ограниченные вычислительные ресурсы устройства. Если вы пытаетесь добиться минимального доступа к датчику камеры, используйте AVCaptureSession
было бы действительно хорошим началом.
Вам нужно получить данные каждого кадра из CMSampleBuffer
(вы правы), а затем преобразовать кадр в MTLTexture
, AVCaptureSession
будет непрерывно отправлять нам кадры с камеры устройства через функцию обратного вызова делегата.
Все доступные наложения должны быть преобразованы в MTLTextures
тоже. Тогда вы можете составить все MTLTextures
слои с over
операция.
Итак, здесь вы найдете всю необходимую информацию в серии из четырех частей Metal Camera.
А вот ссылка на блог: О композитинге в металле.
Кроме того, я хотел бы опубликовать выдержку из кода (работа с AVCaptureSession in Metal):
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
}
И здесь вы можете найти окончательный проект на GitHub: MetalRenderCamera