背景:
我正在使用AVCaptureVideoDataOutput
其他AVCaptureSession
各种AV
工具来创建视频会话,以便我可以创建相机会话。我有相机在屏幕上看到的实时信息。
我使用AVCaptureVideoDataOutput
而不是AVCaptureMovieFileOutput
因为我通过实时提要获得的图像是使用CIFilter
's. 现在,我想记录按下按钮时向用户显示的内容。我这样做的想法是使用下面的函数,因为我认为这个函数会捕获每一帧。我从Apple 的页面中推断出这一点,该页面指出:
每当输出捕获并输出新的视频帧、解码或重新编码它的 videoSettings 属性时,代表就会收到此消息。代表可以将提供的视频帧与其他 API 结合使用以进行进一步处理。
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
我希望每一帧都在这里,这样我就可以使用一个AVAssetWriter
并将缓冲区添加到videoWriterInput
. 这可以在这里看到,其中答案表明该方法每次都func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
添加。sampleBuffer
videoWriterInput
我的努力:
我试图模拟上面的 SO 帖子,其中答案AVAssetWriter
用于写入AVCaptureVideoDataOutput
文件。但是,我的代码(如下所示)没有调用AVCaptureVideoDataOutputSampleBufferDelegate
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
委托方法。
注意:这不是所有代码 - 我只添加相关部分 - 如果缺少您需要的东西,请告诉我
VideoCapture.swift
class VideoCapture: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate {
private let captureSession = AVCaptureSession()
private let videoDataOutput = AVCaptureVideoDataOutput()
private let dataOutputQueue = DispatchQueue(label: "com.Camera.dataOutputQueue")
private var videoConnection: AVCaptureConnection!
//NEVER GETS CALLED
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
print("Buf: \(sampleBuffer)")
}
func captureOutput(_ output: AVCaptureOutput, didDrop sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
print("Drop Buff: \(sampleBuffer)")
}
init() {
//Some Setup
captureSession.sessionPreset = AVCaptureSession.Preset.high
//...
do {
// video output
videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
videoDataOutput.alwaysDiscardsLateVideoFrames = true
videoDataOutput.setSampleBufferDelegate(self, queue: dataOutputQueue)
guard captureSession.canAddOutput(videoDataOutput) else { fatalError() }
captureSession.addOutput(videoDataOutput)
videoConnection = videoDataOutput.connection(with: .video)
}
//...
}
}
另一个文件.swift
class VC: UIViewController {
private var videoCapture: VideoCapture!
init() {
self.videoCapture = VideoCapture()
}
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let videoCapture = videoCapture else {return}
videoCapture.startCapture()
}
}
我的期望:
我期待这个方法
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
被调用并至少打印出上面示例中的缓冲区。这没有发生,所以我无法进一步开发并将我的缓冲区插入到videoWriteInput
记录中。
实际发生的事情:
它永远不会被调用。我确保使用设置委托videoDataOutput.setSampleBufferDelegate(self, queue: dataOutputQueue)
并清楚地表明委托方法已创建。我肯定会使用自动完成功能,以便从 XCode 创建该方法,所以我没有弄乱方法名称,例如这个 SO post。
问题:
我怎样才能适当地获取要调用的方法——假设我的直觉是正确的,这个方法是为每一帧调用的,并且是我可以插入到我的缓冲区中videoWriterInput
——这样我就可以从AVCaptureSession
屏幕上看到的视频录制?
值得注意的是:
这个项目在调用方面不起作用
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
虽然这 确实有效。
编辑:
我发现由于某种原因,AVCaptureDataOutputSynchronizer
导致它不调用委托函数。有任何想法吗?