必须在play()前设置currentTime,且需用户手势触发、等待loadedmetadata事件、处理play()返回的Promise拒绝;否则iOS Safari等浏览器会静音拦截或跳转失败。

play() 调用前必须先设置 currentTime
HTML5 play() 本身不接受起始时间参数,它只是触发播放。想从指定位置开始,得在调用 play() 前手动设置 currentTime 属性。
常见错误是先 play() 再设 currentTime,此时浏览器可能已从 0 秒开始解码和渲染,再改时间会触发重新加载或跳转延迟,甚至被部分浏览器(如 iOS Safari)静音策略拦截导致失败。
- 正确顺序:
video.currentTime = 12.5;→video.play(); -
currentTime单位是秒,支持小数(如3.75) - 设置后立即读取
currentTime可能仍为 0,因为尚未加载到该位置;应监听seeked事件确认就位
为什么有时设了 currentTime 还是从头播?
本质是媒体资源未缓冲到目标时间点,或浏览器拒绝非用户手势触发的自动播放 + 定位组合。
典型场景包括:页面加载完成就自动定位播放、定时器里调用、AJAX 回调中执行。这些都属于“非直接用户交互触发”,Chrome 和 Safari 会静默阻止。
立即学习“前端免费学习笔记(深入)”;
- 必须由用户真实操作(如
click、touchend)的回调中同步执行currentTime+play() - 视频需至少加载了目标时间附近的片段(可通过
video.buffered.end(0) > targetTime判断) - 若
readyState (即未达到HAVE_ENOUGH_DATA),设置currentTime会无效或抛错
play() 返回 Promise,要处理拒绝情况
现代浏览器中 play() 返回 Promise,失败时不会抛异常,而是 reject —— 比如因策略限制无法播放,或 currentTime 设置后还未就绪就调了 play()。
忽略这个 Promise 拒绝会导致静默失败,界面卡住无反馈。
video.currentTime = 30;
video.play().catch(err => {
console.warn("播放失败:", err.name); // 常见 err.name: "NotAllowedError", "AbortError"
// 可降级提示用户点击按钮重试
});
移动端特别注意:iOS Safari 的 currentTime 行为差异
iOS Safari 对 currentTime 设置极其保守:只有在 play() 成功后(即 Promise resolve 后),才允许再次设置 currentTime 并保证生效;首次设置必须紧贴用户手势,且不能早于 loadedmetadata 事件。
- 务必监听
loadedmetadata后再设置初始currentTime - 避免在
canplay或canplaythrough中过早设置,iOS 可能忽略 - 如果需要精确跳转,建议在
play()的 Promise resolve 回调里再设一次currentTime(即使和之前一样),iOS 更可靠
currentTime 就万事大吉,但没等元数据加载完、没走用户手势上下文、也没处理 Promise 拒绝 —— 这三者任意一个缺失,都会让“从某秒开始播”变成玄学。










