GPUImage过滤视频

Posted

技术标签:

【中文标题】GPUImage过滤视频【英文标题】:GPUImage filtering video 【发布时间】:2014-04-09 20:53:18 【问题描述】:

这是对之前的一个后续但只相关的question

我正在使用 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];
            );
        ];
    ];

【问题讨论】:

好吧,根据这个线程github.com/BradLarson/GPUImage/issues/1321,似乎'endProcessing'方法实现可能存在问题。 【参考方案1】:

我正在为未来的访问者发布此问题的“答案”。我的代码现在可以工作,但事实是我不确定是什么造成了不同。我不希望上面的代码成为任何人的红鲱鱼。问题可能出在我的代码库的其他地方。但是,我想提一下问题中发布的方法与我的工作代码中的方法之间的区别。

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

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

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

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

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

【讨论】:

以上是关于GPUImage过滤视频的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GPUImage 中叠加一系列图像

初始化 The Amazing Audio Engine 后,视频录制中没有音频(使用 GPUImage)

将 GPUImage 框架添加到 IOS 项目

在 swift 中使用 GPUImage 链接过滤器

使用 GPUImage 过滤器后无法保存图像

GPUImage 查找过滤器 - 创建大于 512² 颜色的颜色深度