【问题标题】:HLS AVPlayer on iOS - return to liveiOS 上的 HLS AVPlayer - 回归直播
【发布时间】:2012-10-20 03:35:53
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

    标签: ios live avplayer http-live-streaming


    【解决方案1】:

    我用:

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

    在我的应用中运行良好。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 这才是真正的答案。像魅力一样为我工作。
      • 也可以用CMTimeAdd代替转浮点数
      • 您也可以使用 CMTimeRangeGetEnd 而不是将持续时间添加到开头。
      【解决方案3】:

      Igor Kulagin 的 Swift 版本回答:

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

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

      【讨论】:

      • 在 iOS 14 上这似乎不再起作用,必须使用 seekableTimeRanges 解决方案
      • 这在 iOS 14+ 上对我很有用。
      【解决方案4】:

      Swift 3.0 版本

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

      【讨论】:

        【解决方案5】:

        Karim Mourra 回答的 Swift 版本:

        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)
        

        【讨论】:

        • 守卫让 lastRange = player.currentItem?.seekableRanges.last else { return; } player.seekToTime(lastRange.end)
        • 什么是“时间偏移”?
        • @HongZhou 在几秒钟内它是一个完全可选的缓冲区。您可以只使用livePosition 并省略带有timeOffset 的行。
        【解决方案6】:

        如果您使用 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 的评论点赞

        【讨论】:

        • 使用CMTimeRangeGetEnd不需要加时间
        【解决方案7】:

        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()
            })
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-11-17
          • 2012-11-10
          • 1970-01-01
          • 2013-10-24
          • 2020-10-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多