buffered 属性返回 timeranges 对象,用于描述已缓冲的时间段集合;其 length 表示段数,start(i) 和 end(i) 分别获取第 i 段起止时间;需用 end(length-1) 获取最远缓冲时间,且与 readystate、networkstate 无严格对应关系。

buffered 属性返回的是 TimeRanges 对象
buffered 是 HTMLMediaElement(如 <video></video> 或 <audio></audio>)的只读属性,它不返回数组、不返回布尔值,也不直接返回数字范围。它返回一个 TimeRanges 实例——这是浏览器原生的、不可构造的类,用于描述媒体资源中已加载(即已缓冲)的时间段集合。
这个对象本身没有 length 以外的可枚举属性,所有时间信息必须通过其方法访问:
-
buffered.length:已缓冲的连续时间段个数(可能为 0) -
buffered.start(index):第index段的起始时间(秒,浮点数) -
buffered.end(index):第index段的结束时间(秒,浮点数)
常见误判:buffered.length === 0 不代表没加载
刚设置 src 后立即读取 buffered,大概率拿到 length === 0,但这不表示“一点都没缓冲”。原因有二:
- 浏览器尚未触发预加载策略(例如
preload="none"时,buffered始终为空,直到用户主动播放) -
buffered只反映已解码并存入内存的帧范围,而网络层可能已下载更多字节(但未送入解码器) - 某些浏览器(如 Safari)对
buffered的更新有延迟,需监听progress或timeupdate事件后再查
如何安全获取当前已缓冲的最远时间点
多数场景下,你真正关心的是“用户拖到哪能立刻播放”,即最后一个缓冲段的 end 值。但不能直接用 buffered.end(0) ——因为可能存在多个不连续段(如跳播后产生碎片缓冲):
function getBufferedEnd() {
const buffered = video.buffered;
if (buffered.length === 0) return 0;
return buffered.end(buffered.length - 1);
}
注意:buffered.end(i) 返回的是媒体时间轴上的绝对时间(单位秒),与视频是否设置了 currentTime 无关;它也不受 playbackRate 影响。
buffered 与 readyState、networkState 的关系容易混淆
buffered 描述“哪些时间范围已准备好播放”,而:
-
readyState表示媒体元素整体就绪程度(如HAVE_METADATA仅表示头信息加载完,此时buffered.length很可能还是 0) -
networkState反映网络连接状态(如NETWORK_LOADING时buffered可能正在增长,但未必连续) - 三者无严格先后顺序:
buffered.length > 0时readyState仍可能是HAVE_CURRENT_DATA(无法播放下一帧)
真正决定能否播放的是 readyState >= HAVE_FUTURE_DATA 且 buffered 覆盖了 currentTime 所在位置——这点常被忽略,导致“明明有缓冲却卡住”的调试困境。










