You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVPlayer播放HLS直播流初始currentTime返回异常值问题咨询

iOS AVPlayer播放带时移HLS直播时初始currentTime异常偏小问题

问题背景

iOS端基于AVPlayer实现HLS流播放时,点播场景下的进度拖动、播放、暂停、进度回调功能均运行正常,仅支持时移能力的直播素材存在初始播放阶段currentTime获取异常的问题。

核心实现代码

public final class CustomPlayer: AVPlayer {
    static let periodicTimeObserverPeriod = 0.5
    
    var timeObserverToken: Any?

    // 其他方法和参数
    
    override public func replaceCurrentItem(with item: AVPlayerItem?) {
        super.replaceCurrentItem(with: item)
        removePeriodicTimeObserver()
        if let item = item {
            addPeriodicTimeObserver()
        }
    }
    
    private func addPeriodicTimeObserver() {
        let time = CMTime(seconds: CustomPlayer.periodicTimeObserverPeriod, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
        timeObserverToken = self.addPeriodicTimeObserver(forInterval: time, queue: .main, using: { [weak self] currentTime in
            guard let self = self else {
                return
            }
            print("NEW TIME in periodicTimeObserver: \(CMTimeGetSeconds(currentTime))")
            // 更新播放位置等业务逻辑
        })
    }
    
    private func removePeriodicTimeObserver() {
         // 已实现周期观察者移除逻辑
    }

}

异常复现流程

测试用直播素材支持60分钟时移,即用户最多可从当前最新直播点位往回追溯60分钟的历史内容,异常可按以下步骤稳定复现:

  • 初始进入播放页,从最新直播点位开始播放该素材
  • 此时周期时间观察者回调返回的currentTime为20秒左右的异常偏小值,日志输出示例:
    • NEW TIME in periodicTimeObserver: 20.13
    • NEW TIME in periodicTimeObserver: 20.72
  • 手动回退约30分钟观看时移内容,播放功能正常,此时回调返回的currentTime为1800秒左右的合理值,日志输出示例:
    • NEW TIME in periodicTimeObserver: 1805.56
    • NEW TIME in periodicTimeObserver: 1806.21
  • 再次seek回最新直播点位观看,回调返回的currentTime为3600秒左右的数值,日志输出示例:
    • NEW TIME in periodicTimeObserver: 3597.86
    • NEW TIME in periodicTimeObserver: 3598.31
  • 完成上述操作后,后续所有播放、时移操作的currentTime返回值均保持正常,符合60分钟时移窗口的时间范围规则(时间轴范围为[0, 3599],3599秒左右即为最新直播点位)

根因说明

该异常是AVPlayer对滑动窗口HLS直播流的初始加载逻辑导致的:
支持时移的HLS直播采用滑动播放窗口机制,初始拉流时AVPlayer不会立刻拉取完整60分钟窗口的全部分片索引,只会先拉取窗口尾部(最新直播点位附近)的少量分片完成播放初始化,此时AVPlayer内部时间轴的原点是从首个加载到的分片起始位置开始计算的,没有对齐到时移窗口的0点,因此返回的currentTime只有几十秒的小值。
当用户主动触发时移seek操作后,AVPlayer才会拉取完整时移窗口的分片索引,重新校准内部时间轴原点,将时间轴映射到完整的0-3600秒区间,后续所有时间回调就会恢复正常。

排查与修复方向

  • 调整周期观察者添加时机:不要在replaceCurrentItem调用后立刻添加周期时间观察者,先监听当前AVPlayerItem的status属性,等状态变为.readyToPlay,同时确认item.duration为有效值(对应60分钟时移窗口,CMTimeGetSeconds(item.duration)应在3600秒左右),此时再添加观察者,避开初始时间轴未校准的阶段。
  • 增加时间值有效性校验:每次进度回调拿到currentTime后,先计算当前时间与总时长的差值,正常播放最新直播点位时,该差值等于播放器的直播缓存时长(通常在10-30秒区间);如果差值远超出这个范围(比如初始阶段总时长仅20余秒,差值接近0),说明时间轴未完成校准,直接丢弃本次回调的时间值,不做UI更新。
  • 监听时间轴校准事件:注册AVPlayerItemTimeJumped通知,收到该通知时说明AVPlayer内部调整了时间轴原点,此时主动拉取一次currentTime同步UI状态,覆盖初始校准完成的节点。
  • 核对HLS源配置:检查直播m3u8文件的EXT-X-PLAYLIST-TYPE、EXT-X-MEDIA-SEQUENCE、EXT-X-START标签配置,确认时移窗口的起始序号、长度声明正确,不存在初始返回分片列表序号偏移的问题。

内容的提问来源于stack exchange,提问作者Janek Podwysocki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:27:13