来自 AVCaptureVideoDataOutput 的 CMSampleBuffer 意外地发现 nil
CMSampleBuffer from AVCaptureVideoDataOutput unexpectedly found nil
我正在尝试将从 AVCaptureVideoDataOutput 委托(作为 CMSampleBuffer)获取的帧转换为 UIImage。但是我得到了 fatal error: unexpectedly found nil while unwrapping an Optional value
有人可以告诉我我的代码有什么问题吗?我假设我的 sampleBufferToUIImage 函数有问题。
将 CMSampleBuffer 转换为 UIImage 的函数:
func sampleBufferToUIImage(sampleBuffer: CMSampleBuffer) -> UIImage{
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer!)
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
let width = CVPixelBufferGetWidth(imageBuffer!)
let height = CVPixelBufferGetHeight(imageBuffer!)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue)
let context = CGContext(data: baseAddress, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
// *********Getting the error from this line***********
let quartzImage = context!.makeImage()
CVPixelBufferUnlockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let image = UIImage(cgImage: quartzImage!)
return image
}
委托我正在阅读框架的地方:
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
if count <= 0 {
// Calling my function to convert to UIImage.
let image = sampleBufferToUIImage(sampleBuffer: sampleBuffer)
let imageData = UIImagePNGRepresentation(image)
uploadImage(jpgData: imageData)
}
count = count + 1
}
正在设置 AVSession:
func setupCameraSession() {
captureSession.sessionPreset = AVCaptureSessionPresetHigh
// Declare AVCaptureDevice to default(back camera). The "as" changes removes the optional?
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) as AVCaptureDevice
do {
let deviceInput = try AVCaptureDeviceInput(device: captureDevice)
if (captureSession.canAddInput(deviceInput) == true) {
captureSession.addInput(deviceInput)
}
let dataOutput = AVCaptureVideoDataOutput()
dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange as UInt32)]
dataOutput.alwaysDiscardsLateVideoFrames = true
if (captureSession.canAddOutput(dataOutput) == true) {
captureSession.addOutput(dataOutput)
}
} catch {
}
AVCaptureVideoDataOutput 的视频设置不正确。将 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
更改为 kCVPixelFormatType_32BGRA
试试这个,对我有用 Swift 3
// Sample buffer handling delegate function
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
let myPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
myCIimage = CIImage(cvPixelBuffer: myPixelBuffer!)
videoImage = UIImage(ciImage: myCIimage)
uIimage.image = videoImage
}
// AV 会话
func startVideoDisplay() {
do {
let tryDeviceInput = try AVCaptureDeviceInput(device: cameraDevice)
cameraCaptureSession.addInput(tryDeviceInput)
} catch { print(error.localizedDescription) }
caViewLayer = AVCaptureVideoPreviewLayer(session: cameraCaptureSession)
view.layer.addSublayer(caViewLayer)
cameraCaptureSession.startRunning()
let myQueue = DispatchQueue(label: "se.paredes.FunAV", qos: .userInteractive, attributes: .concurrent)
let theOutput = AVCaptureVideoDataOutput()
theOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString): NSNumber(value:kCVPixelFormatType_32BGRA)]
theOutput.alwaysDiscardsLateVideoFrames = true
theOutput.setSampleBufferDelegate(self, queue: myQueue)
if cameraCaptureSession.canAddOutput(theOutput) {
cameraCaptureSession.addOutput(theOutput)
}
cameraCaptureSession.commitConfiguration()
}
我正在尝试将从 AVCaptureVideoDataOutput 委托(作为 CMSampleBuffer)获取的帧转换为 UIImage。但是我得到了 fatal error: unexpectedly found nil while unwrapping an Optional value
有人可以告诉我我的代码有什么问题吗?我假设我的 sampleBufferToUIImage 函数有问题。
将 CMSampleBuffer 转换为 UIImage 的函数:
func sampleBufferToUIImage(sampleBuffer: CMSampleBuffer) -> UIImage{
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer!)
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
let width = CVPixelBufferGetWidth(imageBuffer!)
let height = CVPixelBufferGetHeight(imageBuffer!)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue)
let context = CGContext(data: baseAddress, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
// *********Getting the error from this line***********
let quartzImage = context!.makeImage()
CVPixelBufferUnlockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let image = UIImage(cgImage: quartzImage!)
return image
}
委托我正在阅读框架的地方:
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
if count <= 0 {
// Calling my function to convert to UIImage.
let image = sampleBufferToUIImage(sampleBuffer: sampleBuffer)
let imageData = UIImagePNGRepresentation(image)
uploadImage(jpgData: imageData)
}
count = count + 1
}
正在设置 AVSession:
func setupCameraSession() {
captureSession.sessionPreset = AVCaptureSessionPresetHigh
// Declare AVCaptureDevice to default(back camera). The "as" changes removes the optional?
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) as AVCaptureDevice
do {
let deviceInput = try AVCaptureDeviceInput(device: captureDevice)
if (captureSession.canAddInput(deviceInput) == true) {
captureSession.addInput(deviceInput)
}
let dataOutput = AVCaptureVideoDataOutput()
dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString) : NSNumber(value: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange as UInt32)]
dataOutput.alwaysDiscardsLateVideoFrames = true
if (captureSession.canAddOutput(dataOutput) == true) {
captureSession.addOutput(dataOutput)
}
} catch {
}
AVCaptureVideoDataOutput 的视频设置不正确。将 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
更改为 kCVPixelFormatType_32BGRA
试试这个,对我有用 Swift 3
// Sample buffer handling delegate function
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
let myPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
myCIimage = CIImage(cvPixelBuffer: myPixelBuffer!)
videoImage = UIImage(ciImage: myCIimage)
uIimage.image = videoImage
}
// AV 会话
func startVideoDisplay() {
do {
let tryDeviceInput = try AVCaptureDeviceInput(device: cameraDevice)
cameraCaptureSession.addInput(tryDeviceInput)
} catch { print(error.localizedDescription) }
caViewLayer = AVCaptureVideoPreviewLayer(session: cameraCaptureSession)
view.layer.addSublayer(caViewLayer)
cameraCaptureSession.startRunning()
let myQueue = DispatchQueue(label: "se.paredes.FunAV", qos: .userInteractive, attributes: .concurrent)
let theOutput = AVCaptureVideoDataOutput()
theOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString): NSNumber(value:kCVPixelFormatType_32BGRA)]
theOutput.alwaysDiscardsLateVideoFrames = true
theOutput.setSampleBufferDelegate(self, queue: myQueue)
if cameraCaptureSession.canAddOutput(theOutput) {
cameraCaptureSession.addOutput(theOutput)
}
cameraCaptureSession.commitConfiguration()
}