包装 AVPlayer 行为时处理 AVPlayerLayer

Posted

技术标签:

【中文标题】包装 AVPlayer 行为时处理 AVPlayerLayer【英文标题】:Handling AVPlayerLayer when wrapping AVPlayer behaviour 【发布时间】: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 不必透露其潜在玩家?还是我采取了错误的方法?

非常感谢任何指导!

【问题讨论】:

【参考方案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 被用来通过扩展来实现这一点!非常感谢

以上是关于包装 AVPlayer 行为时处理 AVPlayerLayer的主要内容,如果未能解决你的问题,请参考以下文章

AVPlayer seekToTime:循环播放短视频时性能不佳

使用 MPMediaItems 播放歌曲时 MPMediaItemPropertyAssetURL 变为 null

包装接口--模块化起步

如何正确处理 AVPlayer HTTP 错误?

带有 HLS 冗余流和不良网络的奇怪 AVPlayer 行为

当应用程序进入后台时,AVPlayer 和 addPeriodicTimeObserverForInterval 不起作用