首页 > 解决方案 > 使用 AVPlayer 播放和缓存远程资源

问题描述

我正在尝试使用 AVPlayer 使用 Github 上的两个工具播放/缓存远程资产: CachingPlayerItemCache。我在其他地方找到了解决方案(向下滚动),这几乎可以让我到达那里,我现在的问题是我必须在远程音频资产(Firebase 中的超链接)上点击两次才能让它流式传输。出于某种神秘的原因,AVPlayer 不会播放远程资产,除非它在我的情况下被缓存。我知道我可以直接使用流式传输 url,AVPlayerItem(url:)但这不是我正在寻找的解决方案;CachingPlayerItem的示例代码说这不是必需的。

在我的修修补补中,我认为当我调用playerItem.delegate = self. 也许我误解了这个异步委托操作是如何工作的......任何清晰和指针将不胜感激。

import AVKit
import Cache

class AudioPlayer: AVPlayer, ObservableObject, AVAudioPlayerDelegate {

    let diskConfig = DiskConfig(name: "DiskCache")
    let memoryConfig = MemoryConfig(expiry: .never, countLimit: 10, totalCostLimit: 10)

    lazy var storage: Cache.Storage<String, Data>? = {
        return try? Cache.Storage(diskConfig: diskConfig, memoryConfig: memoryConfig, transformer: TransformerFactory.forData())
    }()

    /// Plays audio either from the network if it's not cached or from the cache.
    func startPlayback(with url: URL) {
        let playerItem: CachingPlayerItem
        do {
            let result = try storage!.entry(forKey: url.absoluteString)
            // The video is cached.
            playerItem = CachingPlayerItem(data: result.object, mimeType: "audio/mp4", fileExtension: "m4a")
        } catch {
            // The video is not cached.
            playerItem = CachingPlayerItem(url: url)
        }

        playerItem.delegate = self // Seems to be the problematic line if the result is not cached.
        self.replaceCurrentItem(with: playerItem) // This line is different from what you do. The behaviour doesnt change whether I have AVPlayer as private var.
        self.automaticallyWaitsToMinimizeStalling = false
        self.play()
    }
}

extension AudioPlayer: CachingPlayerItemDelegate {
    func playerItem(_ playerItem: CachingPlayerItem, didFinishDownloadingData data: Data) {
        // Video is downloaded. Saving it to the cache asynchronously.
        storage?.async.setObject(data, forKey: playerItem.url.absoluteString, completion: { _ in })
        print("Caching done!")
    }
}

标签: iosswiftxcodecachingavkit

解决方案


推荐阅读