使用 AVAssetDownloadTask 进行 HLS 缓存
Posted
技术标签:
【中文标题】使用 AVAssetDownloadTask 进行 HLS 缓存【英文标题】:HLS caching using AVAssetDownloadTask 【发布时间】:2020-08-18 11:34:41 【问题描述】:我正在关注 Apple 关于缓存 HLS (.m3u8) 视频的文档。
https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/MediaPlaybackGuide/Contents/Resources/en.lproj/HTTPLiveStreaming/HTTPLiveStreaming.html
在文档的Playing Offline Assets下,指示使用AVAssetDownloadTask的asset同时开始播放。
func downloadAndPlayAsset(_ asset: AVURLAsset)
// Create new AVAssetDownloadTask for the desired asset
// Passing a nil options value indicates the highest available bitrate should be downloaded
let downloadTask = downloadSession.makeAssetDownloadTask(asset: asset,
assetTitle: assetTitle,
assetArtworkData: nil,
options: nil)!
// Start task
downloadTask.resume()
// Create standard playback items and begin playback
let playerItem = AVPlayerItem(asset: downloadTask.urlAsset)
player = AVPlayer(playerItem: playerItem)
player.play()
问题是同一个资源被下载了两次。
在 AVPlayer 初始化之后,它开始缓冲资源。最初,我假设缓冲区中的数据必须用于创建缓存,但 AVAssetDownloadTask 直到 AVPlayer 播放完资产后才开始下载数据进行缓存。缓冲的数据基本被丢弃。
我在 currentItem.loadedTimeRanges 上使用了 KVO 来检查缓冲区的状态。
playerTimeRangesObserver = currentPlayer.observe(\.currentItem?.loadedTimeRanges, options: [.new, .old]) (player, change) in
let time = self.currentPlayer.currentItem?.loadedTimeRanges.firs.
if let t = time
print(t.timeRangeValue.duration.seconds)
下面的方法来检查 AVAssetDownloadTask 的下载状态。
/// Method to adopt to subscribe to progress updates of an AVAssetDownloadTask.
func urlSession(_ session: URLSession, assetDownloadTask: AVAssetDownloadTask, didLoad timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad: CMTimeRange)
// This delegate callback should be used to provide download progress for your AVAssetDownloadTask.
guard let asset = activeDownloadsMap[assetDownloadTask] else return
var percentComplete = 0.0
for value in loadedTimeRanges
let loadedTimeRange: CMTimeRange = value.timeRangeValue
percentComplete +=
loadedTimeRange.duration.seconds / timeRangeExpectedToLoad.duration.seconds
print("PercentComplete for \(asset.stream.name) = \(percentComplete)")
这是正确的行为还是我做错了什么? 我希望能够使用正在缓存的视频数据(正在下载 AVAssetDownloadTask)在 AVPlayer 中播放。
【问题讨论】:
你弄明白了吗? 您是否尝试按照here 的建议重新初始化 AVPlayerItem? 【参考方案1】:您的 AVAssetDownloadTask 必须配置为下载不同于 AVPlayerItem 请求的 HLS 变体。
如果您已经通过 AVAssetDownloadTask 下载了一些数据,您的 AVPlayerItem 将随后使用它。 但是如果你已经通过 AVPlayerItem 下载了一些数据,你的 AVAssetDownloadTask 可能会忽略它,因为它需要满足你的下载配置的要求。
【讨论】:
以上是关于使用 AVAssetDownloadTask 进行 HLS 缓存的主要内容,如果未能解决你的问题,请参考以下文章
使用 Crypto++ 进行 RSA 编码并使用 c# RSACryptoServiceProvider 进行解码
AES GCM 使用 web 微妙加密进行加密并使用颤振加密进行解密
使用 C++ 原子库,我应该使用啥内存顺序进行加载,然后进行比较交换?