Search code examples
swiftavkitcvpixelbuffer

Retrieving CVPixelBuffer from AVCapturePhotoDelegate methods


I would like to obtain a pixelBuffer from didFinishProcessingPhoto delegate method but it's nil.

func capturePhoto() {
        let format = [AVVideoCodecKey: AVVideoCodecType.jpeg]
        let settings = AVCapturePhotoSettings(format: format)
        output.capturePhoto(with: settings, delegate: self)
    }

and extension:

extension CaptureSessionManager: AVCapturePhotoCaptureDelegate {
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        guard let pixelBuffer = photo.pixelBuffer else {
            return
        }

        bufferSubject.onNext(pixelBuffer)
    }
}

Before that I'm obviously adding output to the session. Should I use some different method from this delegate?


Solution

  • I figured it out myself after reading the documentation.

    First make sure to use the AVCaptureSession.Preset.photo as a sessionPreset: session.sessionPreset = .photo.

    Then it's important to use rawPixeFormatType becuase setting it to jpeg or hevc won't produce the pixelBuffer. It can be achieved like this:

    guard let availableRawFormat = self.output.availableRawPhotoPixelFormatTypes.first else {
                return
            }
    
    let photoSettings = AVCapturePhotoSettings(rawPixelFormatType: availableRawFormat,
                                                       processedFormat: [AVVideoCodecKey : AVVideoCodecType.hevc])
    
    output.capturePhoto(with: photoSettings, delegate: self)
    

    processedFormat: in AVCapturePhotoSettings init is optional.