如何使用 AVAssetDownloadTask 下载尚未流式传输的 FairPlay 加密 AVURLAsset 实例?

How can I use AVAssetDownloadTask to download a FairPlay-encrypted AVURLAsset instance that has not yet been streamed?

我正在尝试使用 AVAssetDownloadTask to download and play FairPlay-encrypted audio content offline. I kept getting an error like this in urlSession:task:didCompleteWithError::

Error Domain=AVFoundationErrorDomain Code=-11863 "Operation Stopped" UserInfo={NSLocalizedFailureReason=This content is no longer available., NSLocalizedDescription=Operation Stopped}

我的流程是:

所有这些都有效,并且是按照与 Apple HLSCatalog sample code 相同的方式完成的。但是下载仍然会出现上述错误,即使将相同的播放列表和密钥 URLs 插入示例代码也可以正常下载。

我最终发现 AVAssetDownloadTask 只会下载一个 AVURLAsset 实例 已经流式传输并给出了它的解密密钥(通过AVAssetResourceLoaderDelegate) 并且与玩家无关。我不能只使用与正在播放的内容相同的 URL 制作新的 AVURLAsset 并下载它。所以似乎为了下载任意 FairPlay 内容,我必须:

但这看起来很可怕。这不可能是真的。

所以,我的问题是:如何下载 FairPlay 加密的 AVURL资产,而无需流式传输它的特定实例?

原来您在资产的资源加载器上将 preloadsEligibleContentKeys 设置为 true。然后就可以下载了:

AVURLAsset *asset = [AVURLAsset assetWithURL:self.currDownload.url];
[asset.resourceLoader setDelegate:self queue:dispatch_get_main_queue()];
asset.resourceLoader.preloadsEligibleContentKeys = YES;
AVAssetDownloadTask *task = [self.downloadSession assetDownloadTaskWithURLAsset:asset assetTitle:self.currDownload.title assetArtworkData:nil options:@{AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: @(265000)}];
task.taskDescription = self.currDownload.title;
[task resume];