Обработка AVPlayerLayer при переносе поведения AVPlayer - PullRequest
2 голосов
/ 26 мая 2020

Я пытаюсь обернуть AVPlayer в свой собственный класс, чтобы я мог предоставить более приятный API для использования во всем моем приложении, и чтобы я мог имитировать поведение игрока для тестирования с другими объектами (и потому что AVPlayer KVO довольно некрасиво использовать!). Вот упрощенная модель того, что я пытаюсь сделать, используя только функции воспроизведения и паузы:

protocol VideoPlayerProtocol {
    func play()
    func pause()
}

class AVPlayerWrapped: VideoPlayerProtocol {

    private let player = AVPlayer()

    init(playerItem: AVPlayerItem) {
        self.player.replaceCurrentItem(with: playerItem)
    }

    func play() {
        player.play()
    }

    func pause() {
        player.pause()
    }
}

У меня также есть PlayerView, который добавляет AVPlayerLayer в представление. Из документов Apple это устанавливается путем предоставления представления AVPlayer:

class PlayerView: UIView {

    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    var player: AVPlayer? {
        get { playerLayer.player }
        set { playerLayer.player = newValue }
    }
}

Проблема в том, что когда я настраиваю объект AVPlayerWrapped, для отображения воспроизведения в нужном мне виде чтобы раскрыть базовый AVPlayer свойству player на PlayerView, что лишает меня смысла оборачивать игрока.

Есть ли способ каким-то образом использовать AVPlayerLayer без моего AVPlayerWrapped пожалуйста, раскрыть основного игрока? Или я придерживаюсь неправильного подхода?

Любое руководство очень ценно!

1 Ответ

1 голос
/ 29 мая 2020
class AVPlayerWrapped: VideoPlayerProtocol {

    fileprivate let player = AVPlayer()

    init(playerItem: AVPlayerItem) {
        self.player.replaceCurrentItem(with: playerItem)
    }

    func play() {
        player.play()
    }

    func pause() {
        player.pause()
    }
}

extension AVPlayerLayer {
    func setPlayerWrapper(_ playerWrapped: AVPlayerWrapped) {
        player = playerWrapped.player
    }
}

и

class PlayerView: UIView {

    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }

    var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    func setPlayerWrapper(_ playerWrapped: AVPlayerWrapped) {
        playerLayer.setPlayerWrapper(playerWrapped)
    }
}

Я считаю, что вам не нужен геттер для вашего представления - в своей практике я его не использовал. Но если вы это сделаете, вы можете сделать это с помощью связанного объекта, но это намного медленнее, чем реальная собственность, и я бы посоветовал вам использовать этот подход только в особых случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...