我目前正在使用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离线播放相关的细节,因此最好仔细阅读该视频.