2017-09-14 155 views
1

我在阅读&尝试关于加载视频资产的Apple示例代码。AVURLAsset loadValues异步永不会失败

但我注意到AVURLAsset上的loadValuesAsynchronously功能永远不会失效,即使我打开设备上的飞行模式或关闭我的mac上的wifi。有人知道在什么情况下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

终于想通了这一点,回答我的问题:我一直在使用HLS视频和URL是格式https://www.foo.com/master.m3u8的。 loadValuesAsynchronously将不会执行任何网络操作来确定URL是否包含有效的HLS文件。这就是为什么“可玩”关键始终是有效的:

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

然而不过,如果我还加了一些播放信息,如“时间”和“轨道”,那么它会如果没有任何网络连接失败。更详细的参考这个答案:https://stackoverflow.com/a/31418812/1035008