iOS-获取当前的AVPlayer(Item)状态

时间:2018-08-16 03:45:04

标签: ios streaming ios9 avplayer avplayeritem

我正在寻找一个明确的答案,如何在iOS 9及更高版本中获取当前的AVPlayer/AVPlayerItem状态。为了简单起见,让它们成为Google的ExoPlayer样式状态:

  • 空闲(无媒体或错误)

  • 缓冲(视频实际上不是在播放/前进和等待 更多数据)

  • 正在播放(视频实际上正在播放/前进)

  • 已完成(视频播放结束为止)

请注意,目前我不是在寻找跟踪状态变化的方法(通过通知,KVO观察或其他方式),而只是在当前时间的状态。考虑以下伪代码:

typedef enum : NSUInteger {
    PlayerStateIdle,
    PlayerStateBuffering,
    PlayerStatePlaying,
    PlayerStateCompleted
} PlayerState;

+ (PlayerState)resolvePlayerState:(AVPlayer*)player {
    // Magic code here
}

墙壁,到目前为止,我的头一直在撞:

  • timeControlStatus从iOS 10开始可用

  • playbackBufferEmpty始终为真

  • playbackBufferFull始终为假

  • 乍一看
  • loadedTimeRanges看起来很有希望,但是既没有迹象表明必须预先缓冲多少时间才能播放,也不能保证currentTime处于加载时间范围的边缘是一个摊位

2 个答案:

答案 0 :(得分:0)

根据文档

  

您可以使用键值观察来观察这些状态变化   发生。要观察的最重要的玩家物品属性之一是   它的状态。状态指示该项目是否已准备好播放和   通常可以使用。

要设置观察:

func prepareToPlay() {
    let url = <#Asset URL#>
    // Create asset to be played
    asset = AVAsset(url: url)

    let assetKeys = [
        "playable",
        "hasProtectedContent"
    ]
    // Create a new AVPlayerItem with the asset and an
    // array of asset keys to be automatically loaded
    playerItem = AVPlayerItem(asset: asset,
                              automaticallyLoadedAssetKeys: assetKeys)

    // Register as an observer of the player item's status property
    playerItem.addObserver(self,
                           forKeyPath: #keyPath(AVPlayerItem.status),
                           options: [.old, .new],
                           context: &playerItemContext)

    // Associate the player item with the player
    player = AVPlayer(playerItem: playerItem)
}

要处理:

override func observeValue(forKeyPath keyPath: String?,
                           of object: Any?,
                           change: [NSKeyValueChangeKey : Any]?,
                           context: UnsafeMutableRawPointer?) {
    // Only handle observations for the playerItemContext
    guard context == &playerItemContext else {
        super.observeValue(forKeyPath: keyPath,
                           of: object,
                           change: change,
                           context: context)
        return
    }

    if keyPath == #keyPath(AVPlayerItem.status) {
        let status: AVPlayerItemStatus

        // Get the status change from the change dictionary
        if let statusNumber = change?[.newKey] as? NSNumber {
            status = AVPlayerItemStatus(rawValue: statusNumber.intValue)!
        } else {
            status = .unknown
        }

        // Switch over the status
        switch status {
        case .readyToPlay:
        // Player item is ready to play.
        case .failed:
        // Player item failed. See error.
        case .unknown:
            // Player item is not yet ready.
        }
    }
}

答案 1 :(得分:0)

不确定您的问题是什么。

您可以仅访问player.status或player.timeControlStatus并返回与您的ENUM匹配的结果

这是您的意思吗?