【问题标题】:Handling AVPlayerLayer when wrapping AVPlayer behaviour包装 AVPlayer 行为时处理 AVPlayerLayer
【发布时间】:2020-05-26 11:05:48
【问题描述】:

我正在尝试将 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 显示给 PlayerView 上的 player 属性,这违背了我的目的包裹播放器。

有没有办法让我以某种方式使用AVPlayerLayer 而我的AVPlayerWrapped 不必透露其潜在玩家?还是我采取了错误的方法?

非常感谢任何指导!

【问题讨论】:

    标签: ios swift avfoundation avplayer


    【解决方案1】:
    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)
        }
    }
    

    我相信您的视图不需要吸气剂 - 在我的实践中我没有使用它。但是如果你这样做了,你可以用一个 associatedObject 来做,但它比一个真实的属性慢得多,我建议你只在特殊情况下使用这种方法。

    【讨论】:

    • 太棒了 - 我没想到 fileprivate 被用来通过扩展来实现这一点!非常感谢
    猜你喜欢
    • 2015-10-02
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    相关资源
    最近更新 更多