实时视频(一):RTSP 到浏览器的协议选择
浏览器没有通用的 RTSP 播放入口。摄像头的 RTP 负载需要经过协议转换、容器封装或转码,才能交给浏览器的媒体栈。协议选择不能从“哪个库能播放”开始,应从延迟预算、编码格式、网络边界、并发方式和音频要求倒推。
先写延迟预算
端到端延迟可以拆成:
$$L = L_{capture} + L_{encode} + L_{gateway} + L_{network} + L_{buffer} + L_{decode} + L_{render}$$
每一项都要有观测点。只看浏览器缓冲区会漏掉摄像头编码和网关排队。实时云台控制通常需要低延迟和快速恢复,回放或大屏分发更看重 CDN 复用和长连接稳定性。延迟预算写成上限后,协议比较才有可执行标准。
四种下游路径
WebRTC 适合交互预览。它有 ICE、拥塞控制、抖动缓冲和关键帧反馈,工程重点落在信令、TURN、会话权限和媒体服务器。低延迟不等于零延迟,编码 GOP、网络中继和浏览器缓冲仍会影响体验。
MSE 需要 fMP4 等浏览器接受的媒体片段。服务端负责封装、时间戳、关键帧边界和 SourceBuffer 背压,应用可以复用录制链路。缓冲积累或参数集变化时,播放器需要清理旧片段并等待新的初始化段。
LL-HLS 适合回放与分发。分片、部分分片、CDN 缓存和播放器 live edge 共同决定延迟,缩短分片不能弥补过长 GOP。公网大规模播放先评估 CDN 和浏览器支持,再决定是否接受数秒级延迟。
WebSocket 只提供字节传输。当前浏览器 RTSP demo 选择了这条路径,服务端传递 RTP/Access Unit 相关数据,前端 TypeScript 负责解包、Worker 调度和解码。它便于调试和内网部署,协议、背压、重连、鉴权与音画同步都要自行定义。
编码矩阵比协议名称重要
H.264 的 profile、level、参数集和 packetization mode 会影响浏览器能力。H.265 的浏览器覆盖更受限制,需要准备 WebCodecs、WASM 或服务端转码路径。SDP 中的 codec 信息和实际 Annex B 码流要相互核对,不能只看 MIME 字符串。
音频单独做矩阵。摄像头可能使用 G.711、AAC 或其他编码,WebRTC、MSE 和自定义链路的容器与解码支持不同。只验证画面会把无声和音画漂移留到上线后。双向对讲还要加入浏览器权限、回声处理和上行编码。
共享上游和会话权限
同一路摄像头应由服务端维护一条拉流,再把 Access Unit 分发给多个下游。每个浏览器直接连接摄像头会快速耗尽设备连接数,也会让上游凭据暴露在客户端。会话 API 校验用户对摄像头的权限,签发绑定源、协议、过期时间和用户范围的短期令牌。
WebRTC 信令、MSE 长连接和 WebSocket 订阅都要记录会话状态。令牌过期和权限撤销不能只在握手时检查,服务端需要在心跳或关键事件处执行撤销。上游地址、用户名和密码只留在受控服务端,日志保存摘要和会话 ID。
选择结果要可诊断
播放页面显示实际使用的协议、编码、分辨率、GOP、转码状态、延迟估计和错误阶段。WebRTC 协商失败后是否切换到 MSE 或低码流,由显式策略决定,切换时清空旧队列并重新等待关键帧。用户看到的是协议切换结果,运维需要看到触发原因。
容量估算至少包括活跃源数、每源码率、订阅数、出口带宽、转码路数和 TURN 比例。录制与直播共享上游时,各自使用独立队列,磁盘慢不能阻塞实时预览。压测覆盖不同 GOP、分辨率、音频组合和断线恢复,单一静态样本无法说明链路上限。
这篇文章只给选择框架。它不保证某个协议在所有浏览器和摄像头组合中可用,验收结果需要用目标编码和真实网络做能力矩阵验证。