HTML5无法原生播放RTSP流,必须通过中转服务将RTSP转为WebRTC或HLS;WebRTC延迟低(
浏览器原生 标签只认 HTTP(S) 协议下的 MP4、WebM、HLS(m3u8)、DASH 等格式,rtsp:// 地址直接扔进去会静默失败——既不报错也不播放。这不是兼容性问题,是协议层根本不通。所以“HTML5 播放 RTSP”这个需求,本质是“把 RTSP 流转成浏览器能解的流”,而 WebRTC 是目前延迟最低、体验最接近原生 RTSP 的方案之一。
纯前端无法完成 RTSP 解析和 WebRTC 封包,必须依赖一个中间服务做拉流、解码、重封装。常见组合是:FFmpeg 或 GStreamer 拉 RTSP,再通过信令服务器(如 mediasoup、Janus、LiveKit)推 WebRTC。关键点不是“怎么写 HTML”,而是“怎么搭这条链路”:
FFmpeg 命令示例(拉 RTSP 并推到 mediasoup 的 WebRTC ingest):ffmpeg -i "rtsp://192.168.1.100:554/stream" -c:v libx264 -b:v 1000k -f webm -content_type video/webm http://localhost:3000/ingest
RTCPeerConnection 接收 SDP offer/answerJanus,需启用 videoroom 插件并配置 rtsp bridge;mediasoup 则需搭配 mediasoup-client 和自定义 worker 逻辑如果对延迟不敏感(可接受 5–30 秒),用 HLS 更轻量:
FFmpeg 实时切片:ffmpeg -i "rtsp://..." -c:v libx264 -hls_time 2 -hls_list_size 5 -hls_flags delete_segments out.m3u8
(需服务端支持 CORS + MIME 类型为 application/
vnd.apple.mpegurl)很多项目卡在看似无关的环节:
立即学习“前端免费学习笔记(深入)”;
FFmpeg 转 WebRTC 时必须软解(-c:v libx264)或硬编支持,否则浏览器无法解码——RTCPeerConnection 收到帧但 video 元素黑屏a=setup:actpass 和 a=connection: new 必须匹配客户端生成的 offer,否则 ICE 连接卡在 checking
RTCPeerConnection 的 addTransceiver 调用顺序敏感:必须先 add,再 setLocalDescription,否则触发 InvalidStateError
rtsp://192.168.x.x)不能直接暴露给公网用户,中转服务必须部署在能访问该 RTSP 源的网络环境里真正难的不是写几行 JS,而是让 FFmpeg 不崩、信令不丢包、ICE 穿透成功、编码参数和浏览器能力对齐——每个环节出问题,现象都是“没画面”,但原因可能差十层。