繁体   English   中英

如何使用AVFoundation在macOS中捕获视频数据?

[英]How to use the AVFoundation to capture video data in macOS?

我已根据在网上找到的几个示例编写了以下代码,以便从macOS上的内置摄像头捕获视频数据。 设置AVCaptureSession不会引发任何致命错误,但不会调用该委托,并且在我调用captureSession.startRunning()立即记录一些明显的错误。

到目前为止,我已经尝试对代码进行一些小的调整(例如,从输出中删除videoSettings或从会话中删除sessionPreset ),以及检查系统偏好设置中我的测试应用程序是否具有相机访问权限。 但是,日志仍然存在,并且不会调用该委托。

CameraInput类(包括委托):

final class CameraInput: NSObject {
    private lazy var sampleBufferDelegateQueue = DispatchQueue(label: "CameraInput")
    private lazy var captureSession: AVCaptureSession = {
        let session = AVCaptureSession()
        session.sessionPreset = .hd1280x720

        let device = AVCaptureDevice.default(for: .video)!
        let input = try! AVCaptureDeviceInput(device: device)
        session.addInput(input)

        let output = AVCaptureVideoDataOutput()
        output.videoSettings = [
            kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA,
            kCVPixelBufferMetalCompatibilityKey as String: true
        ]
        output.alwaysDiscardsLateVideoFrames = true
        output.setSampleBufferDelegate(self, queue: self.sampleBufferDelegateQueue)
        session.addOutput(output)

        return session
    }()
}

extension CameraInput: CVInput {
    func start() {
        guard !self.captureSession.isRunning else {
            return
        }

        self.captureSession.startRunning()
    }

    func stop() {
        guard self.captureSession.isRunning else {
            return
        }

        self.captureSession.stopRunning()
    }
}

extension CameraInput: AVCaptureVideoDataOutputSampleBufferDelegate {
    private func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        // Handle captured frame
    }
}

ViewController(新可可应用程序中的默认viewcontroller):

class ViewController: NSViewController {
    lazy var cameraInput = CameraInput()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.cameraInput.start()
    }
}

记录的信息:

2019-01-02 16:27:15.821858+0100 TestApp[14182:1492243] [] CMIO_Unit_ScopeElement.h:200:SafeGetElement Throwing err: -67454
2019-01-02 16:27:15.823248+0100 TestApp[14182:1492243] [] CMIOUnitFigBaseObjectImpl.c:246:CMIOUnitCreateFromDescription Invalid paramater
2019-01-02 16:27:15.840190+0100 TestApp[14182:1492243] [] CMIO_Unit_Input_Device.cpp:244:GetPropertyInfo CMIOUInputFromProcs::GetPropertyInfo() failed for id 102, Error: -67456

非常感谢您对此工作的任何帮助! 另外,如果需要更多信息,请告知我。

编辑 遇到此问题后 ,我已经排除了有关沙盒的问题。

您需要从您的captureOutput:didOutput方法中删除关键字private

我猜想它足以使您的方法不被调用而更改签名。

您的代码似乎没问题。 尝试

  • 在Xcode中创建一个新的“ CocoaApp / Swift”项目
  • 将两个代码段都粘贴到AppDelegate中
  • AVCaptureVideoDataOutputSampleBufferDelegate添加到应用程序委托声明
  • self.captureSession.startRunning()添加到AppDelegate的applicationDidFinishLaunching函数中
  • 在沙箱设置中启用相机使用
  • NSCameraUsageDescription添加到Info.plist(macOS 10.14及更高版本)

我刚刚测试过,委托函数重复调用。 我在macOS 10.14 / XCode 10上看到了提到的日志输出(在macOS 10.13 / Xcode 9上没有显示),但是它不会阻止捕获。

所以问题不在问题中给出的代码中。 确保所有对象均已按预期实际创建,确保捕获会话安装程序运行,并且没有任何对象(尤其是输出委托)过早释放。

我遇到了这个确切的错误。 标记的答案帮助我正确地开始了工作,但是我觉得我的问题分歧很大,值得推荐另一个答案

我的代码在不工作时是这样的。

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!)

那是过去的样子。 我使用Xcode自动完成功能来获取当前版本。

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)

因此,故事的寓意... Conversion to Swift <insert version> is Available并不总是完美的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM