暂停时如何使AVPlayer重绘当前的AVItem videoComposition [英] How to get AVPlayer to redraw current AVItem videoComposition when paused
问题描述
我正在为macOS构建一个简单的视频编辑器:将电影文件作为AVAset加载,由AVVideoComposition中的一系列CIFilter转换,然后由AVPlayer播放.我为CIFilter的某些参数提供了UI控件.
I'm building a simple video editor for macOS: A movie file is loaded as an AVAsset, transformed by a series of CIFilters in a AVVideoComposition, and played by an AVPlayer. I present UI controls for some of the parameters of the CIFilters.
在播放视频时,一切正常,我滑动滑块,效果发生变化!但是,当视频暂停时,更改UI中的控件后,AVPlayerView不会重绘.
When video is playing everything is working great, I slide sliders and effects change! But when the video is paused the AVPlayerView doesn't redraw after the controls in the UI are changed.
我如何鼓励AVPlayerView暂停时重新绘制其当前项目的videoComposition的内容?
How can I encourage the AVPlayerView to redraw the contents of the videoComposition of it's current item when it's paused?
class ViewController: NSViewController {
@objc @IBAction func openDocument(_ file: Any) { ... }
@IBOutlet weak var moviePlayerView: AVPlayerView!
var ciContext:CIContext? = CIContext(mtlDevice: MTLCreateSystemDefaultDevice()!)
var sliderValue: Double = 0.0
@IBAction func sliderMoved(_ sender: NSSlider) {
self.sliderValue = sender.doubleValue
// need to update the view here when paused
self.moviePlayerView.setNeedsDisplay(self.moviePlayerView.bounds)
// setNeedsDisplay has no effect.
}
func loadMovie(file: URL) {
let avMovie = AVMovie(url: file)
let avPlayerItem = AVPlayerItem(asset: avMovie)
avPlayerItem.videoComposition = AVVideoComposition(asset: avMovie) { request in
let output = request.sourceImage.applyingGaussianBlur(sigma: self.sliderValue)
request.finish(with: output, context: self.ciContext)
}
self.moviePlayerView.player = AVPlayer(playerItem: avPlayerItem)
}
}
推荐答案
事实证明,重新设置AVPlayerItem的videoComposition
属性将触发该项目重新绘制.即使将属性设置为其当前值,该方法也起作用:item.videoComposition = item.videoComposition
.该属性设置器似乎具有未记录的副作用.
It turns out re-setting the AVPlayerItem's videoComposition
property will trigger the item to redraw. This works even if you set the property to it's current value: item.videoComposition = item.videoComposition
. The property setter appears to have undocumented side effects.
要修复上面的示例代码,请执行以下操作:
To fix the sample code above, do this:
@IBAction func sliderMoved(_ sender: NSSlider) {
self.sliderValue = sender.doubleValue
// update the view when paused
if self.moviePlayerView.player?.rate == 0.0 {
self.moviePlayerView.player?.currentItem?.videoComposition = self.moviePlayerView.player?.currentItem?.videoComposition
}
}
希望有人发现这很有用!
Hopefully someone finds this useful!
这篇关于暂停时如何使AVPlayer重绘当前的AVItem videoComposition的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!