已下载的.movpkg需联网才能播放的问题排查
问题描述
- 使用
AVAggregateAssetDownloadTask下载带FairPlay加密的HLS流媒体,保存为.movpkg文件夹。 - 关闭WiFi与LTE网络后,部分视频可正常播放,部分无法播放;对比文件体积发现,无法播放的文件明显偏小,未完成完整下载。
- 重新连接WiFi后,这些异常的
.movpkg文件在播放时会下载大量.frag文件。
补充下载代码
func downloadStream(for asset: Asset) { // 获取资源媒体选择组的默认媒体选择项 let preferredMediaSelection = asset.urlAsset.preferredMediaSelection /* 创建并初始化AVAggregateAssetDownloadTask,用于下载AVURLAsset上的多个AVMediaSelection。 初始下载时,我们请求URLSession返回一个AVAssetDownloadTask,对应资源中较低码率的变体之一,设置最低要求码率。 */ guard let task = assetDownloadURLSession.aggregateAssetDownloadTask(with: asset.urlAsset, mediaSelections: [preferredMediaSelection], assetTitle: asset.stream.name, assetArtworkData: nil, options: [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: 265_000]) else { return } // 为了更好地跟踪AVAssetDownloadTask,为任务设置唯一的描述信息 task.taskDescription = asset.stream.name activeDownloadsMap[task] = asset task.resume() var userInfo = [String: Any]() userInfo[Asset.Keys.name] = asset.stream.name userInfo[Asset.Keys.downloadState] = Asset.DownloadState.downloading.rawValue userInfo[Asset.Keys.downloadSelectionDisplayName] = displayNamesForSelectedMediaOptions(preferredMediaSelection) NotificationCenter.default.post(name: .AssetDownloadStateChanged, object: nil, userInfo: userInfo) }
原因分析与解决方案
核心原因
- FairPlay加密的密钥依赖:FairPlay加密的HLS流,解密所需的内容密钥(CKC)通常需要向License服务器请求。如果下载过程中未提前获取并缓存完整的密钥,或者密钥存在有效期、绑定播放场景等限制,部分分片的解密信息会缺失,导致离线时无法解密播放。
- 最低码率参数的限制:你设置了
AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: 265_000,AVFoundation会优先下载符合最低码率要求的分片,但如果HLS流的码率切换逻辑或分片依赖关系存在问题,可能导致部分必要的高码率分片未被下载,离线播放时播放器尝试切换码率失败。 AVAggregateAssetDownloadTask的下载逻辑:该API默认仅下载当前选中媒体轨的必要分片,但对于FairPlay加密内容,部分加密分片的元数据或密钥相关信息可能未被完整下载,只有在播放时才会触发补充下载,导致离线时无法播放。
解决建议
- 移除最低码率限制:删除
AVAssetDownloadTaskMinimumRequiredMediaBitrateKey参数,让AVFoundation自动选择合适的码率完成完整下载,避免因码率筛选导致分片缺失。 - 严格监听下载完成状态:在
URLSessionDownloadDelegate的urlSession(_:aggregateAssetDownloadTask:didCompleteFor:)回调中,确认所有媒体轨的下载状态为完成,不要仅依赖任务resume()后的表面状态。 - 优化FairPlay密钥缓存:下载前通过
AVAssetResourceLoader预获取并缓存FairPlay解密密钥,确保离线时所有分片都能获取到有效的解密信息。 - 检查HLS流结构:验证HLS的
m3u8文件,确认所有分片的URI路径正确,EXT-X-KEY等加密信息完整且可离线访问,排除流本身的结构问题导致的下载不完整。
内容的提问来源于stack exchange,提问作者Rao
相关产品推荐
相关产品推荐

