我正在初始化AVPlayerItem
,它需要一个参数automaticallyLoadedAssetKeys
,它指示在标记为“准备播放”之前需要加载哪些AVAsset
个键。< / p>
我已经看到过将duration
属性作为其中一个键传递的人的例子。
但是在AVPlayerItem
的文档中,它讨论了duration
属性,以及如何确保它有效。
此属性的值将报告为kCMTimeIndefinite,直到加载基础资产的持续时间为止。有两种方法可以确保只有在可用时才访问持续时间值:
等到玩家项目的
status
为readyToPlay
另一种方法是注册一个KVO,这很好。但是第一条评论会向我表明我不需要问duration
是否自动加载,因为它应该已经存在。(?)
如果这是真的,我无法弄清楚为什么有人会传递duration
作为自动加载的标志,因为看起来就是这种情况。我在这里错过了什么吗?
答案 0 :(得分:0)
之所以这样做是因为有些iOS错误(包括iOS 12.1.4中的错误)有时会导致AVPlayerItem.duration为nan,即使状态为readyToPlay。示例here和here。
但是,根据我的经验,尽管Apple为AVPlayerItem提供了文档,但在autoLoadedAssetKeys中指定“持续时间”并不能解决问题:
在播放器项达到状态AVPlayerItem.Status.readyToPlay之前,基础AVAsset将自动加载automaticLoadedAssetKeys中每个键的值;也就是说,当物品准备好播放时,通过调用资产属性的statusOfValue(forKey:error :)方法返回的值将是终端状态值之一
我可以获得AVPlayerItem.Status.readyToPlay,其中statusOfValue(forKey:“ duration”)返回.loaded,持续时间为nan。
我发现每次都能奏效的唯一解决方案是将AVPlayerItem.status(用于.readyToPlay)和AVPlayerItem.duration(用于有效数字)同时进行KVO,并且当任一触发时,请同时进行检查:
if item.status != AVPlayerItem.Status.readyToPlay || !item.duration.isUsableNumber() {
return // not ready yet (for addBoundaryTimeObserver, seek to end, etc.)
}
isUsableNunber()在哪里:
func isUsableNumber() -> Bool {
return isValid && isNumeric && !isIndefinite && !isNegativeInfinity && !isPositiveInfinity
}
答案 1 :(得分:0)
对不起,我知道这有点陈旧。但是我最近找到了解决我问题的答案。
所以,我意识到我把文档弄糊涂了,而且也许一直以来都是正确的,如果我看起来更努力的话,我会注意到的。
AVPlayerItem(asset: asset)
默认情况下会加载duration
属性。就像打电话给AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: ["duration"])
它实际上在文档中是这样说的,但是我完全错过了它。