iOS возобновляет загрузку HLS и удаление частично загруженного файла - PullRequest
3 голосов
/ 18 апреля 2019

Я реализую потоковую передачу HLS согласно Apple Docs

Но проблема, с которой я сталкиваюсь, заключается в возобновлении загрузки, когда пользователь убивает приложение. Если загрузка выполняется и, скажем, 50% выполнено, и пользователь по какой-либо причине убивает приложение или приложение уничтожено системой, а когда приложение снова работает, то делегат сеанса URL-адреса didCompleteWithError называется

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
}

и здесь у меня нет частично загруженного пути к файлу или возможности возобновить задачу.

Единственное местоположение для загруженного файла вызывается, когда загрузка завершается через следующий вызов делегата

func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
}

Теперь док говорит использовать

downloadSession.getAllTasks { tasksArray in }

но, к сожалению, загрузка не возобновляется

Итак, моя проблема

  1. Как возобновить задачу из этого загруженного состояния, чтобы вся загрузка не начиналась заново с 0%?
  2. Для задачи, которая не может быть возобновлена, или для конкретного сценария, когда я не хочу ее возобновлять, как я могу удалить частично загруженный файл? Как я получу загруженный путь (я не хочу искать весь каталог документов)

1 Ответ

2 голосов
/ 25 апреля 2019

На самом деле, вы можете использовать getAllTasks(completionHandler:)] для получения отложенных задач, которые не были выполнены при предыдущем запуске , но каким-то образом эти задачи будут отменены сразу после создания сеанса загрузки , что приводит к вызову urlSession(_:task:didCompleteWithError:)как вы видите.

К счастью, я нашел другой способ возобновления AVAssetDownloadTask

AVAssetDownloadTask предоставляет возможность возобновления ранее остановленных загрузок при определенных обстоятельствах.Для этого просто создайте новый экземпляр AVAssetDownloadTask с экземпляром AVURLAsset, в котором файл 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.

Для более подробной информации, я создал образец репо по ссылке ниже.Есть еще некоторая ошибка, но она может работать в обычном случае.Попробуйте запустить задачу загрузки, дайте ей немного поработать и завершите работу приложения.Перезапустите и возобновите задачу, вы увидите результат.

https://github.com/trungducc/stackoverflow/tree/hls-download-resuming

...