在没有预览的情况下使用 AVCaptureVideoDataOutputSampleBufferDelegate window
Using AVCaptureVideoDataOutputSampleBufferDelegate without a preview window
我正在开发一个基于 Swift 的 macOS 应用程序,我需要在其中捕获视频输入,但不将其显示在屏幕上...而不是显示视频,我想发送缓冲的视频在其他地方处理的数据,并最终将其显示在 SceneKit
场景中的对象上。
我有一个 CameraInput
class 有一个 prepareCamera
方法:
fileprivate func prepareCamera() {
self.videoSession = AVCaptureSession()
self.videoSession.sessionPreset = AVCaptureSession.Preset.photo
if let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] {
for device in devices {
if device.hasMediaType(AVMediaType.video) {
cameraDevice = device
if cameraDevice != nil {
do {
let input = try AVCaptureDeviceInput(device: cameraDevice)
if videoSession.canAddInput(input) {
videoSession.addInput(input)
}
} catch {
print(error.localizedDescription)
}
}
}
}
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self as AVCaptureVideoDataOutputSampleBufferDelegate, queue: DispatchQueue(label: "sample buffer delegate", attributes: []))
if videoSession.canAddOutput(videoOutput) {
videoSession.addOutput(videoOutput)
}
}
}
以及启动 AVCaptureSession
会话的 startSession
方法:
fileprivate func startSession() {
if let videoSession = videoSession {
if !videoSession.isRunning {
self.videoInputRunning = true
videoSession.startRunning()
}
}
}
我还实现了 AVCaptureVideoDataOutputSampleBufferDelegate
,我打算在其中捕获 CMSampleBuffer
供以后使用:
extension CameraInput: AVCaptureVideoDataOutputSampleBufferDelegate {
internal func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
print(Date())
}
}
但是,永远不会调用委托。这是我必须显示视频输出以便调用它的情况吗?
None 您的问题与您是否显示捕获视频的预览有关。
如果你在 Swift 4(看起来你是),你要实现的委托方法签名不是 captureOutput(_:didOutputSampleBuffer:from:)
,它是 this :
optional func captureOutput(_ output: AVCaptureOutput,
didOutput sampleBuffer: CMSampleBuffer,
from connection: AVCaptureConnection)
不相关的提示:
命名空间常量意味着您可以根据需要更简短;例如videoSession.sessionPreset = .photo
AVCaptureDevice.devices()
已弃用。而不是调用它并自己循环遍历设备,只需 ask AVCaptureDevice
for exactly the kind of device you want:
let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera,
for: .video, position: .back)
如果您的 class 已经声明符合 AVCaptureVideoDataOutputSampleBufferDelegate
协议,则您不需要在 videoOutput.setSampleBufferDelegate(self as AVCaptureVideoDataOutputSampleBufferDelegate
中进行 as
转换。
最后,如果您只是想将来自摄像机的实时视频映射到 SceneKit 场景的某些部分,请注意,在 iOS 11 中,您可以将 AVCaptureDevice
分配给直接 SCNMaterialProperty
的 contents
— 无需自己抓取、处理和移动像素缓冲区。
我正在开发一个基于 Swift 的 macOS 应用程序,我需要在其中捕获视频输入,但不将其显示在屏幕上...而不是显示视频,我想发送缓冲的视频在其他地方处理的数据,并最终将其显示在 SceneKit
场景中的对象上。
我有一个 CameraInput
class 有一个 prepareCamera
方法:
fileprivate func prepareCamera() {
self.videoSession = AVCaptureSession()
self.videoSession.sessionPreset = AVCaptureSession.Preset.photo
if let devices = AVCaptureDevice.devices() as? [AVCaptureDevice] {
for device in devices {
if device.hasMediaType(AVMediaType.video) {
cameraDevice = device
if cameraDevice != nil {
do {
let input = try AVCaptureDeviceInput(device: cameraDevice)
if videoSession.canAddInput(input) {
videoSession.addInput(input)
}
} catch {
print(error.localizedDescription)
}
}
}
}
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self as AVCaptureVideoDataOutputSampleBufferDelegate, queue: DispatchQueue(label: "sample buffer delegate", attributes: []))
if videoSession.canAddOutput(videoOutput) {
videoSession.addOutput(videoOutput)
}
}
}
以及启动 AVCaptureSession
会话的 startSession
方法:
fileprivate func startSession() {
if let videoSession = videoSession {
if !videoSession.isRunning {
self.videoInputRunning = true
videoSession.startRunning()
}
}
}
我还实现了 AVCaptureVideoDataOutputSampleBufferDelegate
,我打算在其中捕获 CMSampleBuffer
供以后使用:
extension CameraInput: AVCaptureVideoDataOutputSampleBufferDelegate {
internal func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
print(Date())
}
}
但是,永远不会调用委托。这是我必须显示视频输出以便调用它的情况吗?
None 您的问题与您是否显示捕获视频的预览有关。
如果你在 Swift 4(看起来你是),你要实现的委托方法签名不是 captureOutput(_:didOutputSampleBuffer:from:)
,它是 this :
optional func captureOutput(_ output: AVCaptureOutput,
didOutput sampleBuffer: CMSampleBuffer,
from connection: AVCaptureConnection)
不相关的提示:
命名空间常量意味着您可以根据需要更简短;例如
videoSession.sessionPreset = .photo
AVCaptureDevice.devices()
已弃用。而不是调用它并自己循环遍历设备,只需 askAVCaptureDevice
for exactly the kind of device you want:let captureDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)
如果您的 class 已经声明符合
AVCaptureVideoDataOutputSampleBufferDelegate
协议,则您不需要在videoOutput.setSampleBufferDelegate(self as AVCaptureVideoDataOutputSampleBufferDelegate
中进行as
转换。
最后,如果您只是想将来自摄像机的实时视频映射到 SceneKit 场景的某些部分,请注意,在 iOS 11 中,您可以将 AVCaptureDevice
分配给直接 SCNMaterialProperty
的 contents
— 无需自己抓取、处理和移动像素缓冲区。