AVCaptureVideoDataOutputSampleBufferDelegate.CaptureOutput 未调用

Posted

技术标签:

【中文标题】AVCaptureVideoDataOutputSampleBufferDelegate.CaptureOutput 未调用【英文标题】:AVCaptureVideoDataOutputSampleBufferDelegate.CaptureOutput not called 【发布时间】:2016-03-07 03:53:38 【问题描述】:

我目前有一个自研框架(MySDK),以及一个使用MySDK的ios应用(MyApp)。

在 MySDK 内部,我在 MySDK 中有一个类 (Scanner),用于处理来自设备摄像头的视频输出的图像。

这是我的代码示例:

Scanner.swift

class Scanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate 

    var captureDevice : AVCaptureDevice?
    var captureOutput : AVCaptureVideoDataOutput?
    var previewLayer : AVCaptureVideoPreviewLayer?
    var captureSession : AVCaptureSession?

    var rootViewController : UIViewController?

    func scanImage (viewController: UIViewController)
    
        NSLog("%@", "scanning begins!")

        if (captureSession == nil)  captureSession = AVCaptureSession() 

        rootViewController = viewController;

        captureSession!.sessionPreset = AVCaptureSessionPresetHigh

        let devices = AVCaptureDevice.devices()

        for device in devices 
            if (device.hasMediaType(AVMediaTypeVideo)) 
                if(device.position == AVCaptureDevicePosition.Back) 
                    captureDevice = device as? AVCaptureDevice
                
            
        

        if (captureDevice != nil) 
            NSLog("%@", "beginning session!")

            beginSession()
        
    

    func beginSession()
    
        if (captureSession == nil)  captureSession = AVCaptureSession() 
        if (captureOutput == nil)  captureOutput = AVCaptureVideoDataOutput() 
        if (previewLayer == nil)  previewLayer = AVCaptureVideoPreviewLayer() 

        let queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);

        captureOutput!.setSampleBufferDelegate(self, queue: queue)
        captureOutput!.videoSettings = [kCVPixelBufferPixelFormatTypeKey as NSString: Int(kCVPixelFormatType_32BGRA)]

        captureSession!.addInput(try! AVCaptureDeviceInput(device: captureDevice))
        captureSession!.addOutput(captureOutput)

        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer!.frame = rootViewController!.view.layer.frame

        rootViewController!.view.layer.addSublayer(previewLayer!)

        captureSession!.startRunning()
    

    func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBufferRef!, fromConnection connection: AVCaptureConnection!)
    
        NSLog("%@", "captured!")
    

在 MyApp 内部,我有一个 ViewController,它实现了一个 IBAction,其中初始化了 Scanner 类,并触发了 scanImage 函数。

MyApp.m

- (IBAction)btnScanImage_TouchDown:(id)sender

    Scanner * scanner = [[Scanner alloc] init];

    [scanner scanImage:self];

相机视图出现在应用程序内部,但从不触发 captureOutput 函数,并且控制台仅包含以下两行:

2016-03-07 11:11:45.860 myapp[1236:337377] scanning begins!
2016-03-07 11:11:45.984 myapp[1236:337377] beginning session!

创建一个独立的应用程序,并将 Scanner.swift 中的代码嵌入到 ViewController 中就可以了; captureOutput 函数正确触发。

有人知道我在这里做错了什么吗?

【问题讨论】:

【参考方案1】:

经过多次尝试和错误,我终于找到了解决问题的方法。

显然,我没有将 Scanner 对象创建为 class 变量,而只是作为 local 变量。

一旦Scanner 对象被创建为 变量,委托方法captureOutput 就会被正确触发。

【讨论】:

以上是关于AVCaptureVideoDataOutputSampleBufferDelegate.CaptureOutput 未调用的主要内容,如果未能解决你的问题,请参考以下文章