Open
Description
I have recording app implementation where user can tap the "record" button to start/stop recording. I achieve this with a basic GPUImageVideoCamera with output set to a GPUImageView as well as a GPUImageMovieWriter.
50% of the time, the recorded clip ends up with a couple (or a single) black frame at either ends, sometimes both. The implementation is fairly straightforward, but here is it anyway.
gpuImageView = [[GPUImageView alloc] initWithFrame:cameraView.frame];
gpuImageView.fillMode = kGPUImageFillModePreserveAspectRatioAndFill;
[cameraView addSubview:gpuImageView];
videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:(usingBackCamera) ? AVCaptureDevicePositionBack : AVCaptureDevicePositionFront];
[videoCamera addTarget:gpuImageView];
[videoCamera addTarget:movieWriter];
videoCamera.audioEncodingTarget = movieWriter;
[videoCamera startCameraCapture];
double delayToStartRecording = 0.5;
dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, delayToStartRecording * NSEC_PER_SEC);
dispatch_after(startTime, dispatch_get_main_queue(), ^(void){
NSLog(@"Start recording");
[movieWriter startRecording];
});
And then stop the recording with the following (while the live camera continues to show up on gpuimageview.
[movieWriter finishRecording];
Has anyone else experienced this and/or found a solution to avoid black frames? I cannot pause/resume camera capture so to ensure seamless user experience.
Activity
staykids commentedon Oct 15, 2013
I've definitely encountered this issue before. It's annoying - I spent some time trying to investigate why it occurs but it's sporadic enough that I just looked to mitigate it some other way.
Here's a low-tech solution: after the movieWriter is finished recording, start an AVAssetExportSession with the newly completely video URL, chop some "buffer time" off the video, then save it back to disk. I find that removing a CMTime duration of CMTimeMake(1,10) off both the start and end of the movieWriter video removes all black frame artifacts. YMMV. I'd recommend maybe using movieWriter finishRecordingWithCompletionHandler, and then in the completion block make a call to whatever method does the "buffer time" trimming.
If you notice, Apple's stock Camera app (when taking a video) chops off a bit of time from the beginning of a video after you finish recording. I'm not saying it's necessarily because of an issue like this, but just wanted to mention it to illustrate that it can indeed be a lot of data to deal with.
I leave it to more interested minds to discover the "why" of this issue and engineer a better solution.
zakinaeem commentedon Oct 15, 2013
Thanks for your input mate - what you suggest (chopping the frames off) is definitely in for Plan B. I never noticed the chopping off on Apple's stock camera app, interesting!
Is definitely worth finding out the reason behind this behavior and a possible solution. Will continue to look into it myself.
m1entus commentedon Oct 20, 2013
videoCamera.audioEncodingTarget = movieWriter - this is your problem. It's very expensive operation.
followmyheart-Bao commentedon Nov 21, 2013
I experienced the same issue, anyone else has solution?
zmzhuai commentedon Nov 27, 2013
I think I found the reason, I look into the file GPUImageVideoCamera.m, the GPUImageVideoCamera process frames, There is a semaphore named frameRenderingSemaphore, at line 951. It will wait this semaphore, when the process is not finished,It will drop the frames. and I think GPUImage does not change CMTime of CMSampleBufferRef. I do not have some solution, To solute this problem, You may rewrite this class.
zakinaeem commentedon Dec 25, 2013
No luck with this and as much as I have tried to push it back, its quite incorrect user-experience wise to have these black frames you cannot control. Anyone with a solution, please do let know.
barrault01 commentedon Feb 12, 2014
I do have the same problem and can't resolved it.
xujingzhou commentedon Oct 7, 2014
I met the same issue. Any solution now?
KageDev commentedon Dec 26, 2014
The problem is that the audio buffer is written before the video buffer.
Fix:
Inside GPUImageMovieWriter.m
add code:
- fix for black frames as per BradLarson#1255 (comment)
protez commentedon Jul 15, 2015
Thank you so much KageDev! You're the hero.
yumincode commentedon Jan 14, 2016
hello,can anyOne help me?When i add this code,my video is silent,there is no sound, please help me...
add patch BradLarson#1255
mingyue1991 commentedon Nov 24, 2016
@KageDev e~,it can avoid the black frame at the beginning, but the black frame at the end still occur sometimes.do you know how to solve it?
jiliszc commentedon Nov 30, 2016
5c and 4s the black frame at the end still occur
15 remaining items