2017-05-18 2 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

[OK]を、愚かな間違い...

アプリを起動し、私は私の AVCaptureSession、追加の入力、出力はinitに、私はちょうど少し早く start_new_recordと呼んでいましたが、私のキャプチャセッションでは commitConfigurationが呼び出される直前でした。

私のコードは、少なくとも一部の人には役に立ちます。

関連する問題