如何使用 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}
我的流程是:
- 使用像
https://my.cdn.com/playlist.m3u8
这样的 URL 创建一个 AVURLAsset
- 设置其resource loader's delegate
- 以
AVPlayerItem
的形式将其交给玩家
- 使用methods in
AVAssetResourceLoaderDelegate
, look for a URL beginning the scheme skd
, download the CKC, get the persist-able form,并将其交还给资源加载器请求
所有这些都有效,并且是按照与 Apple HLSCatalog sample code 相同的方式完成的。但是下载仍然会出现上述错误,即使将相同的播放列表和密钥 URLs 插入示例代码也可以正常下载。
我最终发现 AVAssetDownloadTask
只会下载一个 AVURLAsset
实例 已经流式传输并给出了它的解密密钥(通过AVAssetResourceLoaderDelegate
) 并且与玩家无关。我不能只使用与正在播放的内容相同的 URL 制作新的 AVURLAsset
并下载它。所以似乎为了下载任意 FairPlay 内容,我必须:
- 做一个
AVURLAsset
- 制作一个
AVPlayer
并将其音量设置为0
- 给它资产并播放它
- 等到它从资源加载器请求它的密钥并开始播放
- 将其交给下载任务并取消与播放器的关联
但这看起来很可怕。这不可能是真的。
所以,我的问题是:如何下载 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];
我正在尝试使用 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}
我的流程是:
- 使用像
https://my.cdn.com/playlist.m3u8
这样的 URL 创建一个 - 设置其resource loader's delegate
- 以
AVPlayerItem
的形式将其交给玩家
- 使用methods in
AVAssetResourceLoaderDelegate
, look for a URL beginning the schemeskd
, download the CKC, get the persist-able form,并将其交还给资源加载器请求
AVURLAsset
所有这些都有效,并且是按照与 Apple HLSCatalog sample code 相同的方式完成的。但是下载仍然会出现上述错误,即使将相同的播放列表和密钥 URLs 插入示例代码也可以正常下载。
我最终发现 AVAssetDownloadTask
只会下载一个 AVURLAsset
实例 已经流式传输并给出了它的解密密钥(通过AVAssetResourceLoaderDelegate
) 并且与玩家无关。我不能只使用与正在播放的内容相同的 URL 制作新的 AVURLAsset
并下载它。所以似乎为了下载任意 FairPlay 内容,我必须:
- 做一个
AVURLAsset
- 制作一个
AVPlayer
并将其音量设置为0 - 给它资产并播放它
- 等到它从资源加载器请求它的密钥并开始播放
- 将其交给下载任务并取消与播放器的关联
但这看起来很可怕。这不可能是真的。
所以,我的问题是:如何下载 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];