iOS上的HLS AVPlayer-返回现场

iOS上的HLS AVPlayer-返回现场,ios,live,avplayer,http-live-streaming,Ios,Live,Avplayer,Http Live Streaming,我有一个AVPlayer,它正在直播HLS流 当用户多任务处理应用程序时,我看到播放速率下降到0.0(暂停),当用户返回时,它返回到1.0(播放),但从暂停点开始播放 在不完全重新启动流的情况下,强制玩家恢复活动的最佳方式是什么?是否有处理最接近实时参数的seekToTime方法 谢谢 我使用: double time = MAXFLOAT; [player seekToTime: CMTimeMakeWithSeconds(time, NSEC_PER_SEC)]; 在我的应用程序中运行

我有一个AVPlayer,它正在直播HLS流

当用户多任务处理应用程序时,我看到播放速率下降到0.0(暂停),当用户返回时,它返回到1.0(播放),但从暂停点开始播放

在不完全重新启动流的情况下,强制玩家恢复活动的最佳方式是什么?是否有处理最接近实时参数的seekToTime方法

谢谢

我使用:

 double time = MAXFLOAT;
 [player seekToTime: CMTimeMakeWithSeconds(time, NSEC_PER_SEC)];

在我的应用程序中运行良好。

假设player是AVPlayer实例:

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)];

卡里姆·莫拉答案的快速版本:

let seekableRanges = player.currentItem!.seekableTimeRanges
guard seekableRanges.count > 0 else {
  return
}

let range = seekableRanges.last!.CMTimeRangeValue
let livePosition = range.start + range.duration

let minus = CMTimeMakeWithSeconds(Float64(timeOffset), Int32(NSEC_PER_SEC))
let time = livePosition - minus

player.seekToTime(time)

如果使用Apple的
CMTimeRange
操作功能,则无需转换为浮点:

NSValue *value = player.currentItem.seekableTimeRanges.lastObject;
if (value) {
    CMTimeRange seekableRange = [value CMTimeRangeValue];
    CMTime latestTime = CMTimeRangeGetEnd(seekableRange);
    [player seekToTime:latestTime];
} else {
    // there are no seekable time ranges
}
编辑:请更新以下Fabian的评论

Swift 3.0版

public func resumeLive() {
    guard let livePosition = player.currentItem?.seekableTimeRanges.last as? CMTimeRange else {
        return
    }
    player.seek(to:CMTimeRangeGetEnd(livePosition))
}
答案的快速版本:

在任何情况下都能完美工作。其他解决方案给了我
NaN
错误计算
livePosition
值,或者
{INVALID}
错误直接使用
CMTime

Swift 4版本:

if let seekableRange = player.currentItem?.seekableTimeRanges.last?.timeRangeValue {
    let seekableStart = seekableRange.start
    let seekableDuration = seekableRange.duration
    let livePosition = seekableStart + seekableDuration

    player.seek(to: livePosition, completionHandler: { [weak self] _ in
        self?.player.play()
    })
}

这才是真正的答案。你也可以使用CMTimeAdd而不是转换为浮点。你也可以使用CMTimeRangeGetEnd而不是将持续时间添加到start.guard let lastRange=player.currentItem?.seekablranges.last else{return;}player.seekToTime(lastRange.end)什么是“时间偏移”?@HongZhou这是一个完全可选的缓冲区,只需几秒钟。您可以只使用
livePosition
并省略带有
timeOffset
的行。如果您使用CMTimeRangeGetEndon iOS 14,则无需添加时间。这似乎不再有效,必须使用SeekableMelementes解决方案
if let seekableRange = player.currentItem?.seekableTimeRanges.last?.timeRangeValue {
    let seekableStart = seekableRange.start
    let seekableDuration = seekableRange.duration
    let livePosition = seekableStart + seekableDuration

    player.seek(to: livePosition, completionHandler: { [weak self] _ in
        self?.player.play()
    })
}