监听 loadedmetadata 事件是获取网页视频真实尺寸最可靠的方式,需设置 preload="metadata"、服务端支持字节范围请求,并在设置 src 后立即绑定事件;回调中读取 video.videoWidth/video.videoHeight 并校验有效性。

监听 loadedmetadata 事件是获取网页视频真实尺寸(宽高)最可靠的方式——它在浏览器解析完视频文件头(如 MP4 的 moov box)后立即触发,此时 video.videoWidth 和 video.videoHeight 才有稳定、有效的像素值。
确保 preload 属性正确设置
必须给 <video> 标签显式声明 preload="metadata":
- 这是关键前提,告诉浏览器只请求元数据(尺寸、时长、编码等),不下载画面帧,节省带宽且响应快
- 不要用
preload="none"(首次播放才加载元数据)或preload="auto"(iOS Safari 实际忽略,等同于 none) - 服务端需支持字节范围请求(响应头含
Accept-Ranges: bytes),否则可能退化为下载整个文件前几 KB
绑定事件要“早”且“准”
监听必须在设置 src 后立刻进行,不能等到页面完全加载或用户交互后再加:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 推荐写法:
video.src = 'xxx.mp4'; video.addEventListener('loadedmetadata', handler); - 如果使用动态插入的
<video>元素(如 JS 创建),即使写了preload="metadata",也需手动调用video.load()才能触发预加载 - 避免在
DOMContentLoaded或window.onload中才绑定——缓存资源可能已触发事件却无人接收
读取尺寸并做基础校验
在事件回调中安全读取,同时处理常见异常:
- 直接访问
video.videoWidth和video.videoHeight,它们是只读属性,单位为像素 - 用
if (video.videoWidth > 0 && video.videoHeight > 0)做基本有效性判断,避免 0 值干扰后续逻辑 - 计算宽高比建议保留小数(如
video.videoWidth / video.videoHeight),不要四舍五入成整数比(如 16/9),因实际可能是 1.777… - 若值仍为 0,可检查
video.readyState是否 ≥HTMLMediaElement.HAVE_METADATA,或加 5 秒超时兜底
常见失效原因与应对
如果 loadedmetadata 没触发或尺寸始终为 0,优先排查底层问题:
- iOS Safari 会强制禁用
preload,可配合<link rel="preload" as="video" href="xxx.mp4">主动预热(仅限同域) - 用户开启低电量模式或省流量设置时,Chrome/Firefox 可能跳过 metadata 缓冲,需监听
durationchange作为补充时机 - MP4 文件未用
ffmpeg -c copy -movflags +faststart把moov箱移到开头,会导致时长和尺寸读取失败 - CORS 限制或跨域资源未配
crossorigin属性,也会阻断元数据加载

















