我想知道以下是否真的是了解视频何时准备好播放的最佳方法:目前我所做的是 if currentMedia.playerQueue?.status.rawValue == 1 {
I播放,else
(视频尚未加载)我将显示加载图标,然后执行以下操作来观察视频何时准备好播放:
我使用相同的视频 url 创建一个 AVPlayer,然后当它准备好时,我将调用 playCurentMedia() 方法来播放视频。
currentMedia.avPlayer = AVPlayer(url: currentMedia.videoURL!)
currentMedia.avPlayer!.addObserver(self, forKeyPath: "status", options: [.new, .initial], context: &P2SheetViewController.playerStatusContext)
这个策略有什么缺陷吗?或者这是一个好的解决方案吗?
然后我如何观察变化,以便在视频准备好时显示视频?
目前,我只能在队列旁边设置一个AVPlayer,以便我可以观察它的变化...
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("observe KVO")
// Only handle observations for the playerItemContext
guard context == &P2SheetViewController.playerStatusContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
if keyPath == #keyPath(AVPlayer.status) {
let status: AVPlayer.Status
if let statusNumber = change?[.newKey] as? NSNumber {
status = AVPlayer.Status(rawValue: statusNumber.intValue)!
} else {
status = .unknown
}
//Switch over status value
switch status {
case .readyToPlay:
print("READY TO PLAY")
GlobalSharedData.shared.videoAllSetToGoMedia1 = true
if GlobalSharedData.shared.p2Media1VideoWasNotReadyWhenPressedView {
baseVC.playVideoControlForP2()
}
break
// Player item is ready to play.
case .failed:
print(".UKNOWN")
break
// Player item failed. See error.
case .unknown:
print(".UKNOWN")
break
// Player item is not yet ready.
}
}
}
最佳答案
据官方AVPlayer文档中,您可以使用两种方法来观察玩家的状态:
General State Observations: You can use Key-value observing (KVO) to observe state changes to many of the player’s dynamic properties, such as its
currentItem
or its playback rate. You should register and unregister for KVO change notifications on the main thread. This avoids the possibility of receiving a partial notification when making a change on another thread. AVFoundation invokesobserveValue(forKeyPath:of:change:context:)
on the main thread, even when making the change operation on another thread.Timed State Observations: KVO works well for general state observations, but isn’t intended for observing continuously changing state like the player’s time. AVPlayer provides two methods to observe time changes:
addPeriodicTimeObserver(forInterval:queue:using:)
addBoundaryTimeObserver(forTimes:queue:using:)
These methods let you observe time changes either periodically or by boundary, respectively. As changes occur, invoke the callback block or closure you supply to these methods to give you the opportunity to take some action such as updating the state of your player’s user interface.
另请参阅AVPlayer status property注意:
The player’s status does not indicate its readiness to play a specific player item. You should instead use the status property of
AVPlayerItem
to make that determination.
因此,如果您想知道特定视频何时加载并准备好播放,您应该创建 AVPlayerItem
并观察其 status
属性。当播放器项目的媒体已加载并可供使用时,其状态将更改为 AVPlayerItem.Status.readyToPlay
。
关于ios - 有没有更好的方法来观察键值变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56843375/