Я записываю вывод воспроизводимого видео с помощью AVPlayerItemVideoOutput.copyPixelBuffer
Я могу преобразовать буфер пикселей в CIImage, затем снова отобразить его обратно в буфер пикселей, а затем AVAssetWriter успешно записывает поток буфера в новый фрагмент ролика.
Причина, по которой я конвертирую в CIImage, заключается в том, что я хочу поработать над каждым кадром. (Пока я не понимаю, как напрямую управлять пиксельными буферами).
В этом случае я хочу наложить рисунок в стиле каракулей, который пользователь делает пальцем. Во время воспроизведения видео они могут рисовать поверх него. Я успешно записываю этот рисунок в CAShapeLayer.
Приведенный ниже код успешно выводит только наложение CAShapeLayer. Когда я пытаюсь повторно включить исходный кадр, раскомментировав показанные строки, весь процесс резко замедляется и падает с 60 кадров в секунду до нестабильных 10 кадров в секунду или около того на iPhone 12. Я получаю стабильные 60 кадров в секунду во всех случаях, кроме тех случаев, когда я раскомментирую этот код.
Как лучше всего включить слой-фигуру в этот поток буферов пикселей со скоростью 60 кадров в секунду в реальном времени?
Примечание: часть этого кода не доработана - правильная установка границ и т. Д. Однако это не связано с моим вопросом, и я знаю, что это необходимо сделать. Вращение / перемещение используются для ориентации слоя формы - на данный момент все это работает.
func addShapesToBuffer(buffer: CVPixelBuffer, shapeLayer: CAShapeLayer) -> CVPixelBuffer? {
let coreImage = CoreImage.CIImage.init(cvImageBuffer: buffer)
let newBuffer = getBuffer(from: coreImage)
CVPixelBufferLockBaseAddress(newBuffer!, [])
let rect = CGRect(origin: CGPoint.zero, size: CGSize(width: 800, height: 390))
shapeLayer.shouldRasterize = true
shapeLayer.rasterizationScale = UIScreen.main.scale
shapeLayer.backgroundColor = UIColor.clear.cgColor
let renderer = UIGraphicsImageRenderer(size: rect.size)
let uiImageDrawing = renderer.image {
context in
// let videoImage = UIImage(ciImage: coreImage)
// videoImage.draw(in: rect)
let cgContext = context.cgContext
cgContext.rotate(by: deg2rad(-90))
cgContext.translateBy(x: -390, y: 0)
return shapeLayer.render(in: cgContext)
}
let ciContext = CIContext()
let newImage = CIImage(cgImage: uiImageDrawing.cgImage!)
ciContext.render(_: newImage, to: newBuffer!)
CVPixelBufferUnlockBaseAddress(newBuffer!, [])
return newBuffer
}