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

如何获取HTMLMediaElement执行seek操作前的currentTime值

可行方案

最稳定的实现方式是拦截视频元素currentTime的赋值操作,从属性修改的源头捕获跳转前的时间值,完全不受浏览器事件触发顺序影响,在Safari默认播放器场景下可以稳定拿到你要的结果。

实现代码

const video = document.querySelector('#myvideo');
let preSeekTime = 0;

// 拿到原生currentTime的属性方法
const nativeCurrentTime = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'currentTime');

// 重写当前video实例的currentTime属性
Object.defineProperty(video, 'currentTime', {
  get() {
    return nativeCurrentTime.get.call(this);
  },
  set(targetTime) {
    // 非seeking状态下的赋值,就是seek操作触发的修改,此时先存下旧值
    if (!this.seeking) {
      preSeekTime = nativeCurrentTime.get.call(this);
    }
    return nativeCurrentTime.set.call(this, targetTime);
  },
  configurable: true
});

// 后续任意事件回调里都能拿到正确的跳转前时间
video.addEventListener('seeking', () => {
  console.log('seek前的播放时间:', preSeekTime); // 对应你举的例子,这里会输出7
});

普通缓存方案失效的原因

你之前靠timeupdate缓存时间的方案不生效,是因为Safari处理seek操作的内部执行顺序是:

  • 内部直接把currentTime修改为跳转目标值
  • 触发timeupdate事件,你缓存的变量会被更新为新的时间值
  • 触发pause事件
  • 依次触发seeking、seeked事件
    等你在pause或者seeking回调里读缓存值的时候,旧值已经被提前触发的timeupdate覆盖了,自然拿不到想要的结果。

方案优势

  • 不依赖浏览器事件触发顺序,就算后续Safari调整事件触发的先后逻辑,功能也不会失效
  • 没有定时器、轮询这类额外性能开销,完全不影响视频原有播放功能
  • 兼容所有支持ES5属性拦截的浏览器版本,覆盖所有上线的Safari正式版本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:15:33