问题描述
我正在使用AVFoundation创建一个应用程序,在该应用程序中,必须将摄像机的Feed延迟从0ms延迟到1000ms。
当我有0.0的延迟时,我是从AVCaptureOutput提供的CVImageBuffer创建UIImage的,它工作得很好。
但是当我的延迟> 0.0时,我正在录制视频片段,对其进行编码,然后使用AVAssetWriter将其存储在文件中,然后在AVPlayer中播放。当我的延迟> 100ms,但值
我在做什么错了?
这是代码:
func setupCamera() {
captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
let availableDevices = AVCaptureDevice.discoverySession(deviceTypes: [.builtInUltraWideCamera,.builtInWideAngleCamera],mediaType: .video,position: .back).devices
if let device = availableDevices.first {
captureDevice = device
captureDevice.updateFormatWithPreferredVideoSpec(preferredSpec: AVCaptureDevice.VideoSpec(fps: 60,size: CGSize(width: 1920,height: 1080)))
beginCameraSession()
}
}
private func setupDeviceinput() {
do {
let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice)
captureSession.addInput(captureDeviceInput)
} catch {
print(error.localizedDescription)
}
}
private func setupDeviceOutput() {
let dataOutput = AVCaptureVideoDataOutput().then {
$0.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as String):NSNumber(value: kCVPixelFormatType_32BGRA)]
$0.alwaysdiscardsLateVideoFrames = true
}
if captureSession.canAddOutput(dataOutput) {
captureSession.addOutput(dataOutput)
}
captureSession.commitConfiguration()
let queue = dispatchQueue(label: "com.captureQueue")
dataOutput.setSampleBufferDelegate(self,queue: queue)
}
fileprivate func createWriterInput(for presentationTimeStamp: CMTime) {
let fileManager = FileManager.default
chunkOutputURL = fileManager.urls(for: .documentDirectory,in: .userDomainMask)[0].appendingPathComponent("chunk\(chunkNumber).mov")
try? fileManager.removeItem(at: chunkOutputURL)
assetWriter = try! AVAssetWriter(outputURL: chunkOutputURL,fileType: AVFileType.mov)
assetWriter.shouldOptimizeforNetworkUse = true
let outputSettings: [String: Any] = [AVVideoCodecKey:AVVideoCodecType.h264,AVVideoWidthKey: 1920,AVVideoHeightKey: 1080,AVVideoCompressionPropertiesKey: [AVVideoExpectedSourceFrameRateKey: 60,AVVideoAverageNonDroppableFrameRateKey: 60,AVVideoAverageBitRateKey: 60000000,AVVideoMaxKeyFrameIntervalDurationKey: 0.0,AVVideoAllowFrameReorderingKey: true]]
assetWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video,outputSettings: outputSettings)
assetWriterInput.expectsMediaDataInRealTime = true
assetWriter.add(assetWriterInput)
chunkNumber += 1
chunkStartTime = presentationTimeStamp
assetWriter.startWriting()
assetWriter.startSession(atSourceTime: chunkStartTime)
}
// MARK: - Outputs
fileprivate func createImageOutput(from buffer: CMSampleBuffer) {
guard let cvBuffer = CMSampleBufferGetimageBuffer(buffer) else {
return
}
let ciImage = CIImage(cvImageBuffer: cvBuffer)
let uiImage = UIImage(ciImage: ciImage)
didOutputimage?(uiImage)
}
fileprivate func createVideoOutput(from buffer: CMSampleBuffer) {
let presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(buffer)
if assetWriter == nil {
createWriterInput(for: presentationTimeStamp)
} else {
let chunkDuration = CMTimeGetSeconds(CMTimeSubtract(presentationTimeStamp,chunkStartTime))
if chunkDuration > latency {
assetWriter.endSession(atSourceTime: presentationTimeStamp)
let newChunkURL = chunkOutputURL!
let chunkAssetWriter = assetWriter!
chunkAssetWriter.finishWriting { [weak self] in
guard let strongSelf = self else { return }
strongSelf.didOutputPlayerItem?(AVPlayerItem(url: newChunkURL))
}
createWriterInput(for: presentationTimeStamp)
}
}
if !assetWriterInput.append(buffer) {
print("append says NO: \(assetWriter.status.rawValue)")
}
}
func captureOutput(_ output: AVCaptureOutput,didOutput sampleBuffer: CMSampleBuffer,from connection: AVCaptureConnection) {
if latency == 0.0 {
createImageOutput(from: sampleBuffer)
} else {
createVideoOutput(from: sampleBuffer)
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)