简体   繁体   English

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

[英]AVAssetWriter switch from audio to video makes first frames black

I record audio and video files. 我录制音频和视频文件。 The user can switch from video to audio only and from audio to video. 用户可以仅从视频切换到音频,从音频切换到视频。 But when I switch from audio to video, the first frames are black. 但是当我从音频切换到视频时,第一帧是黑色的。

Switch 开关

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()
}

Recording 记录

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")
        }
    }
}

Ok, stupid mistake... 好吧,愚蠢的错误......

When launching the app, I init my AVCaptureSession , add inputs, outputs, etc. And I was just calling start_new_record a bit too soon, just before commitConfiguration was called on my capture session. 当启动应用程序,我初始化我AVCaptureSession ,增加输入,输出等。而我只是打电话start_new_record有点太早,之前commitConfiguration叫我捕获会话。

At least my code might be useful to some people. 至少我的代码可能对某些人有用。

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

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