I'm using GPUImage in my application and trying to filter video. Live video filtering is working well. The trouble comes up when I try to read a video into memory from the filesystem and apply filters using the code posted on the sunsetlakessoftware tutorial page and in the SimpleVideoFileFilter demo.
EDIT: I realized that my original post may not have been posing a specific enough question. What I am asking is: How exactly can I read a video from disk into memory, apply a GPUImageFilter, and then overwrite the original with the filtered version?
The application is crashing with the following error:
-[AVAssetWriter startWriting] Cannot call method when status is 2
status 2 is AVAssetWriterStatusCompleted
. I've seen the same failure occur with all three other AVAssetWriterStatus
es.
I have posted the relevant code below.
GPUImageFilter *selectedFilter = [self.allFilters objectAtIndex:indexPath.item];
// get the file url I stored when the video was initially captured
NSURL *url = [self.videoURLsByIndexPath objectForKey:self.indexPathForDisplayedImage];
GPUImageMovie *movieFile = [[GPUImageMovie alloc] initWithURL:url];
movieFile.runBenchmark = YES;
movieFile.playAtActualSpeed = NO;
[movieFile addTarget:selectedFilter]; // apply the user-selected filter to the file
unlink([url.absoluteString UTF8String]); // delete the file that was at that file URL so it's writeable
// A different movie writer than the one I was using for live video capture.
GPUImageMovieWriter *editingMovieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:url size:CGSizeMake(640.0, 640.0)];
[selectedFilter addTarget:editingMovieWriter];
editingMovieWriter.shouldPassthroughAudio = YES;
movieFile.audioEncodingTarget = editingMovieWriter;
[movieFile enableSynchronizedEncodingUsingMovieWriter:editingMovieWriter];
[editingMovieWriter startRecording];
[movieFile startProcessing]; // Commenting out this line prevents crash
// weak variables to prevent retain cycle
__weak GPUImageMovieWriter *weakWriter = editingMovieWriter;
__weak id weakSelf = self;
[editingMovieWriter setCompletionBlock:^{
[selectedFilter removeTarget:weakWriter];
[weakWriter finishRecording];
[weakSelf savePhotosToLibrary]; // use ALAssetsLibrary to write to camera roll
}];
Perhaps my issue is with the scope of the editingMovieWriter. Or perhaps the fact that I am initializing a GPUImageMovie instance with the same URL that I am attempting to write to. I have read several posts on the issues page of the GPUImage github, several related posts on SO, the readme, and the tutorial linked above.
Any insight into this issue would be greatly appreciated. Thanks.