【发布时间】:2016-07-27 17:20:18
【问题描述】:
我正在使用 AVPlayer 播放直播。此流支持一小时追赶,这意味着用户可以搜索到一小时前并播放。但是我有一个问题,我如何知道玩家正在打的准确位置。我需要在播放器视图上显示当前位置。例如,如果用户半小时前正在玩,则显示-30:00;如果用户正在播放最新内容,播放器将显示 00:00 或直播。谢谢
【问题讨论】:
标签: ios avplayer http-live-streaming
我正在使用 AVPlayer 播放直播。此流支持一小时追赶,这意味着用户可以搜索到一小时前并播放。但是我有一个问题,我如何知道玩家正在打的准确位置。我需要在播放器视图上显示当前位置。例如,如果用户半小时前正在玩,则显示-30:00;如果用户正在播放最新内容,播放器将显示 00:00 或直播。谢谢
【问题讨论】:
标签: ios avplayer http-live-streaming
要获得实时位置毒药并寻找它,您可以使用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;
【讨论】:
快速解决方案:
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;
}
【讨论】:
我知道这个问题很老,但我有同样的要求,我相信解决方案没有正确解决问题的意图。
我为同样的要求所做的是收集当前时间点、开始时间和流的总持续时间的长度。
在继续之前我会解释一下,当前时间点可能会超过(开始时间 + 总持续时间),这是由于 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 个值,你可能必须如果你想添加所有范围的持续时间,使用哪个时间范围作为起始值等。至少对于我的用例来说,这已经足够了。
【讨论】: