在 Swift 中获取 HLS 段请求的通知

Geo*_*e_T 7 streaming http-live-streaming ios swift

我正在用 Swift 编写一个用于 HLS 直播的 iOS 应用程序。我希望在播放期间启动每个 HLS 段请求(以及相应的 URL 是什么)时通知我的应用程序逻辑。我尝试使用 KVO 观察 AVPlayer 和 AVPlayerItem 的各种属性的变化。但是,它只通知我何时开始播放。比如添加下面的observer,会在播放开始的时候触发observeValue方法的调用,但是我还没有找到让每个segment请求持续得到通知的方法。

playerItem.addObserver(self, forKeyPath: "status", options:NSKeyValueObservingOptions(), context: nil)

是否有使用 KVO 的方法可以让我收到每个段请求的通知?是否有其他与 AVFoundation 无关的对象/API:我应该考虑?

/乔治

Nah*_*dan 5

当我需要调试 HLS 流时,我会遵循 Fabian 的方法。每次有与当前正在播放的流相关的更新时,它都会显示有用的信息。这是我使用的代码,希望它可以帮助遇到类似问题的人!

func trackPlayerLogs() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(handleAVPlayerAccess),
                                           name: NSNotification.Name.AVPlayerItemNewAccessLogEntry,
                                           object: nil)
}

func handleAVPlayerAccess(notification: Notification) {

    guard let playerItem = notification.object as? AVPlayerItem,
        let lastEvent = playerItem.accessLog()?.events.last else {
        return
    }

    let indicatedBitrate = lastEvent.indicatedBitrate

    print("--------------PLAYER LOG--------------")
    print("EVENT: \(lastEvent)")
    print("INDICATED BITRATE: \(indicatedBitrate)")
    print("PLAYBACK RELATED LOG EVENTS")
    print("PLAYBACK START DATE: \(lastEvent.playbackStartDate)")
    print("PLAYBACK SESSION ID: \(lastEvent.playbackSessionID)")
    print("PLAYBACK START OFFSET: \(lastEvent.playbackStartOffset)")
    print("PLAYBACK TYPE: \(lastEvent.playbackType)")
    print("STARTUP TIME: \(lastEvent.startupTime)")
    print("DURATION WATCHED: \(lastEvent.durationWatched)")
    print("NUMBER OF DROPPED VIDEO FRAMES: \(lastEvent.numberOfDroppedVideoFrames)")
    print("NUMBER OF STALLS: \(lastEvent.numberOfStalls)")
    print("SEGMENTS DOWNLOADED DURATION: \(lastEvent.segmentsDownloadedDuration)")
    print("DOWNLOAD OVERDUE: \(lastEvent.downloadOverdue)")
    print("--------------------------------------")
}
Run Code Online (Sandbox Code Playgroud)


Fab*_*ian 1

我不知道有什么简单的方法可以在每个分段请求发生时收到通知。您应该查看AVPlayerItemaccessLog属性并查看日志中的AVPlayerItemAccessLogEvents 。这些将描述网络和播放事件。如果这种方法适合您的需求,我强烈推荐它。

另一种方法是将您的应用程序设置为 HTTP 服务器,并将AVURLAsset/AVPLayerItem指向本地服务器,然后本地服务器必须将这些请求转换到外部服务器。这要复杂得多、困难得多、容易出错,而且几乎肯定会产生糟糕的性能。请不要这样做。


附录:

您可能会想看看,AVAssetResourceLoaderDelegate因为它说您可以代表AVURLAsset. 不幸的是,它不会通过段加载器。它似乎用于播放列表、解密密钥和其他此类资产。