AVURLAsset loadValues异步永远不会失败

时间:2017-09-14 22:42:40

标签: ios avplayer avqueueplayer

我正在阅读&尝试Apple关于加载视频资产的示例代码。

但是我注意到即使我在设备上打开飞行模式或关闭我的mac上的wifi,loadValuesAsynchronously上的AVURLAsset功能也不会失败。有人知道loadValuesAsynchronously在什么情况下无法加载密钥?

这是相对sample code

asset.loadValuesAsynchronously(forKeys: PlayerViewController.assetKeysRequiredToPlay) {

    /*
        The asset invokes its completion handler on an arbitrary queue.
        To avoid multiple threads using our internal state at the same time
        we'll elect to use the main thread at all times, let's dispatch
        our handler to the main queue.
    */
    DispatchQueue.main.async() {
        /*
            This method is called when the `AVAsset` for our URL has 
            completed the loading of the values of the specified array 
            of keys.
        */

        /*
            Test whether the values of each of the keys we need have been
            successfully loaded.
        */
        for key in PlayerViewController.assetKeysRequiredToPlay {
            var error: NSError?

            if asset.statusOfValue(forKey: key, error: &error) == .failed {
                let stringFormat = NSLocalizedString("error.asset_%@_key_%@_failed.description", comment: "Can't use this AVAsset because one of it's keys failed to load")

                let message = String.localizedStringWithFormat(stringFormat, title, key)

                self.handleError(with: message, error: error)

                return
            }
        }

        // We can't play this asset.
        if !asset.isPlayable || asset.hasProtectedContent {
            let stringFormat = NSLocalizedString("error.asset_%@_not_playable.description", comment: "Can't use this AVAsset because it isn't playable or has protected content")

            let message = String.localizedStringWithFormat(stringFormat, title)

            self.handleError(with: message)

            return
        }

        /*
            We can play this asset. Create a new AVPlayerItem and make it
            our player's current item.
        */
        self.loadedAssets[title] = asset

        let name = (thumbnailResourceName as NSString).deletingPathExtension
        let type = (thumbnailResourceName as NSString).pathExtension
        let path = Bundle.main.path(forResource: name, ofType: type)!

        let thumbnail = UIImage(contentsOfFile: path)!

        self.assetTitlesAndThumbnails[asset.url] = (title, thumbnail)
    }
}

1 个答案:

答案 0 :(得分:2)

最后想出来,回答我自己的问题:我一直在使用HLS视频,网址格式为 https://www.foo.com/master.m3u8 loadValuesAsynchronously将不会执行任何网络操作来确定URL是否包含有效的HLS文件。这就是“可玩”键始终有效的原因:

static let assetKeysRequiredToPlay = [
    "playable",
    "hasProtectedContent"
]

但是,如果我还添加一些播放信息,例如“duration”和“tracks”,那么如果没有任何网络连接它将会失败,因为它将需要实际加载信息。更多细节参考这个答案:https://stackoverflow.com/a/31418812/1035008