【问题标题】:How to get the accurate time position of a live streaming in avplayer如何在avplayer中获取直播的准确时间位置
【发布时间】:2016-07-27 17:20:18
【问题描述】:

我正在使用 AVPlayer 播放直播。此流支持一小时追赶,这意味着用户可以搜索到一小时前并播放。但是我有一个问题,我如何知道玩家正在打的准确位置。我需要在播放器视图上显示当前位置。例如,如果用户半小时前正在玩,则显示-30:00;如果用户正在播放最新内容,播放器将显示 00:00 或直播。谢谢

【问题讨论】:

    标签: ios avplayer http-live-streaming


    【解决方案1】:

    要获得实时位置毒药并寻找它,您可以使用seekableTimeRanges of AVPlayerItem

    CMTimeRange seekableRange = [player.currentItem.seekableTimeRanges.lastObject CMTimeRangeValue];
    CGFloat seekableStart = CMTimeGetSeconds(seekableRange.start);
    CGFloat seekableDuration = CMTimeGetSeconds(seekableRange.duration);
    CGFloat livePosition = seekableStart + seekableDuration;
    
    [player seekToTime:CMTimeMake(livePosition, 1)];
    

    另外当你回溯一段时间时,你可以通过调用currentTime方法获取当前播放位置

    CGFloat current = CMTimeGetSeconds([self.player.currentItem currentTime]);
    CGFloat diff = livePosition - current;
    

    【讨论】:

    • 很好的解决方案,但我很好奇为什么 (AVPlayerItem:loadedTimeRanges start + duration) 的值在我的情况下比 livePosition 略大
    【解决方案2】:

    快速解决方案:

       override func getLiveDuration() -> Float {
        var result : Float = 0.0;
    
        if let items = player.currentItem?.seekableTimeRanges {
    
            if(!items.isEmpty) {
                let range = items[items.count - 1]
                let timeRange = range.timeRangeValue
                let startSeconds = CMTimeGetSeconds(timeRange.start)
                let durationSeconds = CMTimeGetSeconds(timeRange.duration)
    
                result = Float(startSeconds + durationSeconds)
            }
    
        }
        return result;
    }
    

    【讨论】:

    • 这对我来说非常有效,但这次的准确性只有 10 秒的片段。所以结果总是十的倍数,而不是更准确的时间点。你知道有什么方法可以更精确地衡量用户落后于直播多远吗?
    • @AllanWeir 您能否与为您提供实时源的内容团队讨论,尝试修改 m3u8 播放列表清单上的片段​​持续时间?
    【解决方案3】:

    我知道这个问题很老,但我有同样的要求,我相信解决方案没有正确解决问题的意图。

    我为同样的要求所做的是收集当前时间点、开始时间和流的总持续时间的长度。

    在继续之前我会解释一下,当前时间点可能会超过(开始时间 + 总持续时间),这是由于 hls 被构造为 ts 段的方式。 Ts 片段是可播放视频的小片段,您可以在可搜索范围内拥有 5 个 ts 片段,每个片段 10 秒。这并不意味着 50 秒是直播的全部长度,大约还有一个完整的片段(因此总共 60 秒的播放时间),但它不被归类为可搜索,因为您不应该搜索该片段。如果您这样做,您会在大多数情况下注意到重新缓冲(因为当您已经到达播放结束时,源可能仍在创建下一个 ts 片段)。

    我所做的是检查当前流时间是否超过可搜索的范围,如果是,则意味着正在直播。如果不是,您可以通过减去当前时间、开始时间和总时长,轻松计算出您与直播之间的距离。

    let timeRange:CMTimeRange = player.currentItem?.seekableTimeRanges.last
    let start = timeRange.start.seconds
    let totalDuration = timeRange.duration.seconds
    let currentTime = player.currentTime().seconds
    let secondsBehindLive = currentTime - totalDuration - start
    

    上面的代码会给你一个负数,表示“live”之后的秒数,或者更具体地说,是最后一个 ts 段的开始。播放最新的 ts 片段时为正数或零。

    Tbh 我真的不知道 seekableTimeRanges 什么时候会有超过 1 个值,对于我测试过的流来说,它一直只有一个,但是如果你在流中发现超过 1 个值,你可能必须如果你想添加所有范围的持续时间,使用哪个时间范围作为起始值等。至少对于我的用例来说,这已经足够了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 2012-07-12
      • 2018-03-06
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      相关资源
      最近更新 更多