Search code examples
gpuimage

GPUImageMovieWriter - black frame caused by audioEncodingTarget


I'm trying to record video using the GPUImage library. The recorded clip ends with a black frame. I know that is caused by audioEncodingTarget that is a very expensive operation. This has been discussed a lot, but i still don't find a solution. Here is my code:

GPUCameraRecorder class init

    videoCamera = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPresetiFrame960x540, cameraPosition: .Back)
    videoCamera.outputImageOrientation = .LandscapeRight;
    videoCamera.horizontallyMirrorFrontFacingCamera = true

    filter = GPUImageFilter()
    videoCamera.addTarget(filter)

    view = GPUImageView(frame: frame)
    view.fillMode = kGPUImageFillModePreserveAspectRatioAndFill

    movieWriter = GPUImageMovieWriter(movieURL: output, size: view.frame.size)
    movieWriter?.encodingLiveVideo = true

    filter?.addTarget(movieWriter!)
    filter?.addTarget(view as GPUImageView)

    videoCamera.audioEncodingTarget = self.movieWriter!
    videoCamera.startCameraCapture()

start recording function

func startRecording(){
    println("Start recording.")
    recording = true

    dispatch_async(dispatch_get_main_queue()) {
        var res = self.videoCamera.addAudioInputsAndOutputs()
        println(res)

        self.movieWriter!.startRecording()            
    }
}

end recording function

func stopRecording(){
    println("Recording end.")

    dispatch_async(dispatch_get_main_queue()) {            
        self.filter?.removeTarget(self.movieWriter!)
        self.videoCamera.audioEncodingTarget = nil
        self.movieWriter!.finishRecording()

        self.putTorchOff()
        self.delegate?.recordingEnd()

        println("completed")
    }
 }

Any suggestion? Someone have find a way to make it work without black frames?


Solution

  • Did you try this ?

    Inside GPUImageMovieWriter.m add code:

    static BOOL allowWriteAudio = NO;
    
    - (void)startRecording;
    {
      ...
      allowWriteAudio = NO;
    }
    
    - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer;
    {
      if (!allowWriteAudio) {
        return;
      }
      ...
    }
    
    - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
    {
      ...
      if (![assetWriterPixelBufferInput appendPixelBuffer:pixel_buffer withPresentationTime:frameTime])
        NSLog(@"Problem appending pixel buffer at time: %@", CFBridgingRelease(CMTimeCopyDescription(kCFAllocatorDefault, frameTime)));
    
      allowWriteAudio = YES;   //< add this
      ...
    }
    

    https://github.com/BradLarson/GPUImage/issues/1255