You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在未流播放特定实例时下载FairPlay加密的AVURLAsset

How to Download FairPlay-Encrypted AVURLAsset Without Pre-Playing the Asset?

我之前也碰到过一模一样的-11863错误,真的让人头大——明明逻辑和HLSCatalog示例完全对齐,结果就是下载失败。后来才搞清楚核心问题:AVAssetDownloadTask需要提前确认目标asset具备解密能力,但直接用未加载过密钥的asset创建下载任务时,系统不会自动触发资源加载器去获取CKC。

你之前那种"先静音播放再下载"的路子确实是歪的,正确的做法是手动触发asset的解密密钥获取流程,不需要借助AVPlayer。下面是具体的实现步骤:

正确实现流程

  1. 单独创建用于下载的AVURLAsset实例,绑定好你的AVAssetResourceLoaderDelegate(和你播放时用的代理逻辑一致,重点是处理SKD scheme的请求、返回持久化的CKC)。
  2. 调用loadValuesAsynchronously(forKeys:)方法,强制asset加载playable状态——这个过程会触发资源加载器去处理解密所需的密钥请求:
    let downloadAsset = AVURLAsset(url: yourPlaylistURL)
    downloadAsset.resourceLoader.setDelegate(yourResourceLoaderDelegate, queue: DispatchQueue(label: "download.resource.loader"))
    
    downloadAsset.loadValuesAsynchronously(forKeys: ["playable"]) { [weak self] in
        var loadError: NSError?
        let status = downloadAsset.statusOfValue(forKey: "playable", error: &loadError)
        
        switch status {
        case .loaded:
            // 此时asset已完成密钥获取,可安全创建下载任务
            guard let downloadTask = self?.downloadSession.makeAssetDownloadTask(
                asset: downloadAsset,
                assetTitle: "Your Content Title",
                assetArtworkData: nil,
                options: nil
            ) else { return }
            downloadTask.resume()
        case .failed:
            print("Failed to prepare asset for download: \(loadError?.localizedDescription ?? "Unknown error")")
        default:
            break
        }
    }
    
  3. 确保你的AVAssetResourceLoaderDelegate在处理shouldWaitForLoadingOfRequestedResource时,返回的CKC是可持久化的——也就是调用streamingContentKeyRequestData(forApp:contentIdentifier:options:error:)时,要配置正确的选项让密钥能和离线内容绑定存储。

为什么之前的方法会失败?

当你把asset关联到AVPlayer时,播放器会主动触发资源加载流程去获取解密密钥;但AVAssetDownloadTask不会做这件事,它要求传入的asset必须已经处于"可播放"(即已获取有效密钥)的状态。手动加载playable key,本质是强制asset完成解密所需的所有前置资源请求,不需要播放器介入。

额外注意点

  • 不要复用同一个AVURLAsset实例同时做播放和下载,最好为下载单独创建实例,避免状态冲突。
  • 确认你的CKC获取逻辑返回的是持久化形式的密钥,否则下载后的离线内容无法正常解密播放。

这样操作下来,就能跳过"先播放再下载"的奇葩流程,直接完成FairPlay加密内容的离线下载了,亲测和HLSCatalog示例的逻辑完全兼容,也能解决你遇到的-11863错误。

内容的提问来源于stack exchange,提问作者Tom Hamming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:08:11