代码之家  ›  专栏  ›  技术社区  ›  Gori

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

  •  0
  • Gori  · 技术社区  · 6 年前

    AVCaptureSession ,但没有调用该委托,并且在调用时会立即记录一些明显的错误 captureSession.startRunning() .

    到目前为止,我已经尝试过对代码进行一些小的调整(例如删除 videoSettings 关于输出或 sessionPreset 以及在系统首选项中检查我的测试应用程序是否具有摄像头访问权限。但是,日志仍然存在,并且不会调用委托。

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

    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
    

    非常感谢您的帮助!另外,如果需要更多信息,请通知我。

    编辑 this question ,我已经排除了这是一个关于沙箱的问题。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Gordon Childs    6 年前

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

        2
  •  0
  •   NoHalfBits    6 年前

    你的代码似乎还可以。尝试

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

    我刚刚测试了这个,委托函数 我反复打电话。 我在macOS 10.14/XCode 10上看到了上面提到的日志输出(它没有在macOS 10.13/XCode 9上显示),但它并不阻止捕获。

    所以问题不在问题中给出的代码中。确保所有对象都按预期创建,捕获会话设置运行,并且没有对象(尤其是输出委托)被过早释放。

        3
  •  0
  •   Lucas Goossen    6 年前

    我正好遇到了这个错误。有标记的答案帮助我走上了正确的道路,但我觉得我的问题分歧很大,值得另一个答案

    我的代码是这样的,当它不工作的时候。

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

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

    所以这个故事的寓意。。。 Conversion to Swift <insert version> is Available 并不总是完美地工作。