我想知道是否可以检测播放控件何时从AVPlayerViewController视图中出现或消失。我试图在播放器上添加一个UI元素,它必须跟随播放控件显示。仅在显示控件时出现,否则消失我似乎没有找到任何价值,我可以观察到AVPlayerViewController实现这一点,也没有任何回调或委托方法。我的项目在Swift中。
tquggr8v1#
观察和响应播放变化的一种简单方法是使用键值观察(KVO)。在您的情况下,请观察AVPlayer的timeControlStatus或rate属性。例如:
timeControlStatus
rate
{ // 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值更改时,就会调用此方法。
-observeValueForKeyPath:ofObject:change:context:
// 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:
-dealloc
[playerViewController.player removeObserver:self forKeyPath:@"timeControlStatus"];
顺便说一下,你也可以观察AVPlayer的rate属性,导致-play相当于将rate的值设置为1.0,而-pause相当于将rate的值设置为0.0。但在你的情况下,我认为timeControlStatus更有意义。有一个官方的DOC供进一步阅读(但只是“准备玩”,“失败”和“未知”状态,在这里无用):"Responding to Playback State Changes"。希望有帮助。
-play
-pause
hivapdat2#
设法找到一些工作(至少对iOS)的基础上对另一个职位的评论。它可能不适用于所有平台,可能不适用于所有平台。创建一个AVPlayerViewController子类,并在它的一个子视图上设置一个观察器,检查hidden属性的更改。试图以一种避免显式使用任何标记为私有的东西的方式来避免任何应用程序商店问题。下面的代码为任何人寻找同样的,请让我知道,如果你发现任何更好的
import AVKit protocol CustomAVPlayerViewControllerDelegate: AnyObject { func playbackControlsChanged(visible: Bool) } class CustomAVPlayerViewController: AVPlayerViewController { private var viewToMonitor: UIView? = nil private var previousValue = true public weak var customDelegate: CustomAVPlayerViewControllerDelegate? = nil override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) let container = view.subviews.first viewToMonitor = container?.subviews.last previousValue = viewToMonitor?.isHidden ?? true viewToMonitor?.addObserver(self, forKeyPath: "hidden", context: nil) } deinit { viewToMonitor?.removeObserver(self, forKeyPath: "hidden") } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { // Check if its the correct element and avoid double trigger if keyPath == "hidden", let v = viewToMonitor, previousValue != v.isHidden { previousValue = v.isHidden customDelegate?.playbackControlsChanged(visible: !v.isHidden) } } }
2条答案
按热度按时间tquggr8v1#
观察和响应播放变化的一种简单方法是使用键值观察(KVO)。在您的情况下,请观察AVPlayer的
timeControlStatus
或rate
属性。例如:
要获得状态更改的通知,需要实现
-observeValueForKeyPath:ofObject:change:context:
方法。每当timeControlStatus
值更改时,就会调用此方法。最后一个最重要的步骤,当你不再需要观察者时,记得删除它,一般在
-dealloc
:顺便说一下,你也可以观察AVPlayer的
rate
属性,导致-play
相当于将rate的值设置为1.0,而-pause
相当于将rate的值设置为0.0。但在你的情况下,我认为
timeControlStatus
更有意义。有一个官方的DOC供进一步阅读(但只是“准备玩”,“失败”和“未知”状态,在这里无用):"Responding to Playback State Changes"。
希望有帮助。
hivapdat2#
设法找到一些工作(至少对iOS)的基础上对另一个职位的评论。它可能不适用于所有平台,可能不适用于所有平台。
创建一个AVPlayerViewController子类,并在它的一个子视图上设置一个观察器,检查hidden属性的更改。试图以一种避免显式使用任何标记为私有的东西的方式来避免任何应用程序商店问题。下面的代码为任何人寻找同样的,请让我知道,如果你发现任何更好的