You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ReadableStream流式播放服务器返回的音频文件?

流式音频边接收边播放的实现方案

方案一:使用MediaSource API(最常用)

MediaSource是专门处理流式媒体的API,能让你把分片的音频数据逐步喂给<audio>元素,实现边下载边播放。

具体步骤:

  • 创建<audio>元素,开启控制栏(也可设置自动播放,但需注意浏览器的自动播放限制,通常需要用户交互触发)
  • 实例化MediaSource,将其生成的URL赋值给audio的src属性
  • 监听MediaSource的sourceopen事件,在事件回调中创建对应音频格式的SourceBuffer(格式需和服务器返回的编码匹配,比如MP3对应audio/mpeg; codecs="mp3")
  • 通过fetch获取流式响应,用body.getReader()读取分片数据
  • 等待上一个分片处理完成(监听SourceBuffer的updateend事件)后,将新分片的ArrayBuffer数据append到SourceBuffer中
  • 所有分片读取完成后,调用mediaSource.endOfStream()结束流

代码示例:

const audio = document.createElement('audio');
audio.controls = true;
document.body.appendChild(audio);

const mediaSource = new MediaSource();
audio.src = URL.createObjectURL(mediaSource);

mediaSource.addEventListener('sourceopen', async () => {
  // 替换为实际的音频编码格式,需和服务器返回一致
  const sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg; codecs="mp3"');
  
  const response = await fetch('/your-audio-stream-api');
  const reader = response.body.getReader();
  
  async function processChunk() {
    const { done, value } = await reader.read();
    if (done) {
      mediaSource.endOfStream();
      return;
    }
    
    // 等待SourceBuffer处理完上一个分片
    while (sourceBuffer.updating) {
      await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }));
    }
    
    sourceBuffer.appendBuffer(value);
    processChunk();
  }
  
  processChunk();
});

注意事项:

  • 服务器返回的音频必须是支持流式的编码格式,比如MP3、AAC(封装在MP4容器中),无压缩的WAV格式无法分片解码,不适用
  • 服务器需要按完整的编码帧切割数据流,否则SourceBuffer无法解析分片数据
  • 浏览器自动播放限制:直接加载可能被拦截,建议通过用户点击等交互触发播放

方案二:使用Web Audio的AudioWorklet(适合自定义处理场景)

如果需要对音频做实时自定义处理,可使用AudioWorklet,它能在独立音频线程中处理分片数据,避免阻塞主线程。

核心思路:

  • 创建AudioContext并加载自定义的AudioWorklet处理器
  • 使用支持流式解码的WebAssembly库(比如libmp3lame的Wasm版本),将读取到的音频分片解码为PCM格式
  • 将PCM数据通过AudioWorklet的端口传递给处理器,由处理器输出到扬声器

这个方案复杂度较高,需要额外引入解码库,仅在需要自定义音频处理时使用,单纯播放推荐用MediaSource。

原方案失效原因

你之前用AudioContext.decodeAudioData失败,是因为该API仅能解码完整的音频文件或完整的编码帧序列,不支持增量式的流式解码。单独的音频分片不是可独立解码的完整单元,因此无法直接播放。

内容的提问来源于stack exchange,提问作者bittere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:04:59