【问题标题】:How to detect the toggle on the display of playback controls with AVPlayerViewController?如何使用 AVPlayerViewController 检测播放控件显示的切换?
【发布时间】:2019-08-03 03:41:02
【问题描述】:

我想知道是否可以检测播放控件何时从 AVPlayerViewController 视图中出现或消失。 我正在尝试在我的播放器上添加一个必须遵循播放控件显示的 UI 元素。仅在控件显示时出现,否则消失

我似乎没有找到任何可以在 AVPlayerViewController 上观察到的值来实现这一点,也没有任何回调或委托方法。

我的项目使用 Swift。

【问题讨论】:

  • 目前似乎无法撤消。但是,作为一种解决方法,您可以检查:stackoverflow.com/questions/39885018/… 或者您可能需要将子视图添加到其contentOverlayView
  • 感谢您的快速回复。给 contentOverlayView 添加子视图的问题是它们总是可见的。它们不会跟随播放控件上发生的显示切换。
  • 是的,这是真的。所以您可能需要遵循我提到的问题的方法,但请记住,它与显示/隐藏播放控件不完全匹配。至少这是我们现在能做的最好的:)

标签: ios swift avplayer avplayerviewcontroller


【解决方案1】:

观察和响应播放变化的一种简单方法是使用键值观察 (KVO)。在您的情况下,请注意 AVPlayer 的 timeControlStatusrate 属性。

例如:

{
  // 1. Setup AVPlayerViewController instance (playerViewController)

  // 2. Setup AVPlayer instance & assign it to playerViewController

  // 3. Register self as an observer of the player's `timeControlStatus` property

  // 3.1. Objectice-C
  [player addObserver:self
           forKeyPath:@"timeControlStatus"
              options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew // NSKeyValueObservingOptionOld is optional here
              context:NULL];

  // 3.2. Swift
  player.addObserver(self,
                     forKeyPath: #keyPath(AVPlayer.timeControlStatus),
                     options: [.old, .new], // .old is optional here
                     context: NULL)
}

要获得状态更改通知,您需要实现-observeValueForKeyPath:ofObject:change:context: 方法。只要timeControlStatus 值发生变化,就会调用此方法。

// Objective-C
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary <NSKeyValueChangeKey, id> *)change
                       context:(void *)context
{
  if ([keyPath isEqualToString:@"timeControlStatus"]) {
    // Update your custom UI here depend on the value of `change[NSKeyValueChangeNewKey]`:
    // - AVPlayerTimeControlStatusPaused
    // - AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate
    // - AVPlayerTimeControlStatusPlaying
    AVPlayerTimeControlStatus timeControlStatus = (AVPlayerTimeControlStatus)[change[NSKeyValueChangeNewKey] integerValue];
    // ...

  } else {
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  }
}

// Swift
override func observeValue(forKeyPath keyPath: String?,
                           of object: Any?,
                           change: [NSKeyValueChangeKey : Any]?,
                           context: UnsafeMutableRawPointer?)
{
  if keyPath == #keyPath(AVPlayer.timeControlStatus) {
    // Deal w/ `change?[.newKey]`
  } else {
    super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
  }
}

最后最重要的一步,当你不再需要观察者时,记得将其移除,一般在-dealloc

[playerViewController.player removeObserver:self forKeyPath:@"timeControlStatus"];

顺便说一句,您还可以观察 AVPlayer 的 rate 属性,导致 -play 等效于将 rate 的值设置为 1.0,而 -pause 等效于将 rate 的值设置为 0.0。

但就你而言,我认为timeControlStatus 更有意义。


有一个官方文档供进一步阅读(但只是“准备播放”、“失败”和“未知”状态,在这里没用):"Responding to Playback State Changes"

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多