MediaSource API 不支持 WebSocket 自动播放,需手动解析、转封装(如 Annex B→fMP4)、按序 append 至 SourceBuffer;关键在时间戳对齐、NALU 边界识别、init segment 仅追加一次及 readyState 校验。

MediaSource API 本身不支持直接接收 WebSocket 数据并自动播放,必须手动将 WebSocket 接收的视频数据(如 H.264 Annex B 格式裸流或 fragmented MP4)解析、分段、封装为可被 SourceBuffer 接受的格式(如 ISO BMFF),再追加到 MediaSource 中。关键在于“解包→转封装→按序 append”的闭环控制,而非简单转发。
WebSocket 接收端需明确流格式与时间戳
服务端通过 WebSocket 发送的不能是任意二进制流,必须约定结构:
- 推荐使用带起始码(0x00000001 或 0x000001)的 H.264 Annex B 帧,每帧含完整 NALU,且需附带解码时间戳(DTS)和显示时间戳(PTS)——可通过自定义二进制协议头携带(如前8字节:4字节 PTS + 4字节 DTS)
- 避免发送未标记关键帧(IDR)的纯 P/B 帧;首帧必须是 IDR,否则解码器无法初始化
- 若用 fMP4(fragmented MP4),需确保每个 fragment 包含 moof + mdat,且 moof 中的 traf box 含正确的时间信息(tfdt/tfhd)
MediaSource 初始化与 SourceBuffer 配置
创建 MediaSource 后,需根据实际编码格式设置 MIME type,并监听 sourceopen 事件再添加 SourceBuffer:
const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
// H.264 over MP4 容器(最常用)
const sourceBuffer = mediaSource.addSourceBuffer(
'video/mp4; codecs="avc1.42E01E"'
);
// 若为纯 Annex B 流,需先转封装为 fMP4(见下节)
});
注意:MIME type 中的 codec 字符串必须与实际视频编码参数严格匹配(如 profile/level),否则 addSourceBuffer 抛错。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
立即学习“前端免费学习笔记(深入)”;
Annex B → fMP4 的客户端实时转封装
浏览器 SourceBuffer 只接受 MP4(ISO BMFF)格式,因此 WebSocket 收到的 Annex B 流必须在前端转换。可借助轻量库如 mp4box.js 或自行构造基础 fMP4 片段:
- 提取每个 NALU,过滤 SEI/SPS/PPS(首次出现时存为 init segment)
- 将 SPS/PPS 注入
moov的 avcC box,生成初始化段(init segment)并调用sourceBuffer.appendBuffer(initSeg) - 对每个视频帧(IDR/P),构造最小 fMP4 fragment:含
moof(含 tfdt 时间戳、traf)、mdat(写入 NALU,前置长度域而非起始码) - 按 PTS 顺序 append fragment,避免时间戳跳变或倒退(否则触发
updateend后报错)
WebSocket 控制与缓冲管理
避免内存溢出和卡顿,需主动控制接收节奏:
- 监听
sourceBuffer.updating状态,仅当!updating时才 append 新数据 - 监控
sourceBuffer.buffered,用video.currentTime判断是否接近缓冲末尾,动态暂停/恢复 WebSocketonmessage处理 - 设置最大缓冲时长(如 5 秒),超出时调用
sourceBuffer.remove(start, end)清理旧片段 - 捕获
sourcebuffer.error和mediasource.sourceended,及时重连或提示解码失败
不复杂但容易忽略:时间戳对齐、NALU边界识别、init segment 仅 append 一次、append 前必须 ensure readyState === 'open'。整个链路依赖精准的二进制处理能力,建议从固定 IDR+P 帧序列的离线 demo 入手验证流程。


















