Мое приложение включает получение видеокадров с камеры и запуск на нем CoreML. Это будет отображаться в представлении. Для этого у меня есть AVCaptureSession (), который подключен к видеовыходу. Основная обработка CoreML выполняется в captureOutput (didOutput Samplebuffer). Каждая обработка кадра занимает около 0,15 секунды, что означает, что у меня будут некоторые пропущенные кадры. После завершения процесса CoreML у меня есть AVAssetWriter, который добавляет все эти кадры вместе и сохраняет его в телефонном справочнике.
Основная проблема, однако, в том, что в моем сценарии использования также требуется сохранение исходного видео, и это видео должно иметь ВЫСОКИЙ FPS, и, поскольку я могу получать кадры изображения только в captureOutput (didOutput), видео качество будет нестабильным.
Я пробовал следующее:
Причина, по которой я использую AVAssetWriter, заключается в том, что здесь указано: https://forums.developer.apple.com/thread/98113#300885 то, что невозможно иметь AVCaptureVideoDataOutput и AVCaptureMovieFileOutput.
Я также попытался извлечь буфер изображения из captureOutput (didDrop), используя guard let pixelBuffer = CMSampleBufferGetImageBuffer (sampleBuffer) else {return}, но это дает мне ноль. Это потому, что sampleBuffer содержит только метаданные, но не буфер изображения, как описано здесь: https://developer.apple.com/documentation/avfoundation/avcapturevideodataoutputsamplebufferdelegate/1388468-captureoutput.
Вот мой код:
func captureOutput(_ output: AVCaptureOutput, didDrop sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { /* HOW DO I possibly extract an image buffer here from the dropped frames here? */ }
func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
let inputVideoImage = UIImage(pixelBuffer: pixelBuffer)
if self.isRecording{
let sourceTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
if let camera = self.videoWriterVideoInput, camera.isReadyForMoreMediaData {
videoWriterQueue.async() {
self.videoWriterInputPixelBufferAdaptor.append(pixelBuffer, withPresentationTime: sourceTime)
}
}else{
print("AVAssetInput is not ready for more media data ... ")
}
}
runCoreML()
}