包装 AVPlayer 行为时处理 AVPlayerLayer
Handling AVPlayerLayer when wrapping AVPlayer behaviour
我正在尝试将 AVPlayer
包装在我自己的 class 中,以便我可以提供更好的 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
不必透露其底层播放器?还是我采取了错误的方法?
非常感谢任何指导!
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)
}
}
我相信您的观点不需要 getter - 在我的实践中我没有使用过它。但是如果你这样做,你可以用一个关联的对象来做,但它比真正的要慢得多 属性 我建议你只在特殊情况下使用这种方法。
我正在尝试将 AVPlayer
包装在我自己的 class 中,以便我可以提供更好的 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
不必透露其底层播放器?还是我采取了错误的方法?
非常感谢任何指导!
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)
}
}
我相信您的观点不需要 getter - 在我的实践中我没有使用过它。但是如果你这样做,你可以用一个关联的对象来做,但它比真正的要慢得多 属性 我建议你只在特殊情况下使用这种方法。