HTML5原生不支持RTSP流,video标签无法直接加载rtsp://地址,因其缺乏RTSP解析器、RTP/UDP处理能力及Annex-B裸流支持;可行方案是服务端转封装为HLS或MP4+MSE,前端手动控制缓存。

HTML5 原生不支持 RTSP,更谈不上直接缓存 RTSP 流。浏览器没有内置 RTSP 解析器和解码器,video 标签只认 MP4、WebM、OGG 或 MSE 支持的分段格式(如 MP4 片段、TS + m3u8),RTSP 协议本身无法被 video 标签 src 直接加载。
为什么不能直接用
这是最常踩的坑:开发者看到 IPC 摄像头提供 RTSP 地址,就直接往 video 的 src 里填,结果空白或报错 DOMException: The element has no supported sources。原因很实在:
- RTSP 是控制协议(类似“遥控器”),不传输实际音视频数据;真正载荷走的是 RTP/UDP(有时 TCP),而浏览器禁止 JS 直接收发原始 UDP 包
- HTML5 视频栈不解析 RTSP 握手、DESCRIBE、SETUP 等流程,也不处理 SDP 会话描述
- 即使强制用 WebSocket 转发 RTP 包,浏览器也无法把裸 H.264/H.265 Annex-B 流喂给
MediaSource——它要求 MP4 封装或 TS +video/mp2tMIME 类型
可行路径:服务端转封装 + MSE 缓存控制
所谓“本地缓存 RTSP”,本质是让服务端把 RTSP 流实时转成浏览器能吃的格式(通常是 TS 或 MP4 片段),再由前端用 MediaSource 接收并可控写入 SourceBuffer。缓存行为发生在 JS 层,而非浏览器自动缓存 src。
- 用
ffmpeg或GStreamer拉流:ffmpeg -i "rtsp://..." -c:v copy -c:a aac -f hls -hls_time 2 -hls_list_size 10 -hls_flags delete_segments stream.m3u8,生成带滚动窗口的 HLS - 前端用
Hls.js加载,它内部用MediaSource管理 buffer;通过hls.bufferController可读取已缓冲的buffered时间范围,但不能随意“导出”为文件 - 若真要持久化本地缓存(比如离线回放),需服务端额外保存 TS 分片到磁盘,并由前端用
fetch()下载后手动 append 到SourceBuffer,此时你控制每一段的加载、存储、重放逻辑
用 WebRTC 方案绕过转码?依然无法“缓存”
部分方案(如 janus-gateway + webrtc-streamer)把 RTSP 转成 WebRTC 流,前端用 RTCPeerConnection 接收。这条路延迟低,但:
立即学习“前端免费学习笔记(深入)”;
- WebRTC 数据天生是实时传输,不设计为可缓存;
RTCRtpReceiver没有暴露原始帧供 JS 持久化 - 你能做的顶多是监听
track.onended后停止,或用MediaRecorder录制当前流(输出webm或mp4blob),但这属于“另起炉灶录制”,不是“缓存 RTSP 流本身” - 录制时长受内存限制,长时间录制易触发
QuotaExceededError,必须分段stop()/start()并URL.createObjectURL()导出
真正可控的“缓存”,永远落在服务端转封装 + 前端 MSE 手动管理 buffer 这一环。别信“一行代码实现 HTML5 缓存 RTSP”的说法——协议鸿沟在那里,绕不开,只能桥接。










