HTML5原生不支持RTSP,所谓“多分辨率切换”需依赖服务端转协议(如RTSP→HLS或WebRTC);HLS方案用hls.js解析master.m3u8并手动切换levels,WebRTC则需服务端支持simulcast或多URL流。

HTML5 原生不支持 RTSP 协议,所以不存在“HTML5 播放 RTSP 多分辨率切换”这回事——浏览器根本不会解析 rtsp:// 地址,直接报错或静默失败。
为什么 标签无法播放 RTSP
RTSP 是一个基于 TCP/UDP 的会话控制协议,不传输实际音视频数据(那是 RTP 干的),而 HTML5 只支持 HTTP(S) 下载或流式传输的媒体格式(如 MP4、WebM、HLS、DASH)。RTSP 缺少浏览器原生解码和网络栈支持。
常见错误现象:Media resource failed to load、DOMException: The element has no supported sources,或者控制台完全无日志但画面黑屏。
你看到的“能播 RTSP”的页面,背后一定做了协议转换:
立即学习“前端免费学习笔记(深入)”;
- 用 FFmpeg 或 GStreamer 在服务端把 RTSP 转成 HLS(
.m3u8+.ts)或 WebRTC 流 - 用 WebSocket + 自定义 JS 解码器(如 wasm-ffmpeg)在前端解析 RTP 包(极少见、高延迟、兼容性差)
- 嵌入第三方 WebRTC 客户端 SDK(如 Live555 + webrtc-streamer)
HLS 多分辨率切换:靠 EXT-X-STREAM-INF 实现
如果你走的是“RTSP → HLS”路径(最常见),多分辨率就取决于服务端生成的 HLS 清单是否包含多个变体流(variant streams)。浏览器本身不主动切换,需 JS 控制 src 或利用 的 src 动态赋值。
关键点:
- 服务端必须输出多码率 HLS,例如
master.m3u8内容含多个EXT-X-STREAM-INF条目,指向不同分辨率的子清单(如720p.m3u8、480p.m3u8) - 前端不能直接给
设src="master.m3u8"就完事——原生不解析主清单,只认具体子清单(Chrome/Firefox 对 HLS 支持有限,Safari 略好但也不支持自动切换) - 真正可行方案是用
hls.js(v1+):它能解析master.m3u8,暴露hls.levels和hls.currentLevel,允许手动切换
示例(使用 hls.js 切换):
const hls = new Hls();
hls.loadSource('https://example.com/master.m3u8');
hls.attachMedia(videoEl);
hls.on(Hls.Events.MANIFEST_PARSED, () => {
// 列出所有可用清晰度
console.log(hls.levels.map((l, i) => `${i}: ${l.height}p`));
// 切换到索引 1(比如 720p)
hls.currentLevel = 1;
});
WebRTC 方案下如何实现多分辨率
如果后端用 webrtc-streamer 或自研信令服务将 RTSP 推为 WebRTC,多分辨率控制权完全在服务端——WebRTC 本身不定义“多清晰度”,而是靠 SDP 中的 simulcast 或服务端按需编码多路轨道(track)。
前端操作要点:
- 服务端需支持 simulcast 或提供多个独立的
offer(如/stream?res=720p、/stream?res=480p) - 前端销毁旧
RTCPeerConnection,新建连接并请求对应分辨率的流,比 HLS 切换更重,有明显卡顿 - 无法像 HLS 那样平滑过渡;浏览器也不提供
video.srcObject的“质量等级”API
注意:RTCRtpSender.getParameters() 可读取当前发送参数,但不能用于接收端动态降级——接收方分辨率由远端编码决定。
容易被忽略的坑
多分辨率 ≠ 多 URL。很多用户以为只要准备几个不同分辨率的 RTSP 地址(如 rtsp://...?res=720),前端切 URL 就行——但这是无效的:RTSP URL 参数不改变流内容,只是服务端可能识别并触发不同转码任务,而这依赖服务端是否真实现了该逻辑。
更隐蔽的问题:
- HLS 的
master.m3u8里各子流时间戳未对齐 → 切换时音画不同步 - WebRTC 使用 VP8/VP9 时,某些安卓 WebView 不支持硬件解码多分辨率,软解直接卡死
-
hls.js的currentLevel设为 -1(自动)时,实际行为受网络带宽估算影响,未必按你预期切换
真正可控的方式,永远是服务端输出明确的、可独立加载的多分辨率流地址,并由前端精确控制加载时机——协议转换层(不是 HTML5)决定了你有没有“多分辨率”这个能力。










