HTML5原生video不支持运行时清晰度切换,需通过替换src、切换source或MSE(HLS/DASH)实现;MP4切换有黑屏风险,HLS/DASH才是自适应首选。

HTML5 本身不支持运行时切换清晰度
浏览器原生 元素没有内置的「清晰度切换」能力,quality、res 这类属性并不存在于标准中。所谓“切换清晰度”,本质是**替换 src 或切换 元素**,或使用 MSE(Media Source Extensions)动态加载不同码率的分片(如 HLS/DASH)。直接改 video.src 最简单,但有黑屏、卡顿、丢失播放进度等风险。
用 JavaScript 切换 并重新加载
适用于预置几档固定分辨率 MP4 文件的轻量场景。关键点不是只改 src,而是触发 load() 并手动恢复播放状态:
- 先保存当前
video.currentTime和video.paused状态 - 替换
video.src或清空/重写后调用video.load() -
load()触发loadedmetadata事件后,再seekTo()并按需play() - 注意:Safari 对 MP4 的
load()后 seek 支持不稳定,可能跳回开头
HLS 或 DASH 才真正支持自适应清晰度切换
MP4 是单一文件,无法动态调整;而 HLS(.m3u8)和 DASH(.mpd)是索引+分片协议,播放器可实时选择不同码率的片段。浏览器原生仅支持 HLS(iOS/macOS Safari),DASH 需靠 dash.js 或 hls.js 这类 JS 库。
-
hls.js在 Chrome/Firefox/Edge 中模拟 HLS 支持,提供hls.levels和hls.currentLevelAPI - 设置
hls.currentLevel = index即可切换,库会自动处理缓冲、无缝过渡(若时间戳对齐) - DASH 需引入
dash.js,通过player.getBitrateInfoList()和setQualityFor('video', level) - 务必开启 CORS,否则分片请求会被跨域拦截
手动实现清晰度菜单时容易忽略的细节
很多开发者只关注“能切”,却在体验上翻车:
立即学习“前端免费学习笔记(深入)”;
- 切换前未检查新清晰度资源是否已加载元数据(
readyState 时currentTime设置无效) - 未禁用切换按钮直到
loadeddata触发,导致用户连点多次引发竞态 - 移动端 iOS Safari 下,
play()必须由用户手势触发,不能在异步回调里静默调用 - 如果视频启用了
controls,自定义清晰度按钮建议用display: none隐藏原生控件,避免 UI 冲突 - HTTP Range 请求头缺失会导致 MP4 切换时从头加载——确保服务端支持
Accept-Ranges: bytes
hls.js 加一个 .m3u8 主清单,几乎是最省心、兼容性最好、体验最接近原生的路径。











