我正在使用GPUImage库来应用过滤器到我的相机应用程序中的静态照片和视频.几乎一切都很好.我还没有解决的其余一个问题如下:
>我捕获一个GPUImageMovie
>我把它写入文件系统
>我从文件系统读取它并应用一个新的过滤器
>我将其写入文件系统中的其他URL
保存到该新URL的是具有正确持续时间但没有移动的视频.当我打的时候,它只是静止的图像,我认为视频的第一帧.只要我将任何过滤器应用于从文件系统检索到的视频,就会发生这种情况.将过滤器应用于现场录制视频工作正常.我的代码如下
任何人都可以告诉我如何修改此内容以保存整个原始视频并应用过滤器?
- (void)applyProcessingToVideoAtIndexPath:(NSIndexPath *)indexPath withFilter:(GPUImageFilter *)selectedFilter { NSArray *urls = [self.videoURLsByIndexPaths objectForKey:self.indexPathForDisplayedImage]; NSURL *url = [urls lastObject]; self.editedMovie = [[GPUImageMovie alloc] initWithURL:url]; assert(!!self.editedMovie); [self.editedMovie addTarget:selectedFilter]; // apply the user-selected filter to the file NSURL *movieURL = [self generatedMovieURL]; // A different movie writer than the one I was using for live video capture. movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640.0,640.0)]; [selectedFilter addTarget:movieWriter]; movieWriter.shouldPassthroughAudio = YES; self.editedMovie.audioEncodingTarget = movieWriter; [self.editedMovie enableSynchronizedEncodingUsingMovieWriter:movieWriter]; [movieWriter startRecording]; [self.editedMovie startProcessing]; __weak GPUImageMovieWriter *weakWriter = movieWriter; __weak CreateContentViewController *weakSelf = self; [movieWriter setCompletionBlock:^{ [selectedFilter removeTarget:weakWriter]; [weakWriter finishRecordingWithCompletionHandler:^{ NSArray *urls = [weakSelf.videoURLsByIndexPaths objectForKey:weakSelf.indexPathForDisplayedImage]; urls = [urls arrayByAddingObject:movieURL]; NSMutableDictionary *mutableVideoURLs = [weakSelf.videoURLsByIndexPaths mutableCopy]; [mutableVideoURLs setObject:urls forKey:weakSelf.indexPathForDisplayedImage]; weakSelf.videoURLsByIndexPaths = mutableVideoURLs; dispatch_sync(dispatch_get_main_queue(),^{ [self.filmRoll reloadData]; [weakSelf showPlayerLayerForURL:movieURL onTopOfImageView:weakSelf.displayedImageView]; }); }]; }]; }
解决方法
>我简化了控制器的结构,因此它一次只处理一个媒体项目.没有更多的videoURLsByIndexPath,我只是有self.mediaItem.这使组织显得更加易于管理.我也怀疑在电影作家的完成程序块中为movieURL添加一个条目可能与我看到的意外结果有关.
>电影Writer现在是一个强大的财产,而不是一个ivar.这不应该是AFAIK,因为ivars默认为强引用.然而,这与发布在这里和我的工作代码之间是有区别的.
>几乎肯定是无关的,但是我确实把一个if-else放在self.editedMovie.audioEncodingTarget = self.movieWriter上,以检查[self.mediaItem tracksWithType:AVMediaTypeAudio]的计数是否大于0.
>由于不再需要维护视频网址的字典,所以我只需调用self.mediaItem = [AVURLAsset assetWithURL:movieURL] ;.我在电影作家的完成块之外做到这一点.
我觉得这不是最有价值的答案,但我希望这里提到的几点证明是有用的.