Ant*_*ine 7 fairplay nsurlsession nsurlsessiondatatask avassetdownloadtask
我目前正在使用 FairPlay 流实现离线流。因此,我正在使用AVAssetDownloadTask.
我想向用户提供有关开始下载的大小的反馈:
您确定要下载此流吗?下载需要 2.4GB,您目前还有 14GB 的空间
我已经检查过类似countOfBytesReceived和的属性,countOfBytesExpectedToReceive但这些不会返回正确的值。
let headRequest = NSMutableURLRequest(URL: asset.streamURL)
headRequest.HTTPMethod = "HEAD"
let sizeTask = NSURLSession.sharedSession().dataTaskWithRequest(headRequest) { (data, response, error) in
    print("Expected size is \(response?.expectedContentLength)")
}.resume()
Run Code Online (Sandbox Code Playgroud)
打印大小为 2464,最后大小为 3GB。
在下载过程中,我记录了上述属性:
func URLSession(session: NSURLSession, assetDownloadTask: AVAssetDownloadTask, didLoadTimeRange timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad: CMTimeRange) {
    print("Downloaded \( convertFileSizeToMegabyte(Float(assetDownloadTask.countOfBytesReceived)))/\(convertFileSizeToMegabyte(Float(assetDownloadTask.countOfBytesExpectedToReceive))) MB")
}
Run Code Online (Sandbox Code Playgroud)
但这些保持为零:
已下载 0.0/0.0 MB
我个人没有使用过这个 API,但我至少对 HTTP Live Streaming 有一定的了解。有了这些知识,我想我知道为什么您无法获得您正在寻找的信息。
HLS 协议旨在处理实时流媒体以及固定长度资产的流媒体。它通过将媒体切成通常大约十秒的块(IIRC)并在播放列表文件中的特定 URL 处列出这些块的 URL 来实现此目的。
如果播放列表没有改变,那么您可以下载播放列表,计算文件数量,获取第一个文件的长度,并将其乘以文件数量,您将得到一个粗略的近似值,您可以将其替换当您开始检索最后一个块时,使用精确值。
但不保证播放列表不会改变。 使用 HLS,通过删除(或不删除)最旧的片段并在末尾添加新片段,播放列表可能每十秒更改一次。这样,HLS就支持了没有尽头的直播流。在这种情况下,下载具有大小的概念是荒谬的。
更糟糕的是,2464 可能是播放列表文件的大小,而不是其中第一个资源的大小,也就是说,除非该子类的didReceiveResponse:方法起作用,否则它不会告诉您任何信息,在这种情况下,您可能能够获得通过在获取每个段时读取标头来获取每个段的长度Content-Length。即使它正常工作,您可能仍然无法从此 API 获取段数(并且也不能保证所有段的长度完全相同,尽管它们应该非常接近)。
我怀疑,要获取您想要的信息,即使对于非实时资产,您也可能必须获取播放列表,自行解析它,并对其中列出的每个媒体片段 URL 执行一系列 HEAD 请求。
幸运的是,HLS 规范是一个公开可用的标准,因此如果您想沿着这条路走下去,您可以阅读 RFC 以了解播放列表文件的结构。而且据我所知,播放列表本身没有使用任何 DRM 或任何东西加密,因此即使 API 的实际解密部分不公开(据我所知),也应该可以这样做。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           1421 次  |  
        
|   最近记录:  |