iOS 18.3中长时长FairPlay DRM HLS离线播放请求服务器资源问题
问题背景
基于官方FairPlay Streaming Server SDK开发的应用,支持DRM保护HLS视频的流式传输与离线下载。在iOS 18.3环境下,播放19小时及以上时长的已下载视频时,尽管已将本地文件路径传入AVURLAsset,应用仍会向服务器请求.ts或.aac资源,导致飞行模式下播放失败;18小时及以下时长的视频无此问题,且videoAsset.assetCache.isPlayableOffline返回true。
相关代码
加载视频代码:
// load let path = ".../xxx.movpkg" // 已下载文件路径 videoAsset = AVURLAsset(url: path) playerItem = AVPlayerItem(asset: videoAsset!) player.replaceCurrentItem(with: playerItem)
离线可播放性验证:
// isPlayableOffline print("videoAsset.assetCache.isPlayableOffline = \(videoAsset.assetCache.isPlayableOffline)") // true
可能的解决方向
1. 检查缓存时间范围的完整性
长时长视频的HLS索引包含大量分片,iOS 18.3的AVAssetCache可能存在缓存条目遗漏。通过以下代码确认实际缓存的时长是否覆盖完整视频:
let cachedRanges = videoAsset.assetCache.cachedTimeRanges let totalCachedDuration = cachedRanges.reduce(0.0) { $0 + $1.timeRange.duration.seconds } print("Total cached duration: \(totalCachedDuration)")
如果缓存时长不足,重新触发下载时需通过AVAssetDownloadTask的代理回调,确保所有分片都被完整缓存。
2. 强制使用本地资源,拦截网络请求
将本地路径转为file://协议URL,并通过AVURLAssetResourceLoaderDelegate拦截所有网络请求,直接从movpkg包读取资源:
let fileURL = URL(fileURLWithPath: path) let asset = AVURLAsset(url: fileURL) asset.resourceLoader.setDelegate(self, queue: DispatchQueue(label: "resourceLoaderQueue"))
在代理方法resourceLoader(_:shouldWaitForLoadingOfRequestedResource:)中,解析请求的资源路径,从本地movpkg中读取对应文件并返回响应,阻止网络请求。
3. 验证movpkg包结构
长时长视频的movpkg可能存在结构异常,比如分片文件缺失或索引路径错误。使用Xcode的Media Analysis工具检查包内所有.ts/.aac文件是否存在,以及m3u8索引中的路径是否正确指向本地文件。
4. 适配iOS版本并反馈Bug
该问题仅出现在iOS 18.3且与时长强相关,大概率是系统层面的AVAssetCache Bug。可在iOS 17.x版本验证是否复现,若仅iOS 18.3存在,建议向Apple提交Bug报告,附带测试视频包与完整日志。
内容的提问来源于stack exchange,提问作者m-ogawa

