Как заставить AVPlayer перерисовать текущее AVItem videoComposition при паузе - PullRequest
0 голосов
/ 15 сентября 2018

Я создаю простой видеоредактор для macOS: файл фильма загружается как AVAsset, преобразуется серией CIF-фильтров в AVVideoComposition и воспроизводится AVPlayer. Я представляю элементы управления пользовательского интерфейса для некоторых параметров фильтров CIF.

Когда воспроизводится видео, все работает отлично, я двигаю ползунки и меняю эффекты! Но когда видео приостановлено, AVPlayerView не перерисовывается после изменения элементов управления в пользовательском интерфейсе.

Как я могу побудить AVPlayerView перерисовать содержимое видеокомпозиции текущего элемента, когда он приостановлен?

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 Ответ

0 голосов
/ 17 сентября 2018

Оказывается, переустановка свойства videoComposition AVPlayerItem приведет к перерисовке элемента. Это работает, даже если вы установите для свойства его текущее значение: item.videoComposition = item.videoComposition. Установщик свойства, по-видимому, имеет недокументированные побочные эффекты.

Чтобы исправить пример кода выше, сделайте это:

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

Надеюсь, кто-то найдет это полезным!

...