0

I have successfully set up AVAssetWriter to record and save video to my camera roll. The only problem is that the first frame of the recorded video is a blank white frame. Is there a way I can get around this? What is going on?

Mike Schmidt
  • 945
  • 3
  • 12
  • 31

1 Answers1

2

Are you doing any manipulation on video frames? In my case I was resizing the video frames before writing them. In this case, audio frames were written first and after few frames, video frames were written. Due to this, the first few frames were shown white in the preview. But it was hardly noticeable in the video playback.

Solution :

Skip writing audio frames till you write a video frame using avasssetwriter


Recommended code for captureoutput

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection!) {

    if CMSampleBufferDataIsReady(sampleBuffer) == false
    {
      // Handle error
      return;
    }
    startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)

    if videoWriter.status == AVAssetWriterStatus.Unknown {
                videoWriter.startWriting()
                videoWriter.startSessionAtSourceTime(startTime)
                return 
        }

    if videoWriter.status == AVAssetWriterStatus.Failed {
      // Handle error here
      return;
    }

    // Here you collect each frame and process it

    if(recordingInProgress){

    if let _ = captureOutput as? AVCaptureVideoDataOutput {

        if videoWriterInput.isReadyForMoreMediaData{
            videoWriterInput.append(sampleBuffer)
            video_frames_written = true
        }
    }
    if let _ = captureOutput as? AVCaptureAudioDataOutput {
            if audioWriterInput.isReadyForMoreMediaData && video_frames_written{
                audioWriterInput.append(sampleBuffer)
            }

        }

    }

}
manishg
  • 9,520
  • 1
  • 16
  • 19
  • I thought this might work, but it seems that even though I write audio frames only when video frames are being written, there is still a white frame in which neither video or audio are recorded. Any other suggestions? – Mike Schmidt Feb 05 '17 at 00:17
  • can you share the recorded file and may be a log for the first samplebuffer ? – manishg Feb 05 '17 at 00:37
  • Here is an example of the video https://drive.google.com/file/d/0B2QAK-lm39WhdVlqa0hSY0tNaGM/view?usp=sharing . The way the recorder is setup is to record a new segment every one second, but the problem is not with that because there is still a blank frame with no video or audio for the first second of recording. – Mike Schmidt Feb 05 '17 at 01:03
  • I will add the code above for the sample buffer, but I am not sure how to get a log for it – Mike Schmidt Feb 05 '17 at 01:04
  • I also added the code where I start the first session – Mike Schmidt Feb 05 '17 at 01:06
  • One comment: you need to call startsession just before you write the first video frame. I meant when you receive first video frame for writing, call startsession and then write the video frame – manishg Feb 05 '17 at 01:27
  • Can you show me where in the code I should call it? I am not sure exactly where that would be – Mike Schmidt Feb 05 '17 at 01:34
  • With that code I keep getting an error: `unexpectedly found nil while unwrapping an Optional value` – Mike Schmidt Feb 05 '17 at 02:54
  • CMSampleBufferDataIsReady(sample) may be here this should be CMSampleBufferDataIsReady(sampleBuffer) – manishg Feb 05 '17 at 02:57
  • I got your code to work, but it did not fully fix the problem. Is there something else that is wrong? – Mike Schmidt Feb 05 '17 at 04:02
  • The white frame is gone for the first recording, but for the consecutive ones it still appears – Mike Schmidt Feb 05 '17 at 04:05
  • 1
    The basic concept is the following: when you call startTime, it tells the muxer to prepare the file with pts (presentation time stamp). Then the muxer expects frames with timestamp after that and it writes on the file as per the timestamp. So let's say you told muxer to start at 1st second and you wrote a video frame at 3rd second then for 1-3 seconds, the video will be blank. Instead if you told muxer to start at 3rd second and start writing the video at 3rd second, the video won't be blank. – manishg Feb 05 '17 at 04:11
  • Almost, the first recording works perfect, but the other ones have just a slight pause, but I think it is because of a gap between when I start and stop recording – Mike Schmidt Feb 05 '17 at 17:34
  • I am not sure how to fix that part of it – Mike Schmidt Feb 05 '17 at 17:34