I'm trying to implement a View which can show the preview video of the rear camera and process the captured frames. I would like to use two outputs: one to save the video and one to process each frame.
let movieOutput = AVCaptureMovieFileOutput()
let videoDataOutput = AVCaptureVideoDataOutput()
I have added the delegates to my view controller:
class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate, AVCaptureVideoDataOutputSampleBufferDelegate
Also I have added my outputs to the AVCaptureSession:
do {
videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable as! String: NSNumber(value: kCVPixelFormatType_32BGRA)]
videoDataOutput.alwaysDiscardsLateVideoFrames = true
let queue = DispatchQueue(label: "videosamplequeue")
videoDataOutput.setSampleBufferDelegate(self, queue: queue)
guard captureSession.canAddOutput(videoDataOutput) else {
fatalError()
}
if captureSession.canAddOutput(videoDataOutput){
captureSession.addOutput(videoDataOutput)
}
videoConnection = videoDataOutput.connection(withMediaType:AVMediaTypeVideo)
}
if captureSession.canAddOutput(movieOutput) {
captureSession.addOutput(movieOutput)
}
My preview layer works perfectly and I can see the picture display in my UI view. But captureOutput is never called. If I comment:
//if captureSession.canAddOutput(movieOutput) {
// captureSession.addOutput(movieOutput)
// }
then, my captureOutput is called and works fine, but I would like to save my video in a file. I'm working with swift 3, so I'm using:
func captureOutput(_ output: AVCaptureOutput, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
Currently, when you remove the other source, it's still calling
captureOutputmaybe with fake data, but still for videoDataOutput, because you setsampleBufferDelegatefor it. ButcaptureOutputisn't meant formovieOutput.movieOutputisAVCaptureMovieFileOutput, which is a subclass ofAVCaptureFileOutput.AVCaptureFileOutputimplements two protocols: AVCaptureFileOutputDelegate and AVCaptureFileOutputRecordingDelegateYou should implement one of them (read the documentation to decide which one fits your requirement), and implement their methods, and expect them to be invoked, rather than
captureOutputto be called twice.