Yuc*_*ong 5 ios avplayer avqueueplayer
我正在阅读并尝试苹果关于加载视频资源的示例代码。
但我注意到,即使我打开设备上的飞行模式或关闭 Mac 上的 WiFi,该loadValuesAsynchronously功能也不会失败。AVURLAsset有谁知道什么情况下loadValuesAsynchronously会无法加载密钥?
这是相关示例代码:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
终于弄清楚了,回答我自己的问题:我一直在使用 HLS 视频,URL 的格式为https://www.foo.com/master.m3u8。loadValuesAsynchronously不会执行任何网络操作来确定 URL 是否包含有效的 HLS 文件。这就是为什么“可玩”键始终有效的原因:
static let assetKeysRequiredToPlay = [
"playable",
"hasProtectedContent"
]
Run Code Online (Sandbox Code Playgroud)
但是,如果我还添加一些播放信息,例如“持续时间”和“曲目”,那么如果没有任何网络连接,它将失败,因为它需要实际加载信息。更多详细信息请参阅此答案:/sf/answers/2199316871/