包装 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
带有 HLS 冗余流和不良网络的奇怪 AVPlayer 行为
当应用程序进入后台时,AVPlayer 和 addPeriodicTimeObserverForInterval 不起作用