离线 Fairplay AVAssetDownloadTask 在下载时收到未知错误回调(只发生在 iOS 10.2)
Offline Fairplay AVAssetDownloadTask got unknown error callback while downloading (only happened on iOS 10.2)
我们正在为我们的客户端应用构建离线公平竞赛内容;我们通过参考 HLSCatalog 演示应用程序中的 Apple 示例下载管理器 AssetPersistenceManager class 来实现该功能。
我想在这里强调的是 AssetPersistenceManager class 中的一个函数和两个回调,它是
/
func downloadStream(for asset: Asset) {
/
For the initial download, we ask the URLSession for an AVAssetDownloadTask
with a minimum bitrate corresponding with one of the lower bitrate variants
in the asset.
*/
guard let task = assetDownloadURLSession.makeAssetDownloadTask(asset: asset.urlAsset, assetTitle: asset.name, assetArtworkData: nil, options: [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: 265000]) else { return }
/
task.taskDescription = asset.name
activeDownloadsMap[task] = asset
task.resume()
var userInfo = [String: Any]()
userInfo[Asset.Keys.name] = asset.name
userInfo[Asset.Keys.downloadState] = Asset.DownloadState.downloading.rawValue
NotificationCenter.default.post(name: AssetDownloadStateChangedNotification, object: nil, userInfo: userInfo)
}
并在完成下载流时回调
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
let userDefaults = UserDefaults.standard
/
This delegate callback should only be used to save the location URL
somewhere in your application. Any additional work should be done in
`URLSessionTaskDelegate.urlSession(_:task:didCompleteWithError:)`.
*/
if let asset = activeDownloadsMap[assetDownloadTask] {
userDefaults.set(location.relativePath, forKey: asset.name)
}
}
最后一个是didCompleteWithError回调
func urlSession(_ session: URLSession, task: URLSessionTask,
didCompleteWithError error: Error?)
在 iOS < 10.2 上似乎一切正常,但在某些 运行 最新 iOS 10.2 的设备上进行测试后,应用程序总是收到 didFinishDownloadTo 委托的回调,而只有 13-完成百分比的 15%,之后
didCompleteWithError 错误
被调用,我们收到以下错误
> "=======> completed percent 11.2888760669556" .
> "=======> completed percent 11.44566601233"
> "=======> completed percent 11.7592459030787"
> "=======> completed percent 12.0728257938275"
> "=======> completed percent 12.5431956299506"
> "=======> completed percent 13.0135654660738"
> "=======> completed percent 13.3271453568226"
> "=======> completed percent 13.6407252475713"
> "=======> completed percent 13.9543051383201"
> "=======> completed percent 14.1110950836945"
> "=======> completed percent 14.2678850290689"
> "Error Domain=AVFoundationErrorDomain Code=-11800 \"The operation could not
> be completed\" UserInfo={NSLocalizedDescription=The operation could
> not be completed, NSLocalizedFailureReason=An unknown error occurred
> (-12667)}"
检查代理调试应用程序,它指出应用程序在整个接收响应之前关闭连接。
Status
Complete
Failure
Client closed connection before receiving entire response
Response Code
206 Partial Content
只有 iOS 10.2 有这个错误,在低于该版本的其他 OS 上测试的相同流仍然工作正常。
试图找到一些关于 iOS 10.2 的更新日志,但我什么也没找到?大家有什么建议吗?
经过一周的坚持,我们自己找到了答案。原来是 iOS 10.0 - 10.1 而不是 10.2 上的错误。
错误发生在 30 秒后与 DRM 错误有关,它发生在 iOS 10.2,在 AVAssetDownloadTask 恢复后有来自 AVAssetResourceLoaderDelegate 的回调,您需要点击服务器密钥来完成 [=11= 中的 Fairplay DRM 内容密钥]
func resourceLoader(_ resourceLoader: AVAssetResourceLoader,
shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool
否则,下载将被强制停止,您将收到上述未知错误。
Apple 示例代码 HLSCatalog 只是 non-DRM 流的演示,他们甚至没有提到演示中所需的内容密钥实现。
我们遵循了他们的样本,似乎 iOS 10.0 - 10.1,AVFoundation 在处理下载时没有检查内容密钥,这就是为什么当我们第一次实现下载功能时,我们认为内容密钥是下载时需要,这导致我们在 iOS 10.2...
上浪费了一周
我们正在为我们的客户端应用构建离线公平竞赛内容;我们通过参考 HLSCatalog 演示应用程序中的 Apple 示例下载管理器 AssetPersistenceManager class 来实现该功能。 我想在这里强调的是 AssetPersistenceManager class 中的一个函数和两个回调,它是
/
func downloadStream(for asset: Asset) {
/
For the initial download, we ask the URLSession for an AVAssetDownloadTask
with a minimum bitrate corresponding with one of the lower bitrate variants
in the asset.
*/
guard let task = assetDownloadURLSession.makeAssetDownloadTask(asset: asset.urlAsset, assetTitle: asset.name, assetArtworkData: nil, options: [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: 265000]) else { return }
/
task.taskDescription = asset.name
activeDownloadsMap[task] = asset
task.resume()
var userInfo = [String: Any]()
userInfo[Asset.Keys.name] = asset.name
userInfo[Asset.Keys.downloadState] = Asset.DownloadState.downloading.rawValue
NotificationCenter.default.post(name: AssetDownloadStateChangedNotification, object: nil, userInfo: userInfo)
}
并在完成下载流时回调
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didFinishDownloadingTo location: URL) {
let userDefaults = UserDefaults.standard
/
This delegate callback should only be used to save the location URL
somewhere in your application. Any additional work should be done in
`URLSessionTaskDelegate.urlSession(_:task:didCompleteWithError:)`.
*/
if let asset = activeDownloadsMap[assetDownloadTask] {
userDefaults.set(location.relativePath, forKey: asset.name)
}
}
最后一个是didCompleteWithError回调
func urlSession(_ session: URLSession, task: URLSessionTask,
didCompleteWithError error: Error?)
在 iOS < 10.2 上似乎一切正常,但在某些 运行 最新 iOS 10.2 的设备上进行测试后,应用程序总是收到 didFinishDownloadTo 委托的回调,而只有 13-完成百分比的 15%,之后 didCompleteWithError 错误 被调用,我们收到以下错误
> "=======> completed percent 11.2888760669556" .
> "=======> completed percent 11.44566601233"
> "=======> completed percent 11.7592459030787"
> "=======> completed percent 12.0728257938275"
> "=======> completed percent 12.5431956299506"
> "=======> completed percent 13.0135654660738"
> "=======> completed percent 13.3271453568226"
> "=======> completed percent 13.6407252475713"
> "=======> completed percent 13.9543051383201"
> "=======> completed percent 14.1110950836945"
> "=======> completed percent 14.2678850290689"
> "Error Domain=AVFoundationErrorDomain Code=-11800 \"The operation could not
> be completed\" UserInfo={NSLocalizedDescription=The operation could
> not be completed, NSLocalizedFailureReason=An unknown error occurred
> (-12667)}"
检查代理调试应用程序,它指出应用程序在整个接收响应之前关闭连接。
Status
Complete
Failure
Client closed connection before receiving entire response
Response Code
206 Partial Content
只有 iOS 10.2 有这个错误,在低于该版本的其他 OS 上测试的相同流仍然工作正常。 试图找到一些关于 iOS 10.2 的更新日志,但我什么也没找到?大家有什么建议吗?
经过一周的坚持,我们自己找到了答案。原来是 iOS 10.0 - 10.1 而不是 10.2 上的错误。 错误发生在 30 秒后与 DRM 错误有关,它发生在 iOS 10.2,在 AVAssetDownloadTask 恢复后有来自 AVAssetResourceLoaderDelegate 的回调,您需要点击服务器密钥来完成 [=11= 中的 Fairplay DRM 内容密钥]
func resourceLoader(_ resourceLoader: AVAssetResourceLoader,
shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool
否则,下载将被强制停止,您将收到上述未知错误。 Apple 示例代码 HLSCatalog 只是 non-DRM 流的演示,他们甚至没有提到演示中所需的内容密钥实现。
我们遵循了他们的样本,似乎 iOS 10.0 - 10.1,AVFoundation 在处理下载时没有检查内容密钥,这就是为什么当我们第一次实现下载功能时,我们认为内容密钥是下载时需要,这导致我们在 iOS 10.2...
上浪费了一周