我正在按照Apple Docs实现HLS流
但我面临的问题是当用户杀死应用程序时恢复下载。如果下载正在进行并说其完成50%并且用户杀死应用程序或应用程序由于任何原因被系统杀死,并且当应用程序再次活动时,则调用didCompleteWithError
的URL会话委托
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
}
在这里,我没有部分下载的文件路径或恢复任务的能力。
通过以下委托调用完成下载后,将调用下载文件的唯一位置
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
}
现在doc说要使用
downloadSession.getAllTasks { tasksArray in }
但不幸的是,它没有恢复下载
所以我的问题是
实际上,您可以使用getAllTasks(completionHandler:)]
来获取在上次启动时未完成的待处理任务,但不知何故,这些任务将在创建下载会话后立即取消,这会导致urlSession(_:task:didCompleteWithError:)
被调用。
幸运的是,我找到了恢复AVAssetDownloadTask
的另一种方式
AVAssetDownloadTask提供在某些情况下恢复先前停止的下载的功能。为此,只需使用AVURLAsset实例化一个新的AVAssetDownloadTask,该文件NSURL指向具有所需下载选项的部分下载的包,并且下载将继续恢复以前下载的任何数据。
这意味着如果要恢复挂起的AVAssetDownloadTask
,则必须在下载任务停止时从location
保存urlSession(_:assetDownloadTask:didFinishDownloadingTo:)
。之后,在部分下载的文件上创建另一个下载任务。
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
destinationURL = location
}
func resumeDownloadTask() {
let urlAsset = AVURLAsset(url: destinationURL)
downloadTask = assetDownloadURLSession.makeAssetDownloadTask(asset: urlAsset, assetTitle: "title", assetArtworkData: nil, options: nil)
downloadTask.resume()
}
urlSession(_:assetDownloadTask:didFinishDownloadingTo:)
将始终在urlSession(_:task:didCompleteWithError:)
之前调用,因此当应用程序终止并重新启动或下载任务被取消时,您可以获得destinationURL
。
请注意,您不应该在urlSession(_:task:didCompleteWithError:)
中创建新的下载任务,不知何故它将导致无限循环。
在第二个问题中,只需使用destinationURL
删除该文件即可。
有关更多详细信息,我在以下链接中创建了一个样本仓库。还有一些bug,但它可以在正常情况下运行。尝试开始下载任务,让它运行一段时间并终止应用程序。重新启动并恢复任务,您将看到结果。
https://github.com/trungducc/stackoverflow/tree/hls-download-resuming