2017-09-14 160 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