Ios AVAssetWriter从音频切换到视频会使第一帧变黑

Ios AVAssetWriter从音频切换到视频会使第一帧变黑,ios,swift,avcapturesession,avassetwriter,Ios,Swift,Avcapturesession,Avassetwriter,我录制音频和视频文件。用户可以仅从视频切换到音频,也可以从音频切换到视频。 但当我从音频切换到视频时,第一帧是黑色的 开关 func switch_to_audio(){ capture_session.beginConfiguration() capture_session.removeInput(video_input) capture_session.removeOutput(video_output) init_audio_writer(video_on:

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

开关

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")
        }
    }
}
好吧,愚蠢的错误

启动应用程序时,我启动我的
AVCaptureSession
,添加输入、输出等。我刚刚调用
start\u new\u record
有点太早了,就在我的捕获会话调用
commitConfiguration
之前

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

好吧,愚蠢的错误

启动应用程序时,我启动我的
AVCaptureSession
,添加输入、输出等。我刚刚调用
start\u new\u record
有点太早了,就在我的捕获会话调用
commitConfiguration
之前


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

这是违反直觉的,但至少在我自己的项目中,如果我开始使用AVAssetWriter编写示例,并且没有音频和视频数据开始,那么我在开始时会得到黑色帧,即使我有视频。将视频开始时间调整为第一个音频样本的时间。这是违反直觉的,但至少在我自己的项目中,如果我开始使用AVAssetWriter编写样本,并且没有音频和视频数据开始,那么我会在开始时得到黑色帧,即使我有视频。将视频开始时间调整为第一个音频样本的时间。嘿,玛丽,所以我的程序也有同样的问题,尽管我已经准备好了所有的东西。你能带我过去吗。我的代码的一个例子可以在这里找到:嘿,玛丽,所以我的程序也有同样的问题,尽管我已经准备好了所有的东西。你能带我过去吗。下面是我的代码示例: