const sent = new Set();
video.addEventListener('timeupdate', () => {
  [25,50,75].forEach(p => { if (!sent.has(p) && video.currentTime / video.duration >= p/100) { sent.add(p); track(p); } });
});

后台播放报表里同一用户 25% 进度记了 3 次,50% 记了 4 次,拖动进度条之后还会补报几条。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:timeupdate 每次触发都判断区间,没有记录已上报的标记,来回拖动就会重复命中。多个播放器实例也各自监听同一个事件。

「播放进度上报重复」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。

把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。改完隔一天再看一次,当场正常不代表能稳住。

处理上按这个顺序:用 Set 记录已经上报过的进度点;判断时要求当前时间大于上次 避免回拖重复;主动 seek 后重置标记 与缓冲区分开。

确认没问题再收工,同一次播放每个进度点只上报一条,拖动进度条不再产生重复记录。

作者 9823189