I am creating a function to download M3u8 files in iOS. I can download the M3u8 but I want the ability to restore a pending download if the app is paused or quit. Below is the main documentation I used but I can't get the restore function to work as intended.
Below is what I use to download the M3U8:
private var config: URLSessionConfiguration!
var downloadSession: AVAssetDownloadURLSession!
var downloadTask: AVAssetDownloadTask!
var mediaSelectionMap = [AVAssetDownloadTask : AVMediaSelection]()
let downloadIdentifier = "mySession"
func assetDownload(url: URL) {
print("Download started...")
//Create new background session configuration
let configuration = URLSessionConfiguration.background(withIdentifier: downloadIdentifier)
//Create a new AVAssetDownloadURLSession with background config, delegate and queue
let downloadSession = AVAssetDownloadURLSession(configuration: configuration, assetDownloadDelegate: self, delegateQueue: OperationQueue.main)
downloadSession.getAllTasks { (taskArray) in
//Task array always nil when segment should be found
if taskArray.count > 0 {
print("Check if to resume previous download")
self.restorePendingDownloads()
} else {
let asset = AVURLAsset(url: url)
print("New Movie downloading")
//Create new AVAssetDownloadTask for the desired asset
self.downloadTask = downloadSession.makeAssetDownloadTask(asset: asset, assetTitle: "VideoSample", assetArtworkData: nil, options: [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: NSNumber(value: 0)])
//Start task and begin download
self.downloadTask?.resume()
}
}
}
Below is the restore pending function:
func restorePendingDownloads() {
print("restore pending download...")
// Create session configuration with ORIGINAL download identifier
config = URLSessionConfiguration.background(withIdentifier: downloadIdentifier)
// Create a new AVAssetDownloadURLSession
downloadSession = AVAssetDownloadURLSession(configuration: config,
assetDownloadDelegate: self,
delegateQueue: OperationQueue.main)
// Grab all the pending tasks associated with the downloadSession
downloadSession.getAllTasks { tasksArray in
print("getting all tasks.. \(tasksArray.count)") //returns 0
// For each task, restore the state in the app
for task in tasksArray {
guard let downloadTask = task as? AVAssetDownloadTask else { break }
// Restore asset, progress indicators, state, etc...
let asset = downloadTask.urlAsset
print("asset:\(asset)")
//NEVER CALLED BECAUSE EMPTY
}
}
}
Someone recommended using the function below but this just reset the download to the beginning.
func restorePendingDownload(url: URL){
let urlAsset = AVURLAsset(url: url)
downloadTask = downloadSession.makeAssetDownloadTask(asset: urlAsset, assetTitle: "master", assetArtworkData: nil, options: nil)
downloadTask.resume()
}
UPDATE
I found a solution for the pause resume function but not on how to resume when the app is quit.
I added this function which stores the destinationURL when paused and can be used in the restore pending function.
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
// Do not move the asset from the download location
UserDefaults.standard.set(location.relativePath, forKey: "assetPath")
destinationURL = location
}
in donwload asset function, I changed the following line from:
self.downloadTask = downloadSession.makeAssetDownloadTask(asset: asset, assetTitle: "VideoSample", assetArtworkData: nil, options: [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: NSNumber(value: 0)])
to:
self.downloadTask = downloadSession.makeAssetDownloadTask(asset: asset, assetTitle: "VideoSample", assetArtworkData: nil, options: nil)
I think to set the minimum requirement was causing the issue.
Any help or direction in how to restore the pending download when quitting the application would be amazing. Thanks
From HLSCatalog example I tried adding [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: 265_000] to options when creating AVAssetDownloadTask.
In AppDelegate I call restorePending() and getAllTasks returns number of pending tasks. In next step I still get errors, which I'm still resolving, but tasks are not empty.
I hope it helps you.