问题描述
我一直在尝试寻找一种解决方案,以便在使用AVFoundation切换摄像机时允许连续记录。还有其他关于此问题的帖子,没有得到公认的答案,我已经尝试了所有这些方法,但是似乎都没有用。似乎没有太多滞后是可能的,即:(Snapchat,Facebook)。我尝试将 AVAssetWriter 与多个 AVCaptureVideoDataOutput 和 AVCaptureAudioDataOutput 输出结合使用,但这只会导致在切换相机后关闭视频和音频时序。我也尝试过在2个捕获会话之间切换单个输出,但这会导致相同的问题。理想情况下,我需要在捕获后尽快提供视频输出。
当前,我正在尝试使用 CMBufferQueue 来收集示例缓冲区,然后将它们返回到AVAssetWriter。但是我的输出只显示了几个样本,然后冻结了。
希望得到任何帮助
我当前的一些代码:
var vIsFinished = false
var aIsFinished = false
self.videoWriter.startSession(atSourceTime: self.vQueue!.firstPresentationTimeStamp)
self.videoWriterInput.requestMediaDataWhenReady(on: .init(label: "com.jzyla.CameraTest")) {
while self.videoWriterInput!.isReadyForMoreMediaData {
if let buffer = self.vQueue?.dequeueIfDataReady() {
print("append")
self.videoWriterInput.append(buffer as! CMSampleBuffer)
}
if self.vQueue!.isEmpty {
self.videoWriterInput.markAsFinished()
vIsFinished = true
if vIsFinished && aIsFinished {
self.returnVideo()
break
}
}
}
}
self.audioWriterInput.requestMediaDataWhenReady(on: .init(label: "com.jzyla.CameraTest2")) {
while self.audioWriterInput!.isReadyForMoreMediaData {
if let buffer = self.aQueue?.dequeueIfDataReady() {
print("append")
self.audioWriterInput.append(buffer as! CMSampleBuffer)
}
if self.aQueue!.isEmpty {
self.audioWriterInput.markAsFinished()
aIsFinished = true
if vIsFinished && aIsFinished {
self.returnVideo()
break
}
}
}
}
public func captureOutput(_ output: AVCaptureOutput,didOutput sampleBuffer: CMSampleBuffer,from connection: AVCaptureConnection) {
if canWrite() {
if output == self.videoOutput || output == self.videoOutput2 {
print("vid buffer")
let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
if sessionAtSourceTime == nil {
sessionAtSourceTime = timestamp
self.lastFrameSourceTime = timestamp
}
} else if output == self.audioOutput || output == self.audioOutput2 {
// write audio buffer
if sessionAtSourceTime != nil {
try! self.aQueue?.enqueue(sampleBuffer)
}
}
}
}
func setup() {
self.videoWriterInput.expectsMediaDataInRealTime = false
if self.videoWriter.canAdd(self.videoWriterInput) {
self.videoWriter.add(self.videoWriterInput)
}
// add audio input
self.audioWriterInput = AVAssetWriterInput.init(mediaType: .audio,outputSettings: nil)
self.audioWriterInput.expectsMediaDataInRealTime = false
if self.videoWriter.canAdd(self.audioWriterInput!) {
self.videoWriter.add(self.audioWriterInput!)
}
self.videoOutput.setSampleBufferDelegate(self,queue: .init(label: "com.jzyla.videoCaptureQueue"))
self.audioOutput.setSampleBufferDelegate(self,queue: .init(label: "com.jzyla.audioCaptueQueue"))
self.videoOutput2.setSampleBufferDelegate(self,queue: .init(label: "com.jzyla.videoCaptureQueue2"))
self.audioOutput2.setSampleBufferDelegate(self,queue: .init(label: "com.jzyla.audioCaptueQueue2"))
self.vQueue = try .init(capacity: 0,handlers: .outputPTSSortedSampleBuffers)
self.aQueue = try .init(capacity: 0,handlers: .outputPTSSortedSampleBuffers)
self.videoWriter.startWriting()
}
func setSessionActive(old: AVCaptureSession,new: AVCaptureSession,completion: @escaping () -> Void) {
dispatchQueue.global(qos: .userInitiated).async {
print("set session active",self.currentCamera.rawValue)
old.stopRunning()
new.stopRunning()
new.startRunning()
print("session started")
dispatchQueue.main.async {
completion()
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)