7

我有一个 AVPlayer 正在流式传输实时 HLS 流。

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

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

谢谢!

4

7 回答 7

8

我用:

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

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

于 2012-12-15T13:43:24.987 回答
3

假设 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)];
于 2015-11-19T02:05:38.793 回答
2

Igor Kulagin的 Swift 版本回答:

player.seek(to: kCMTimePositiveInfinity)
player.play()

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

于 2018-01-09T16:09:15.170 回答
1

斯威夫特 3.0 版本

public func resumeLive() {
    guard let livePosition = player.currentItem?.seekableTimeRanges.last as? CMTimeRange else {
        return
    }
    player.seek(to:CMTimeRangeGetEnd(livePosition))
}
于 2017-03-23T05:02:23.807 回答
0

斯威夫特 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()
    })
}
于 2020-04-30T20:45:16.207 回答
0

快速版本的 Karim Mourra 的回答:

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)
于 2016-03-29T00:36:17.567 回答
0

CMTimeRange如果您使用 Apple 的操作函数,则无需转换为浮点数:

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 的评论

于 2016-03-30T18:40:52.970 回答