ios - 有没有更好的方法来观察键值变化?

标签 ios swift video avfoundation avqueueplayer

我想知道以下是否真的是了解视频何时准备好播放的最佳方法:目前我所做的是 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 invokes observeValue(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/

相关文章:

ios - CIColorMatrix 数学没有意义

ios - 内部带有 UITextView 的自定义 UITableViewCell 不可使用 layoutsubviews 进行编辑

ios - SpriteKit 场景图像在模拟器上显示为红十字

ios - 取消或中断 SKAction.moveTo (Swift)

arrays - 如何使用 Swift 将 json 数据添加到数组或类似数据

ios - 如何覆盖 reloadRowsAtIndexPaths?

swift - 以快速奇怪的行为将函数分配给变量

c# - 从一组图像中创建视频

java - 如何将 BufferedImage 转换为 AVI?

android - 使用 Ffmpeg 的多图像交叉淡入淡出动画