<source>标签不支持网速感知切换,仅静态适配;ABR需HLS/DASH+JS播放器,依赖服务端切片与多码率索引,可实时响应网络变化。

source标签本身不支持网速感知切换
<source> 标签只在视频首次加载时参与一次资源选择,它没有运行时能力,也无法读取 navigator.connection.effectiveType 或 downlink。所谓“根据网速自动切换”,必须由 JavaScript 主动干预——<source> 仅适合静态适配(如按屏幕宽度选源),不能做 ABR(自适应码率)。
真正能响应网速的只有 HLS/DASH + JS 播放器
原生 <video> 加 <source> 组合无法实现带宽感知切换;要自动降级/升级清晰度,必须用流式协议:
- HLS(
.m3u8):Safari 原生支持,Chrome/Firefox 需hls.js - DASH(
.mpd):需dash.js或 MediaSource API 手动实现 - 两者都依赖服务端切片 + 多码率索引文件,浏览器或播放器按秒级分片动态选流
- 切换过程无黑屏、可边下边播,且能监听
connection.onchange实时响应网络变化
如果坚持用 MP4 多源,JS 必须手动接管全部逻辑
用多个 MP4 文件模拟“多清晰度”可行,但不是自动的,每一步都得写死:
- 调用
video.currentTime和video.paused保存当前状态 - 设置
video.src = 'video-720p.mp4'后必须立即调用video.load() - 等
loadedmetadata事件触发后再设video.currentTime,否则 Safari 可能 seek 失败 - 用
navigator.connection.effectiveType判断网速(注意:部分安卓 WebView 不支持该 API) - 不要只看
effectiveType,结合downlink(单位 Mbps)更可靠:比如downlink 强制切 360p
容易被忽略的兼容性陷阱
很多方案在开发环境跑通,上线就失效,关键点在于:
立即学习“前端免费学习笔记(深入)”;
- iOS Safari 对
media属性里的min-resolution或device-pixel-ratio完全忽略,只认width/height查询 - MP4 文件若未对齐关键帧,切换后音画不同步——所有分辨率版本必须用相同 GOP 设置重新编码
- 直接替换
src后调play()而不等loadeddata,在低端 Android 上大概率报错DOMException: The element has no supported sources - CDN 缓存可能把低清版缓存成默认响应,导致 JS 切换后仍返回旧文件——需确保 URL 带版本参数或 cache-control 正确



















