localstorage实现音视频断点续播需“存得准、读得稳、跳得对”:节流保存+pause/ended/beforeunload事件双保险;等loadedmetadata后再恢复时间;音视频key隔离;统一id保障跨页连续性。

用 localStorage 实现音视频断点续播,核心是“存得准、读得稳、跳得对”。它不依赖后端,适合游客模式或轻量级应用,关键在于抓住播放状态变化的几个可靠时机,避免频繁写入和时机错位。
保存进度:节流 + 关键事件双保险
不要在 timeupdate 里每秒都写 localStorage——性能差,还容易因页面卡顿或快速拖拽导致时间值不准。推荐组合策略:
- 每 5–10 秒节流保存一次最新
currentTime,用setTimeout或防抖函数控制 - 监听
pause事件,用户手动暂停时立即落盘,确保意图明确 - 监听
ended事件,播放完成即清除对应 key(避免下次误恢复) - 必须监听
beforeunload,这是关闭标签页、刷新或跳转前最后可靠的同步写入机会
恢复播放:等元数据就绪再设置时间
页面加载后不能一上来就改 video.currentTime,否则视频还没解析出时长(duration 是 NaN 或 0),设置会静默失败。正确做法是:
- 在
video元素上监听loadedmetadata事件 - 事件触发后,从 localStorage 读取对应视频的进度(如
localStorage.getItem(`resume_${videoId}`)) - 检查该时间是否合法(
savedTime ),再赋值给 <code>currentTime - 若已获用户交互授权(如用户点过播放按钮),可紧接着调用
play();否则仅设时间,由用户后续操作触发播放
区分音视频:ID 命名与存储隔离
音频和视频共用 localStorage 容易互相覆盖。建议按媒体类型+唯一标识构建 key:
- 视频:用
video_resume_${urlHash}或video_resume_${data-id} - 音频:用
audio_resume_${trackId},尤其在多曲目播放器中更需明确区分 - 如果同一页面有多个媒体元素,每个都应有独立 ID,避免一个暂停影响另一个的记录
跨页面连续性:靠统一 ID 和主动同步
用户从视频页跳到评论页再返回,只要 videoId 不变,就能延续进度。但要注意:
- 所有相关页面使用完全相同的 ID 生成逻辑(比如都取 URL 的 pathname + search,或服务端注入的 data-id)
- 若页面跳转不刷新(如 SPA 路由),可在路由守卫中主动读取并设置
currentTime - 不依赖
visibilitychange做主保存逻辑(它可能延迟或不触发),只作为补充,比如页面切后台超 30 秒再存一次











