简体   繁体   English

AVAssetWriter:开始写入时出现暂时滞后

[英]AVAssetWriter: Momentary Lag When Starting Write

I am developing an app that records a video using AVAssetWriter (the source media are sample buffers output from captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) . 我正在开发一个使用AVAssetWriter录制视频的应用程序(源媒体是从captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)输出的样本缓冲区。

I've noticed that the very first time I instantiate my AVAssetWriter , then call startWriting() and startSession(atSourceTime: CMTime) , there is a lag of about 30ms. 我注意到,第一次实例化AVAssetWriter ,然后调用startWriting()startSession(atSourceTime: CMTime) ,大约有30毫秒的延迟。 This causes the video preview on the screen to momentarily hang, which also results in the first few frames of the video not write properly. 这会导致屏幕上的视频预览暂时挂起,这也导致视频的前几帧无法正确写入。

Curiously, if I then re-instantiate my AVAssetWriter and take all of the same steps again, everything works fine from that point onward. 奇怪的是,如果我随后重新实例化AVAssetWriter并再次执行所有相同的步骤,那么AVAssetWriter起一切都将正常运行。 This only occurs the very first time. 这仅是第一次发生。

While perhaps too lengthy to post, this is the function in which I am certain the error is occurring; 虽然可能太长,无法发布,但是我可以确定该函数正在发生错误。

func insert(pixel buffer: CVPixelBuffer, with time: CMTime) {

    // Check for unknown status
    if fileWriter.status == .unknown {
        guard startingVideoTime == nil else {
            print("We've received an error setting the starting video time.")
            return
        }
        startingVideoTime = time
        if fileWriter.startWriting() {
            fileWriter.startSession(atSourceTime: startingVideoTime!)
            isRecording = true
        }
    }

    // Append buffer
    if videoInput.isReadyForMoreMediaData {
        append(pixel: buffer, with: time)
        isRecording = true
    }
}

For posterity, I am calling the above function from my captureOutput , only doing so when my self.isRecording = true , which I set when the user taps a "Start Record" button. 为了后代,我仅在我的self.isRecording = true时从我的captureOutput调用上述函数,当用户点击“开始记录”按钮时进行设置。

let videoCompressionSettings: [String: Any] = [
  AVVideoCodecKey: AVVideoCodecType.h264,
  AVVideoWidthKey: NSNumber(value: 1080),
  AVVideoHeightKey: NSNumber(value: 1920)
]
let audioCompressionSettings: [String: Any] = [
  AVNumberOfChannelsKey: NSNumber(value: 1),
  AVEncoderAudioQualityForVBRKey: NSNumber(value: 91),
  AVEncoderBitRatePerChannelKey:NSNumber(value: 9600),
  AVEncoderBitRateStrategyKey: AVAudioBitRateStrategy_Variable,
  AVFormatIDKey: NSNumber(value: 1633772320),
  AVSampleRateKey: NSNumber(value: 44100)
]
// My own wrapper for AVAssetWriter
movieWriterManager = MovieWriterManager(videoUrl: recordingVideoURL(), audioUrl: recordingAudioURL(), videoCompressionSettings: videoCompressionSettings, audioCompressionSettings: audioCompressionSettings)
movieWriterManager?.warmup()

You may try to buy time by running the same steps at AppDelegate's didFinishLaunchingWithOptions with a default videoCompressionSettings and audioCompressionSettings. 您可以尝试通过在AppDelegate的didFinishLaunchingWithOptions上使用默认的videoCompressionSettings和audioCompressionSettings运行相同的步骤来争取时间。 It's actually not blocking UI thread but only the video output connection of AVCaptureVideoDataOutput. 实际上,它不是在阻止UI线程,而只是在阻止AVCaptureVideoDataOutput的视频输出连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM