简体   繁体   English

iOS 上的 HLS AVPlayer - 回归直播

[英]HLS AVPlayer on iOS - return to live

I have an AVPlayer which is streaming a live HLS stream.我有一个 AVPlayer 正在流式传输实时 HLS 流。

When the user multitasks the app, I see the play rate drop to 0.0 (paused), when the user comes back it return to 1.0(play), but starts playing from the point it was paused.当用户对应用程序进行多任务处理时,我看到播放速率下降到 0.0(暂停),当用户回来时它返回到 1.0(播放),但从暂停点开始播放。

What is the best way to force the player back to live without restarting the stream completely?在不完全重新启动流的情况下强制播放器恢复活动的最佳方法是什么? Is there a seekToTime method that handles a closest to live time parameter?是否有处理最接近实时时间参数的 seekToTime 方法?

Thanks!谢谢!

I use:我用:

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

Works well in my app.在我的应用程序中运行良好。

Assuming player is an AVPlayer instance:假设 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)];

Swift version of Igor Kulagin answer: Igor Kulagin的 Swift 版本回答:

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

Works perfectly in any condition.在任何条件下都能完美工作。 Other solutions gave me NaN error calculating livePosition value, or {INVALID} error working directly with CMTime .其他解决方案给了我计算livePosition值的NaN错误,或者直接与CMTime一起工作的{INVALID}错误。

Swift 3.0 Version斯威夫特 3.0 版本

public func resumeLive() {
    guard let livePosition = player.currentItem?.seekableTimeRanges.last as? CMTimeRange else {
        return
    }
    player.seek(to:CMTimeRangeGetEnd(livePosition))
}

Swift version of Karim Mourra's answer:快速版本的 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)

No need to convert to floating point if you use Apple's CMTimeRange manipulation functions:如果您使用 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
}

Please see @Fabian's comment below.请参阅下面的@Fabian 评论

Swift 4 version:斯威夫特 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()
    })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM