Ios 将CIFilters切换到视频
有人能帮我理解在不重新启动视频播放器的情况下切换CIFilters的正确方法吗 我有一个本地视频在视图中播放。如果在“收藏”视图中点击某个单元格,视频将更改CIFilter 我的代码Ios 将CIFilters切换到视频,ios,video,swift5,cifilter,avvideocomposition,Ios,Video,Swift5,Cifilter,Avvideocomposition,有人能帮我理解在不重新启动视频播放器的情况下切换CIFilters的正确方法吗 我有一个本地视频在视图中播放。如果在“收藏”视图中点击某个单元格,视频将更改CIFilter 我的代码 let filter = CIFilter(name: "CIPhotoEffectNoir")! let asset = AVAsset(url: fooURL) let item = AVPlayerItem(asset: asset) item.videoComposition = AVVideoCompos
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()
代码运行良好,效果正确
但我有一个集合视图,有很多过滤器。
点击某个单元格时,我无法找到切换与视频相关的过滤器的方法。
如果我用新的过滤器重新创建一个新的播放器,并将其作为当前“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"
}
}
在不重新启动视频的情况下,将CIFilters更改为播放视频的最佳方法是什么
是否可以使用新的过滤器保存视频
谢谢 创建
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
即可轻松更改过滤器
(不过,您可能希望同步对筛选器的访问,以避免并发问题。)创建
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
即可轻松更改过滤器
(不过,您可能希望同步对筛选器的访问,以避免并发问题。)效果很好!!谢谢为了保存结果,我尝试使用AVMutableComposition作为AVPlayerItem的资产。。。。正确的方法是什么?要导出,最好使用
AVAssetExportSession
。它还可以使用AVVideoComposition
,并将视频写入您指定的文件URL。我尝试将asset(让asset=AVAsset(URL:fooURL))传递给avassetxportsession。新视频保存正确,但不带过滤器。有什么想法吗?我使用let exporter=AVAssetExportSession(资产:资产!预设名称:AVAssetExportPresetHighestQuality)。谢谢你,弗兰克!!!您还必须设置导出会话的videoComposition
,就像您对播放器项目所做的那样。非常好!!谢谢为了保存结果,我尝试使用AVMutableComposition作为AVPlayerItem的资产。。。。正确的方法是什么?要导出,最好使用AVAssetExportSession
。它还可以使用AVVideoComposition
,并将视频写入您指定的文件URL。我尝试将asset(让asset=AVAsset(URL:fooURL))传递给avassetxportsession。新视频保存正确,但不带过滤器。有什么想法吗?我使用let exporter=AVAssetExportSession(资产:资产!预设名称:AVAssetExportPresetHighestQuality)。谢谢你,弗兰克!!!您还必须设置导出会话的视频合成
,就像您对播放器项目所做的那样。