使用 AVCapturePhotoOutput 设置自定义相机。配置 AVCapturePhotoOutput 以在主 JPEG 缓冲区之外提供预览缓冲区(缩略图)。
问题是我只接收一次预览缓冲区(第一次捕获),然后从第二次开始接收 nil(始终正确接收主 photoSampleBuffer)。
这是我设置捕获的方式:
func capturePhoto() {
guard let videoPreviewLayerOrientation = deviceOrientation.videoOrientation else { return }
sessionQueue.async {
if let photoOutputConnection = self.photoOutput.connection(withMediaType: AVMediaTypeVideo) {
photoOutputConnection.videoOrientation = videoPreviewLayerOrientation
}
// each photo captured requires a brand new setting object and capture delegate
let photoSettings = AVCapturePhotoSettings()
// Capture a JPEG photo with flash set to auto and high resolution photo enabled.
photoSettings.isHighResolutionPhotoEnabled = true
//configure to receive a preview image (thumbnail)
if let previewPixelType = photoSettings.availablePreviewPhotoPixelFormatTypes.first {
let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String : previewPixelType,
kCVPixelBufferWidthKey as String : NSNumber(value: 160),
kCVPixelBufferHeightKey as String : NSNumber(value: 160)]
photoSettings.previewPhotoFormat = previewFormat
}
// TODO: photoSettings.flashMode = .auto
// Use a separate object for the photo capture delegate to isolate each capture life cycle.
let photoCaptureDelegate = PhotoCaptureDelegate(with: photoSettings, willCapturePhotoAnimation: { [unowned self] in
// show shutter animation
self.shutterAnimation()
}, completed: { [unowned self] (photoCaptureDelegate, photoData, previewThumbnail) in
self.captureCompleted(photoCaptureDelegate: photoCaptureDelegate, data: photoData, thumbnail: previewThumbnail)
}
)
// The Photo Output keeps a weak reference to the photo capture delegate so we store it in an array
// to maintain a strong reference to this object until the capture is completed.
self.inProgressPhotoCaptureDelegates[photoCaptureDelegate.requestedPhotoSettings.uniqueID] = photoCaptureDelegate
self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)
}
}
在我的 PhotoCaptureDelegate(实现 AVCapturePhotoCaptureDelegate)中:
func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
if let photoBuffer = photoSampleBuffer {
photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoBuffer, previewPhotoSampleBuffer: nil)
}
if let previewBuffer = previewPhotoSampleBuffer {
if let pixelBuffer = CMSampleBufferGetImageBuffer(previewBuffer) {
photoThumbnail = CIImage(cvPixelBuffer: pixelBuffer)
}
}
}
发生的情况是,我第一次拍摄时同时收到 photoSampleBuffer 和 previewPhotoSampleBuffer。第二次以后我只收到photoSampleBuffer
,previewPhotoSampleBuffer = nil
虽然当我检查时resolvedSettings.previewDimensions
我得到:
CMVideoDimensions(width: 160, height: 120)
如果我通过重新配置捕获会话来切换相机(从前到后),那么之后的第一次捕获就可以了,然后再次没有预览缓冲区。委托回调中的error
参数始终为零。
在运行 iOS 10.3.1 的 iPhone 6 上测试