关于流式音频播放的两种 Web 实现方式:Media Source Extensions (MSE) 与 AudioContext
在现代 Web 开发中,流式音频播放已成为常见需求。本文将结合实践,介绍两种常见的浏览器原生方案:Media Source Extensions(MSE) 与 Web Audio API(AudioContext),并探讨它们在流媒体播放中的使用方式、适用场景与兼容性差异。
一、Media Source Extensions(MSE)
MSE 是一种允许通过 JavaScript 动态生成媒体流的浏览器 API。它使我们能够在无需插件的情况下,通过 <audio> 或 <video> 元素播放实时或动态生成的音视频内容。
基本使用方式:
const audioElement: HTMLAudioElement = new Audio();
const mediaSource: MediaSource = new MediaSource();
// 设置 audio 元素的 src
audioElement.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
const sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg');
// 模拟接收流式音频数据
sourceBuffer.appendBuffer(chunk1);
sourceBuffer.appendBuffer(chunk2);
sourceBuffer.appendBuffer(chunk3);
});
在这个模型中:
MediaSource是媒体容器。SourceBuffer是数据的接收者,它接收流式的音频数据(chunk)。audioElement负责实际的播放。
一个
MediaSource可以包含多个SourceBuffer,这在处理视频(例如:分别管理音频、视频轨道)时尤为重要。但在本案例中,我们仅涉及音频播放,因此只使用了一个audio/mpeg类型的SourceBuffer。
编码兼容性建议
尽管 MSE 支持 MP3(audio/mpeg),但根据 MDN 文档推荐,AAC 编码(如 audio/aac 或 audio/mp4)具有更好的兼容性和性能表现。AAC 是 MP3 的继任者,在现代浏览器(尤其是移动端)中有更广泛的支持。
参考文档:音频编码格式解析 - 阿里云开发者社区
浏览器兼容性注意事项
MSE 在 iOS Safari 上的支持较差。尤其是在 iPhone 设备上,即使是 iOS 13 以上系统也未完全支持,仅在部分 iPad 上表现良好。
因此,在不支持 MSE 的浏览器中(尤其是移动端),需要寻找其他替代方案。
二、Web Audio API — AudioContext
相比 MSE,AudioContext 是一个更底层、更灵活的音频处理方案。它不依赖 <audio> 元素,而是通过 JavaScript 完全控制音频的解码、播放与处理,适用于实时音频处理与精准控制场景。
基本播放流程:
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
async function playArrayBuffer(arrbuffer: ArrayBuffer) {
const audioSourceNode = audioContext.createBufferSource();
const audioBuffer = await audioContext.decodeAudioData(arrbuffer);
audioSourceNode.buffer = audioBuffer;
audioSourceNode.connect(audioContext.destination);
audioSourceNode.start();
}
说明:
- 使用
decodeAudioData将压缩音频数据(如 MP3、AAC)解码为可播放的AudioBuffer。 - 每次播放都需创建新的
AudioBufferSourceNode实例(轻量,创建成本低)。 - 播放结束后,节点不可复用。
适用于流式音频播放场景
如果需要边接收边播放音频流,可以将多个 ArrayBuffer 按顺序传入上述 playArrayBuffer 函数,确保上一个播放结束时立即衔接下一个,从而尽可能减少卡顿,获得更平滑的播放体验。
总结对比
| 特性 | Media Source Extensions (MSE) | AudioContext |
|---|---|---|
| 播放方式 | 基于 <audio> 或 <video> 元素 | JavaScript 直接控制 |
| 编码支持 | MP3, AAC,需浏览器支持 | 多种编码,通过解码播放 |
| 实时流支持 | 强 | 强(更底层,更灵活) |
| 浏览器兼容性 | iOS Safari 支持差 | 较好,广泛兼容 |
| 控制精度 | 中等 | 高(可接入音效处理、动态调节) |
最佳实践建议
- 桌面端浏览器或 Android WebView:可优先使用 MSE,集成简单,性能良好。
- iOS(尤其是 iPhone):建议使用
AudioContext,以避免兼容性问题。 - 对播放控制精度、音效处理有需求时:优先选择
AudioContext实现更灵活的自定义播放逻辑。