html5 的 duration 属性不能可靠判断直播流,因其初始常为 nan 或 infinity,且跨浏览器不一致;应结合 url 协议、seekable 范围及服务端标识综合识别。

HTML5 <video></video> 标签的 duration 属性**不能可靠判断媒体是否为直播流**。它只是一个只读属性,反映浏览器当前能获取到的媒体总时长(单位:秒),而直播流的时长特性与该值的表现存在根本性矛盾。
Duration 属性在直播场景下的典型表现
对于直播流(如 HLS、DASH 或 WebRTC 推流):
-
初始值通常为
NaN:浏览器尚未解析出任何可预估的总时长,因为直播没有“结束点”; -
部分播放器或服务可能返回
Infinity(尤其在 MSE + HLS.js / dash.js 等环境下),表示“持续进行中”; - 极少数 CDN 或封装方式可能伪造一个大数值(如 2147483647)作为“无限”占位符**,但这不是标准行为,不可依赖。
为什么不能单靠 duration 判断直播?
原因在于语义和实现差异:
-
duration是媒体资源元数据的一部分,由浏览器根据容器头(如 MP4 的moov)或协议反馈(如 HLS 的#EXT-X-TARGETDURATION和分片列表)推导而来,并非主动探测机制; - VOD 文件即使未加载完成,也可能提前暴露
duration(如 MP4 有前置moov); - 某些直播服务会动态更新
duration(例如模拟“当前已播出时长”),导致其随时间缓慢增长,但这种行为非标准、不统一; - 移动端 Safari 对 HLS 直播常返回
NaN,而 Chrome + MSE 可能返回Infinity——跨浏览器结果不一致。
更可靠的直播流识别方式
应结合协议特征、加载行为与上下文信息综合判断:
-
检查
srcURL 后缀与协议特征:如含.m3u8(HLS)、.mpd(DASH)、或使用MediaSource动态追加片段,大概率是直播; -
监听
loadedmetadata后检查duration值:if (isNaN(video.duration) || !isFinite(video.duration))是较实用的启发式线索(但仍需配合其他条件); -
观察
seekable时间范围:直播流的video.seekable.end(0)通常接近video.currentTime,且start可能 > 0(表示仅支持最近 N 分钟回看); -
服务端标识或自定义属性:在
<video data-stream-type="live"></video>中显式标注,是最稳定可控的方式。
实际代码示例(辅助判断)
以下逻辑仅作参考,须结合业务场景校验:
const video = document.querySelector('video');
video.addEventListener('loadedmetadata', () => {
const isLikelyLive = isNaN(video.duration) || video.duration === Infinity;
const hasSeekableEndNearNow = video.seekable.length > 0 &&
Math.abs(video.seekable.end(0) - video.currentTime) if (isLikelyLive && hasSeekableEndNearNow) {
console.log('推测为直播流');
// 可禁用进度条拖拽、隐藏剩余时间等 UI 调整
}
});
不复杂但容易忽略:duration 是结果,不是原因;判断直播的关键,在于理解流的生成方式与传输协议,而非仅仅读取一个属性值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











