HTML5不支持RTSP协议,标签无法直接播放rtsp://地址;音画不同步仅出现在经WebRTC或WebSocket中转后的时间戳未对齐场景。

HTML5 本身不支持 RTSP 协议
直接用 标签加载 rtsp:// 地址必然失败,浏览器会静默忽略或报 DOMException: The element has no supported sources。这不是音画不同步问题,而是根本播不了——RTSP 是传输控制协议,不是浏览器能原生解码的媒体格式。
所谓“音画不同步”,通常出现在你已绕过协议限制(比如用 WebRTC 或 WebSocket 中转 RTSP 流),但后端转封装或前端解码时未对齐音视频时间戳(PTS/DTS)导致的。
WebRTC 方案里音画不同步的常见原因
主流解法是用 GStreamer / FFmpeg 将 RTSP 转成 WebRTC(如通过 aiortc、mediasoup 或 Janus),此时不同步往往源于:
- RTSP 源本身音视频时间戳不连续或有漂移(尤其某些海康/大华 IPC 在低码率下会丢 PTS)
- 转推服务未启用音视频同步校准(如
mediasoup需配置enableRemoteVideo+enableRemoteAudio并确保同一 worker 处理) - 前端
RTCPeerConnection接收流后,未监听track.onunmute就直接绑定srcObject,导致音轨早于视频轨就绪并开始播放 - 浏览器对高帧率(如 50fps)+ 高音频采样率(如 48kHz)组合的渲染调度不一致,Chrome 表现比 Firefox 更明显
用 MSE + WebSocket 转封装时的关键参数
若用 FFmpeg 把 RTSP 转成 fragmented MP4(fMP4)再通过 WebSocket 推给前端 MSE,音画不同步多因 muxer 时间基不统一:
立即学习“前端免费学习笔记(深入)”;
必须保证音视频流使用相同 time_base,例如都设为 1/90000(MPEG-TS 常用),命令参考:
ffmpeg -i rtsp://xxx -c:v libx264 -c:a aac -video_track_timescale 90000 -audio_track_timescale 90000 -f mp4 -movflags +frag_keyframe+empty_moov+default_base_moof -
前端 JS 中写入 SourceBuffer 前,需检查每个 Uint8Array 的 moof/mdat 是否含有效 traf.tfdt.baseMediaDecodeTime,缺失则手动插值补时间戳——否则浏览器无法对齐音画。
调试时优先验证的三个点
别急着调代码,先确认底层链路是否干净:
- 用
ffplay -vst 0 -ast 0 rtsp://xxx直连源,看本地是否也不同步——如果是,问题在 IPC 或网络抖动,前端无解 - 抓包看 WebSocket 或 DataChannel 发送的 chunk 是否音视频 fragment 交替出现(如 video → audio → video → audio),若长期只发视频,则音频编码器卡死或丢包严重
- 在 Chrome 的
chrome://webrtc-internals页面查audioOutputLevel和videoReceivedResolution是否同时有值且稳定,若音频 level 为 0 但视频正常,说明音频轨道未正确 addTrack 或 SDP 中 m=audio 行被过滤
真正难处理的是跨设备时钟漂移:IPC 用 NTP 同步,而浏览器用系统时钟,差几百毫秒就会累积成肉眼可见的拖影。这时候硬靠前端 JS 插帧或丢帧只是掩耳盗铃。










