ios - 来自 AVCaptureVideoDataOutput 的 CMSampleBuffer 意外地发现 nil

标签 ios swift uiimage cmsamplebuffer

我正在尝试将从 AVCaptureVideoDataOutput 委托(delegate)(作为 CMSampleBuffer)获取的帧转换为 UIImage。但是,我遇到了一个 fatal error :在展开可选值时意外发现 nil 有人可以告诉我我的代码有什么问题吗?我假设我的 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

}

委托(delegate)我正在阅读的框架:

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 {

    }

最佳答案

试试这个,对我来说适用于 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
}

//视听 session

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()
}

关于ios - 来自 AVCaptureVideoDataOutput 的 CMSampleBuffer 意外地发现 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41623186/

相关文章:

ios - Swift 3 - 比较两个日期时对 < 运算符的使用不明确

ios - UIWebView 获取请求URL路径(html字符串)

ios - 我如何模糊我的 UIViewController 上的一些层(不是代码,只是概念)

ios - TableView 单元格中的倒计时器在滚动后显示不同的值

ios - XCode 6.3.1 在更新配置文件时崩溃

ios - 如何以毫米/厘米为单位显示两幅图像之间的距离

ios - 使用 UIImage 放大 ScrollView

ios - 持久数据和原始数据类型 Ios 编程

ios - 如何在 UITextField iOS Swift 中添加连字符?

ios - 如何更改图像 tintColor