我的应用程序涉及从摄像机获取视频帧并在其上运行CoreML。然后,它将显示在视图上。为此,我有一个连接到视频输出的AVCaptureSession()。 CoreML的主要处理是在captureOutput(didOutput Samplebuffer)中完成的。帧的每次处理大约需要0.15秒,这意味着我将丢掉一些帧。完成CoreML处理后,我有一个AVAssetWriter将所有这些帧附加在一起,并将其保存在电话目录中。
但是,主要问题是,我的用例还需要保存原始视频,并且该视频应具有HIGH FPS,并且由于我只能在captureOutput(didOutput)中获取图像帧,因此该视频质量会不稳定。
我尝试了以下方法:
我使用AVAssetWriter的原因是因为这里给出了这样的提示:https://forums.developer.apple.com/thread/98113#300885不能同时拥有AVCaptureVideoDataOutput和AVCaptureMovieFileOutput。
我也尝试过使用guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)else {return}从captureOutput(didDrop)中提取图像缓冲区,但它给了我零。这是因为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()
}