2017-05-18 10 views
1

오디오 및 비디오 파일을 레코드합니다. 사용자는 비디오에서 오디오로만, 오디오에서 비디오로 전환 할 수 있습니다. 그러나 오디오에서 비디오로 전환하면 첫 번째 프레임이 검은 색이됩니다.AVAssetWriter에서 오디오에서 비디오로 전환하면 첫 프레임이 검은 색이됩니다.

스위치

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

반 직관적이지만 적어도 내 자신의 프로젝트에서 AVAssetWriter로 샘플을 작성하고 시작하는 오디오 및 비디오 데이터가 없으면 처음에는 검정색 프레임이 생깁니다. 비디오를 가지고있다. 비디오 시작 시간을 첫 번째 오디오 샘플의 시간으로 조정하십시오. – drewster

답변

0

좋아, 바보 같은 실수 ...

이 응용 프로그램을 실행, 내 AVCaptureSession, 추가 입력, 출력은 초기화하기, 등. 그리고 나는 단지 start_new_record를 너무나 곧 호출하고 있었다. 내 캡처 세션에서 commitConfiguration이 호출되기 직전입니다.

적어도 내 코드는 일부 사람들에게 유용 할 수 있습니다.