GPUImage滤镜视频

13

这是关于之前但只有较小关联的问题的跟进。

我正在使用GPUImage库在我的相机应用中对静态照片和视频应用滤镜。几乎一切都很好地运作。我无法解决的一个剩余问题如下:

  1. 我捕获一个GPUImageMovie。
  2. 我将它写入文件系统。
  3. 我从文件系统中读取它并应用新的滤镜。
  4. 我将它写入到文件系统中的不同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];
            });
        }];
    }];
}

根据这个线程 https://github.com/BradLarson/GPUImage/issues/1321 ,看起来在 'endProcessing' 方法的实现上可能存在问题。 - chathuram
1个回答

2
我在此为未来的访客发布一个“答案”。我的代码现在可以工作了,但事实上我不确定是什么导致了这个差异。我不希望以上代码对任何人造成误导。问题可能在我的代码库中的其他地方。然而,我想提到问题中发布的方法和我的工作代码之间的区别。
  1. 我简化了控制器的结构,使其一次只处理一个媒体项。不再使用videoURLsByIndexPath,我只有self.mediaItem。这显然使组织更加可管理。我还怀疑,在电影编写器的完成块内为movieURL添加条目可能与我看到的意外结果有关。
  2. movieWriter现在是一个强引用属性,而不是一个ivar。据我所知,这不应该有影响,因为ivars默认为强引用。尽管如此,这是发布的代码和我的工作代码之间的差异。
  3. 几乎肯定不相关,但我确实在self.editedMovie.audioEncodingTarget = self.movieWriter周围放置了if-else,以检查[self.mediaItem tracksWithType:AVMediaTypeAudio]的计数是否大于0。
  4. 由于不再需要维护视频URL字典,我只需调用self.mediaItem = [AVURLAsset assetWithURL:movieURL];。我在电影编写器的完成块之外这样做。
我感觉这不是最有价值的答案,但我希望我提到的这些要点能够证明有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接