【问题标题】:AVAssetWriter switch from audio to video makes first frames blackAVAssetWriter 从音频切换到视频使第一帧变黑
【发布时间】:2017-05-18 08:25:12
【问题描述】:

我录制音频和视频文件。用户只能从视频切换到音频,也可以从音频切换到视频。 但是当我从音频切换到视频时,第一帧是黑色的。

切换

func switch_to_audio(){
    capture_session.beginConfiguration()
    capture_session.removeInput(video_input)
    capture_session.removeOutput(video_output)
    init_audio_writer(video_on: false)
    capture_session.commitConfiguration()
    start_new_record()
}

func init_audio_writer(video_on:Bool){
    if video_on{
        let video_settings=[
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 44100,
            AVEncoderBitRateKey:128000,
            AVNumberOfChannelsKey: NSNumber(value:1)] as [String : Any]
        audio_writer=AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: video_settings)
    }else{
        let audio_settings=[
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 44100,
            AVEncoderBitRateKey:128000,
            AVNumberOfChannelsKey: NSNumber(value:1)] as [String : Any]

        audio_writer=AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: audio_settings)
    }
}

func switch_to_video(){
    capture_session.beginConfiguration()
    capture_session.addInput(video_input)
    capture_session.addOutput(video_output)
    init_audio_writer(video_on:true)
    capture_session.commitConfiguration()
}

录音

func start_new_record(){
    do{
        try self.file_writer=AVAssetWriter(url: self.file_url!, fileType: AVFileTypeMPEG4)
        if video_on{
            if file_writer.canAdd(video_writer){
                file_writer.add(video_writer)
            }
        }
        if file_writer.canAdd(audio_writer){
            file_writer.add(audio_writer)
        }
    }catch let e as NSError{
        print(e)
    }
}

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!){
    guard is_recording else{
        return
    }

    guard CMSampleBufferDataIsReady(sampleBuffer) else{
        print("data not ready")
        return
    }

    guard let w=file_writer else{
        print("video writer nil")
        return
    }

    if w.status == .unknown && start_recording_time==nil && is_recording{
        if (video_on && captureOutput==video_output) || (!video_on && captureOutput==audio_output){
            print("START RECORDING")
            file_writer?.startWriting()
            start_recording_time=CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
            file_writer?.startSession(atSourceTime: start_recording_time!)
        }else{
            return
        }
    }

    if w.status == .failed{
        print("failed /", w.error ?? "")
        return
    }

    if captureOutput==audio_output{
        if audio_writer.isReadyForMoreMediaData{
            if !video_on || (video_on && video_written){
                audio_writer.append(sampleBuffer)
                //print("write audio")
            }
        }else{
            print("audio writer not ready")
        }
    }else if video_output != nil && captureOutput==video_output{
        if video_writer.isReadyForMoreMediaData{
            video_writer.append(sampleBuffer)
            if !video_written{
                print("added 1st video frame")
                video_written=true
            }
        }else{
            print("video writer not ready")
        }
    }
}

【问题讨论】:

  • 这是违反直觉的,但至少在我自己的项目中,如果我开始使用 AVAssetWriter 编写示例并且没有音频和视频数据开始,那么我会在开始时得到黑帧——虽然我有视频。将视频开始时间调整为第一个音频样本的时间。
  • 你是怎么做到的?我的意思是你是如何检查两个样本是否都存在的?

标签: ios swift avcapturesession avassetwriter


【解决方案1】:

好吧,愚蠢的错误......

在启动应用程序时,我初始化了我的AVCaptureSession,添加了输入、输出等。我只是在我的捕获会话中调用start_new_record 之前调用start_new_record 有点太早了。

至少我的代码可能对某些人有用。

【讨论】:

  • 嘿玛丽,所以我的程序也遇到了同样的问题,即使我已经准备好了一切。你能指导我通过吗?可以在这里找到我的代码示例:stackoverflow.com/questions/65000687/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-11
  • 1970-01-01
  • 2016-05-26
  • 2020-03-09
  • 2023-03-02
  • 2021-03-08
相关资源
最近更新 更多