How to get AVPlayer to redraw current AVItem videoComposition when paused

会有一股神秘感。 提交于 2019-12-11 00:27:29

问题


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.

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.

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)
    }
}

回答1:


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!



来源:https://stackoverflow.com/questions/52339414/how-to-get-avplayer-to-redraw-current-avitem-videocomposition-when-paused

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!