流式音频播放

1,467 阅读3分钟

关于流式音频播放的两种 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/aacaudio/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 实现更灵活的自定义播放逻辑。