HTML5不支持RTSP,所有方案均需服务端转协议(如WebRTC/HLS/FLV);切换源本质是调用服务端API更换拉流地址,并前端同步重建连接,需防缓存、跨域、内存泄漏及并发请求。
直接用 标签加 src="rtsp://..." 必然失败——浏览器根本没实现 RTSP 协议栈。所有“HTML5 播放 RTSP”的方案,本质都是服务端转协议(RTSP → WebRTC / HLS / MSE-HTTP-FLV),前端只是消费转换后的流。所谓“切换源”,实际是切换服务端提供的新流地址,或触发服务端重新拉取不同 RTSP 地址。
基于 WebRTC 的流媒体服务器(如 mediasoup、Janus、EasyNVR、SmartPlayer.js 配合 WebRTC-Stream)通常提供 REST API 或 WebSocket 控制接口,允许运行时更换后端拉流地址。关键不是前端换 src,而是发指令让服务端停旧流、起新流。
/api/v1/channels/{channelId}/switch 的 POST 接口,body 传新 rtsp_url
success: true 后,再调用前端 SDK 的 restart() 或 reconnect() 方法RTCPeerConnection 实例,确保只对当前播放实例操作,别误触其他通道如果走的是 Nginx-rtmp + HLS 或 SRS + HTTP-FLV,前端靠更换 的 src 切换,但必须处理底层副作用:
video.pause() 和 video.src = "",再 URL.revokeObjectURL(oldUrl) 释放旧 blob URL(尤其 MSE 场景)http://x.x/x.m3u8?t=171xxxxxx

Access-Control-Allow-Origin: * 且不能带 cookie
flv.js)切换时,必须先 flvPlayer.unload() 再 flvPlayer.destroy(),否则内存泄漏+黑屏用户连点“切换摄像头”按钮,很容易引发并发请求或状态混乱。不能只靠 UI 禁用按钮了事。
currentChannelId 和 isSwitching 标志位,任何切换请求先检查 isSwitching === false
AbortController 控制未完成的 fetch 请求,避免旧请求回调覆盖新结果"RTSP连接超时" 或 "404: 该通道未启用",而不是只弹“切换失败”fetch("/api/v1/streams/health?rtsp_url=..."),减少用户等待无效流的时间