有人可以帮助我了解在不重新启动视频播放器的情况下切换CIFilter的正确方法吗?
我在视图中播放本地视频。如果在集合视图中点击一个单元格,视频将更改CIFilter。
我的代码
let filter = CIFilter(name: "CIPhotoEffectNoir")!
let asset = AVAsset(url: fooURL)
let item = AVPlayerItem(asset: asset)
item.videoComposition = AVVideoComposition(asset: asset, applyingCIFiltersWithHandler: { request in
let source = request.sourceImage.clampedToExtent()
filter.setValue(source, forKey: kCIInputImageKey)
let output = filter.outputImage
request.finish(with: output!, context: nil)
})
player = AVPlayer(playerItem: item)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = videoViewDetail.bounds
videoViewDetail.layer.addSublayer(playerLayer)
player?.play()
代码效果很好,效果正确
但是我有很多CIFilters的collectionview。点击一个单元格,我找不到切换与视频关联的过滤器的方法。如果我使用新的过滤器重新创建新的播放器,并将其添加为当前“ addsublayer”的替代者,则播放器将重新启动视频。
@IBAction func tap(_ sender: UITapGestureRecognizer) {
let location = sender.location(in: self.collectionView)
let indexPath = self.collectionView.indexPathForItem(at: location)
if let index = indexPath {
// code to switch to another CIFilter like for example "CISepiaTone"
}
}
在不重新启动视频的情况下将CIFilter更改为正在播放的视频的最佳方法是什么?是否可以使用新的过滤器保存视频?
谢谢!
创建AVVideoComposition
播放器时提供的处理程序块会针对播放器显示的每个视频帧连续调用。这意味着您只需要切换该块内部使用的过滤器。
最简单的方法是从块外部引用过滤器,而不是捕获它。然后,您可以在运行时更改引用。
例如,假设您的代码在某个视图控制器方法中运行,则可以执行以下操作:
class MyViewController: UIViewController {
var filter: CIFilter = CIFilter(name: "CIPhotoEffectNoir")!
func createPlayer() {
let asset = AVAsset(url: fooURL)
let item = AVPlayerItem(asset: asset)
item.videoComposition = AVVideoComposition(asset: asset, applyingCIFiltersWithHandler: { [weak self] request in
guard let self = self else {
request.finish(with error: SomeError)
return
}
let source = request.sourceImage.clampedToExtent()
self.filter.setValue(source, forKey: kCIInputImageKey)
let output = self.filter.outputImage
request.finish(with: output!, context: nil)
})
player = AVPlayer(playerItem: item)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = videoViewDetail.bounds
videoViewDetail.layer.addSublayer(playerLayer)
player?.play()
}
// ...
}
然后,您只需更改即可轻松更改过滤器self.filter
。
(不过,您可能希望同步对过滤器的访问,以避免并发问题。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句