GPUImage过滤视频

ger*_*iam 13 ios gpuimage

这是对先前但只有轻微相关问题的后续行动

我正在使用GPUImage库将滤镜应用到我的相机应用中的静态照片和视频.几乎所有东西都运转良好.我无法解决的另一个问题如下:

  1. 我捕获了一个GPUImageMovie
  2. 我把它写到文件系统
  3. 我从文件系统中读取它并应用新的过滤器
  4. 我将它写入文件系统中的不同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];
            });
        }];
    }];
}
Run Code Online (Sandbox Code Playgroud)

ger*_*iam 2

我正在为未来的访客发布这个问题的“答案”。我的代码现在可以工作,但事实是我不确定是什么造成了差异。我不希望上面的代码成为任何人的干扰。问题可能出在我的代码库的其他地方。但是,我想提及问题中发布的方法与我的工作代码中的方法之间的差异。

  1. 我简化了控制器的结构,因此它一次只处理一个媒体项。不再有 videoURLsByIndexPath,我只有 self.mediaItem。显然,这使得组织更加易于管理。我还怀疑将 movieURL 的条目添加到电影编写器的完成块内的字典中可能与我看到的意外结果有关。

  2. movieWriter 现在是一个强大的属性,而不是 ivar。AFAIK这应该不重要,因为 ivars 默认为强引用。然而,这里发布的内容和我的工作代码之间存在差异。

  3. 几乎可以肯定不相关,但我确实放置了一个 if-else 来self.editedMovie.audioEncodingTarget = self.movieWriter检查 的计数是否[self.mediaItem tracksWithType:AVMediaTypeAudio]大于 0。

  4. 由于不再需要维护视频 URL 字典,因此我只需调用self.mediaItem = [AVURLAsset assetWithURL:movieURL];. 我在电影编剧的完成区之外进行此操作。

我觉得这不是最有价值的答案,但我希望我在这里提到的观点是有用的。