nsurlsession – 在下载之前获取AVAssetDownloadTask的大小

我目前正在使用FairPlay流媒体实现离线流媒体.因此我使用AVAssetDownloadTask下载流.

我想向用户提供有关下载开始大小的反馈:

Are you sure you want to download this stream? It will take 2.4GB to download and you currently have 14GB of space left

我正在检查像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()

打印尺寸为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")
}

但这些都保持为零:

Downloaded 0.0/0.0 MB

最佳答案 HLS流实际上是称为清单和传输流的文件集合.清单通常包含子清单的文本列表(每个子清单对应不同的比特率),这些子清单包含包含实际电影数据的传输流列表.

在您的代码中,当您下载HLS URL时,您实际上只下载了主清单,而且通常只有几千字节.如果要复制整个流,则需要解析所有清单,复制原始流的文件夹结构,并抓住传输段(这些通常是10秒段,因此可能有数百个这些).如果使用绝对URL指定清单,则可能需要重写URL.

要计算每个流的大小,您可以将比特率(在主清单中列出)乘以流的持续时间;对于下载目的而言,这可能是一个足够好的估计.

这里有一个更好的答案,因为你在离线FairPlay的上下文中使用AVAssetDownloadTask,就是实现AVAssetDownloadDelegate.该协议中的一种方法为您提供了您正在寻找的进展:

URLSession:assetDownloadTask:didLoadTimeRange:totalTimeRangesLoaded:timeRangeExpectedToLoad:

这是WWDC 2016 Session 504显示这个代表在行动.

有许多与FairPlay离线播放相关的细节,因此最好仔细阅读该视频.

点赞