如何让 AVPlayer 在暂停时重绘当前的 AVItem videoComposition
How to get AVPlayer to redraw current AVItem videoComposition when paused
我正在为 macOS 构建一个简单的视频编辑器:电影文件作为 AVAsset 加载,由 AVVideoComposition 中的一系列 CIFilter 转换,并由 AVPlayer 播放。我为 CIFilters 的一些参数提供 UI 控件。
播放视频时一切正常,我滑动滑块,效果发生变化!但是当视频暂停时,AVPlayerView 在 UI 中的控件更改后不会重绘。
我如何鼓励 AVPlayerView 在暂停时重绘其当前项的 videoComposition 的内容?
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
,这仍然有效。 属性 setter 似乎有未记录的副作用。
要修复上面的示例代码,请执行以下操作:
@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
}
}
希望有人觉得这有用!
我正在为 macOS 构建一个简单的视频编辑器:电影文件作为 AVAsset 加载,由 AVVideoComposition 中的一系列 CIFilter 转换,并由 AVPlayer 播放。我为 CIFilters 的一些参数提供 UI 控件。
播放视频时一切正常,我滑动滑块,效果发生变化!但是当视频暂停时,AVPlayerView 在 UI 中的控件更改后不会重绘。
我如何鼓励 AVPlayerView 在暂停时重绘其当前项的 videoComposition 的内容?
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
,这仍然有效。 属性 setter 似乎有未记录的副作用。
要修复上面的示例代码,请执行以下操作:
@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
}
}
希望有人觉得这有用!