HLS缓存使用AVAssetDownloadTask

3
我正在遵循苹果的缓存HLS (.m3u8) 视频文档。

https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/MediaPlaybackGuide/Contents/Resources/en.lproj/HTTPLiveStreaming/HTTPLiveStreaming.html

在文档中的“播放离线资源”部分,指导使用AVAssetDownloadTask的资产同时开始播放。
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中播放。


1
你解决了吗? - om-ha
你是否尝试按照这里建议的重新初始化AVPlayerItem? - om-ha
1个回答

0

你的AVAssetDownloadTask必须配置为下载与AVPlayerItem请求不同的HLS变体。

如果你已经通过AVAssetDownloadTask下载了一些数据,AVPlayerItem将随后使用它。 但是,如果你已经通过AVPlayerItem下载了一些数据,你的AVAssetDownloadTask可能会忽略它,因为它需要满足你的下载配置要求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接