我正在使用Brad Larson的优秀图书馆GPUImage进行申请。目前我遇到了一个问题。我的应用程序捕获10秒视频,之后允许filter
申请。在filters
中应用GPUImageMovie
时,我无法暂停播放并应用新的filter
,以便视频可以在不从头开始的情况下连续播放。
我看到了一个开放的github问题here。如果有人遇到类似问题并找到解决方案,请发布您的答案。提前谢谢。
答案 0 :(得分:9)
最后我在经过太多搜索后尝试修复此问题。我们需要使用AVPlayerItem而不是URL来启动GPUImageMovie。我从here得到了这个有价值的线索。
我发布了我目前在我的应用程序中使用的代码,它正在按预期工作。但iPod 6.1中存在性能问题,我正在努力改进它。
设置GPUImageMovie的初始方法,
- (void)setupVideo
{
playerItem = [[AVPlayerItem alloc]initWithURL:self.recordSession.outputUrl];
player = [AVPlayer playerWithPlayerItem:playerItem];
movieFile = [[GPUImageMovie alloc] initWithPlayerItem:playerItem];
movieFile.runBenchmark = YES;
movieFile.playAtActualSpeed = YES;
[self.view sendSubviewToBack:self.videoView];
[movieFile addTarget:filter];
[filter addTarget:self.videoView];
[movieFile startProcessing];
movieRunning = YES;
dispatch_async(dispatch_get_main_queue(), ^{
self.playButton.hidden = YES;
});
player.rate = 1.0;
}
当用户点击过滤器按钮时,会调用此方法。
- (void)filterClicked:(UIButton *)button
{
// Set paused time. If player reaches end of the video, set pausedTime to 0.
if (CMTIME_COMPARE_INLINE(pausedTime, !=, player.currentItem.asset.duration)) {
pausedTime = player.currentTime;
} else {
pausedTime = CMTimeMake(0, 600.0);
}
[self.videoView setBackgroundColor:[UIColor clearColor]];
[movieFile cancelProcessing];
switch (button.tag)
{
case 0:
filter = [[GPUImageFilter alloc] init];
break;
case 1:
filter = [[GPUImageColorInvertFilter alloc] init];
break;
case 2:
filter = [[GPUImageEmbossFilter alloc] init];
break;
case 3:
filter = [[GPUImageGrayscaleFilter alloc] init];
break;
default:
filter = [[GPUImageFilter alloc] init];
break;
}
[self filterVideo];
}
生成过滤器后,此方法将处理视频播放恢复。
- (void)filterVideo {
// AVPlayerItem is initialized with required url
playerItem = [[AVPlayerItem alloc]initWithURL:self.outputUrl];
[player replaceCurrentItemWithPlayerItem:playerItem];
//GPUImageMovie is initialized with AVPlayerItem
movieFile = [[GPUImageMovie alloc] initWithPlayerItem:playerItem];
movieFile.runBenchmark = YES;
movieFile.playAtActualSpeed = YES;
// Adding targets for movieFile and filter
[movieFile addTarget:filter];
[filter addTarget:self.videoView]; // self.videoView is my GPUImageView
[movieFile startProcessing];
movieRunning = YES;
dispatch_async(dispatch_get_main_queue(), ^{
self.playButton.hidden = YES;
});
// Player rate is set to 0 means player is paused
[player setRate:0.0];
// Seeking to the point where video was paused
if (CMTIME_COMPARE_INLINE(pausedTime, !=, player.currentItem.asset.duration)) {
[player seekToTime:pausedTime];
}
[player play];
}
答案 1 :(得分:0)
对于我来说,使用AVPlayerItem
是不可行的(我使用合成)。
相反,我编写了以下代码:
class PausableGPUImageMovie: GPUImageMovie {
var isPaused = false
override func readNextVideoFrame(from readerVideoTrackOutput: AVAssetReaderOutput!) -> Bool {
while isPaused {
usleep(100_000)
}
return super.readNextVideoFrame(from: readerVideoTrackOutput)
}
}
非常垃圾,但是随时可以改善它。