如何在AVVideoComposition的applyCIFiltersWithHandler中触发重绘过滤器?

Cha*_*ock 8 ios avplayer avvideocomposition cifilter swift

我正在使用Swift在视图的AVPlayerLayer中显示来自AVPlayer的内容.关联的AVPlayerItem有一个videoComposition,并且用于创建它的代码的略微简化版本(没有错误检查等)如下所示:

playerItem.videoComposition = AVVideoComposition(asset: someAsset, applyingCIFiltersWithHandler: {
                [unowned self] (request: AVAsynchronousCIImageFilteringRequest) in

    let paramDict = << set up parameter dictionary based on class vars >>

    // filter the image
    let filter = self.ciFilterWithParamDict(paramDict) {
    filter.setValue(request.sourceImage, forKey: kCIInputImageKey)
    if let filteredImage = filter.outputImage {
        request.finishWithImage(filteredImage, context: nil)
    }
})
Run Code Online (Sandbox Code Playgroud)

当AVPlayer正在播放或寻找时,这一切都按预期工作.如果创建并加载了新的videoComposition,则会正确呈现AVPlayerLayer.

但是,当我更改了用于计算滤波器参数的一些值时,我还没有找到一种方法来"触发"AVPlayer/AVPlayerItem/AVVideoComposition重新渲染.如果我更改值然后播放或搜索,则会正确呈现,但仅限于我玩或寻找.有没有办法触发"就地"渲染?

Gil*_*tre 6

我所知道的最好的方法是在暂停的 AVPlayer 上编辑 CIFilter 输入时,为 AVPlayerItem 创建一个新的 AVVideoComposition 实例。根据我的经验,这比将玩家物品换出并换回播放器更快、更干净。您可能认为创建新的视频合成很慢,但实际上您所做的只是在该特定帧重新定义渲染路径,这几乎与使受更改影响的 Core Image 缓存部分无效一样有效。

这里的关键是播放器项目的视频合成必须以某种方式无效以触发重绘。可悲的是,简单地更改核心图像过滤器的输入参数无法(据我所知)使视频合成无效,这是问题的根源。

您可以通过为 AVPlayerItem 创建 AVMutableVideoComposition 实例并在暂停编辑时以某些方式对其进行变异(通过更改指令、animationTool、frameDuration 等内容)来提高效率。


Mat*_*elf 4

我使用 hack 完全替换了 avPlayerItem 以强制刷新。但如果有办法直接触发avPlayerItem重新渲染那就更好了。

// If the video is paused, force the player to re-render the frame.
if (self.avPlayer.currentItem.asset && self.avPlayer.rate == 0) {
    CMTime currentTime = self.avPlayerItem.currentTime;

    [self.avPlayer replaceCurrentItemWithPlayerItem:nil];
    [self.avPlayer replaceCurrentItemWithPlayerItem:self.avPlayerItem];
    [self.avPlayerItem seekToTime:currentTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
}
Run Code Online (Sandbox Code Playgroud)