HTML5原生不支持RTSP协议,必须通过服务端转流为HLS或WebRTC等浏览器兼容格式;断流重连需前后端协同,HLS依赖hls.js重试机制,WebRTC需处理信令保活、SDP更新与ICE重启。

HTML5 原生不支持 RTSP 协议,所以所谓“HTML5 播放 RTSP”本质上是靠服务端转协议(如转成 WebRTC、HLS 或 MSE 兼容的格式),再由前端加载。断流重连不是前端单方面能解决的问题,必须前后端协同设计。
为什么直接 无法播放 RTSP
RTSP 是会话控制协议,依赖 TCP/UDP 传输 RTP 包,而浏览器 标签只支持 HTTP(S) 资源(如 MP4、WebM)或 MSE(Media Source Extensions)喂入的 fragmented MP4/WebM 流,不解析 RTSP 握手、SETUP、PLAY 等指令。
- 常见错误现象:
DOMException: The element has no supported sources或静音黑屏无报错 - 误以为加个
src="rtsp://..."就能播 —— 实际上所有现代浏览器都会忽略该 URL 并静默失败 - 某些旧版 Electron 或定制内核浏览器可能支持,但不可移植、不推荐用于生产
可行路径:服务端转流 + 前端 MSE / WebRTC 重连
主流方案只有两类,选型取决于延迟容忍度和部署能力:
-
HLS 方案:用 FFmpeg 或 GStreamer 拉 RTSP,切片为
.ts+.m3u8,前端用+hls.js;重连靠hls.js的retryDelay和maxMaxBufferLength控制,但首屏慢(通常 >10s)、断流后恢复至少 2–3 个切片周期 -
WebRTC 方案:用 Janus、Mediasoup、LiveKit 等信令服务器拉 RTSP,转为 VP8/VP9/H.264 over WebRTC;前端用
RTCPeerConnection接收;重连需监听iceConnectionState变为"disconnected"或"failed"后触发createOffer+setLocalDescription再发信令
WebRTC 延迟低(
立即学习“前端免费学习笔记(深入)”;
hls.js 断流自动重连实操要点
若选 HLS,hls.js 是目前最稳定的 MSE 封装库,但默认配置对弱网不友好,需手动调优:
- 启用自动重试:
enableStreaming: true、autoStartLoad: true - 缩短重试间隔:
retryDelay: 1(单位秒),避免卡死在ERROR状态不恢复 - 限制缓冲上限:
maxMaxBufferLength: 3(秒),防止断流后积压旧分片拖慢重连 - 关键事件监听:
hls.on(Hls.Events.ERROR, (e, data) => { if (data.fatal) hls.destroy(); hls.loadSource(...); }) - 注意:
loadSource()必须在destroy()后重新初始化实例,不能复用老实例调loadSource()
示例片段:
const hls = new Hls({ retryDelay: 1, maxMaxBufferLength: 3 });
hls.loadSource('http://server/live/stream.m3u8');
hls.on(Hls.Events.ERROR, (e, data) => {
if (data.fatal && (data.type === 'networkError' || data.type === 'mediaError')) {
hls.destroy();
setTimeout(() => initHls(), 500);
}
});
WebRTC 重连容易被忽略的坑
WebRTC 表面是“点对点”,实际依赖服务端中继和信令,重连失败常因以下细节:
- 信令通道未保活:WebSocket 断开后,
iceConnectionState可能长期卡在"checking";需监听ws.onclose并主动重连信令 - SDP 不更新:重连时若复用旧
offer,服务端可能拒绝;每次重连必须调createOffer({offerToReceiveVideo: true}) - ICE 重启逻辑缺失:仅调
restartIce()不够,需先removeTrack()再addTrack()触发新候选收集 - 移动端特殊限制:iOS Safari 对后台标签页的
RTCPeerConnection会冻结 ICE,唤醒后需手动restartIce()并检查iceGatheringState
真正健壮的重连不是“断了再连”,而是提前探测连接质量(如统计 getStats() 中的 packetsLost、jitter),在恶化到断流前就主动重建连接。










