AVPlayerViewController 上的 tvOS PlayPause 按钮点击手势

tvOS PlayPause button tap gesture on AVPlayerViewController

提问人:C0D3 提问时间:11/13/2023 最后编辑:C0D3 更新时间:11/16/2023 访问量:51

问:

这个赏金已经结束了。这个问题的答案有资格获得 +50 声望赏金。赏金宽限期将在 37 分钟后结束。C0D3 希望引起人们对这个问题的更多关注
使用 AVPlayerViewController 的要求可能没有解决方案,但我有兴趣确定或是否有人对此问题有任何其他有趣的解决方案

我为播放/暂停按钮添加了一个 tapGestureRecognizer,它适用于自定义播放器(即插入 ViewController 实例中的 AVPlayer),如下所示:

lazy var playPauseButtonTap: UITapGestureRecognizer = {
    let gesture = UITapGestureRecognizer(target: self, action: #selector(playPauseTapped))
    gesture.allowedPressTypes = [NSNumber(value: UIPress.PressType.playPause.rawValue)]
    return gesture
}()

@objc private func playPauseTapped() {
    print("HELLO PLAY PAUSE TAPPED")
    togglePlayPause()
}
private func togglePlayPause() {
    switch avPlayer.timeControlStatus {
    case .playing:
        avPlayer.pause()
    case .paused:
        avPlayer.play()
    case .waitingToPlayAtSpecifiedRate:
        break
    @unknown default:
        break
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    let playerLayer = AVPlayerLayer(player: avPlayer)
    playerLayer.frame = self.view.bounds
    self.view.layer.addSublayer(playerLayer)
    avPlayer.play()

    self.view.addGestureRecognizer(playPauseButtonTap)
}

这行得通!但是,当在继承自 AVPlayerViewController 的类上运行相同的代码时(我们插入 AVPlayerLayer 的部分除外,因为 AVPlayerViewController 处理该部分),当点击按钮暂停时,手势识别器代码不会被调用,当点击按钮播放/恢复时,它确实被调用。

我需要知道用户何时暂停播放。有没有办法使用 AVPlayerViewController 让它工作?

我不想做 swizzling 或使用任何私有 API,因为 Apple 不会掉以轻心,但是,我很想知道是否有人以这种方式使用一些 hacky 解决方案让它工作。

注意:我还发现您是否有此调用:在您的应用程序中,这会使手势识别器完全忽略播放/暂停按钮点击。UIApplication.shared.beginReceivingRemoteControlEvents()

提前致谢。

Swift avfoundation tvos avplayerviewcontroller

评论

0赞 Gordon Childs 11/22/2023
也许会给你足够的信息。 可能与播放/暂停点击相关。注意:我相信这只是一个增强的 KVOAVPlayerRateDidChangeNotificationAVPlayerRateDidChangeReasonKeyAVPlayerRateDidChangeReasonSetRateCalledAVPlayer.rate
0赞 C0D3 12/10/2023
哦,这是一个有趣的想法。我会试一试并报告!非常感谢。如果它有效,我会把赏金放回去,你可以把它:)

答:

1赞 iUrii 11/16/2023 #1

如果要跟踪,则应使用键值观察来观察它,而不是处理手势等,因为AVPlayerViewController还有其他按钮。timeControlStatusAVPlayer

import AVKit

let observer: NSKeyValueObservation?

let url = URL(string: "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8")!
let player = AVPlayer(url: url)
player.play()

let playerController = AVPlayerViewController()
playerController.player = player

observer = player.observe(\.timeControlStatus, options: [.new]) { player, change in
  switch player.timeControlStatus {
    case .paused:
      print("paused")

    case .playing:
      print("playing")
      
    case .waitingToPlayAtSpecifiedRate:
      print("waitingToPlayAtSpecifiedRate")
      
    @unknown default:
      break
  }
}

PlaygroundPage.current.liveView = playerController
PlaygroundPage.current.needsIndefiniteExecution = true

注意:变量必须存储在控制器上的任何位置或全局存储。observer

评论

0赞 C0D3 11/20/2023
谢谢,实际上是的,我也想到了一个观察者,但就我而言,这是行不通的。我基本上是想具体知道用户何时使用播放/暂停按钮来展示广告。如果他们不使用播放/暂停或中键点击暂停,我不想展示广告。这就是原因。内容暂停的另一种方式是用户按住向左/向右箭头进行擦除。在这种情况下也不想展示广告。谢谢你的想法和帮助。