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

时间:2017-06-10 14:35:17

标签: ios swift streaming hls

我正在Swift中为HLS实时流媒体编写一个iOS应用程序。我希望在回放期间启动每个HLS段请求时通知我的应用程序逻辑(以及相应的URL是什么)。我试图观察使用KVO对AVPlayer和AVPlayerItem的各种属性的更改。但是,它只会告诉我何时启动播放。例如,添加以下观察者会在回放开始时触发observeValue方法的调用,但我还没有找到一种方法可以不断通知每个段请求。

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

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

/乔治

2 个答案:

答案 0 :(得分:1)

我不知道在每个细分请求发生时都会收到通知的简单方法。您应该查看AVPlayerItem的{​​{3}}属性并查看日志中的accessLog。这些将描述网络和回放事件。如果符合您的需求,我强烈推荐这种方法。

另一种方法是将您的应用程序设置为HTTP服务器,并在本地服务器上指向AVURLAsset / AVPLayerItem,然后必须将这些请求转换为外部服务器。这更加复杂,困难,容易出错,几乎可以保证性能不佳。请不要这样做。

附录:

您可能很想看AVPlayerItemAccessLogEvents,因为它表示您可以代表AVURLAsset处理资源请求。不幸的是,它不会通过装载程序进行分段。它似乎适用于播放列表,解密密钥和其他此类资产。

答案 1 :(得分:0)

当我需要调试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("--------------------------------------")
}