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

如何播放从服务器下载的MP3文件?流式数据新手求助

问题分析与解决

你的代码核心问题是没有设置XMLHttpRequest的响应类型,默认情况下xhr.response会返回文本格式内容,而音频播放器需要二进制音频数据,因此无法识别播放。

修改后的代码

servpl.onclick = e =>{
  const xhr = new XMLHttpRequest();
  // 关键:设置响应类型为blob(二进制大对象)
  xhr.responseType = 'blob';
  xhr.open('GET', 'sounds/test.mp3');

  xhr.send();
  xhr.onload = function() {
    if (xhr.status != 200) {
      alert(`Error ${xhr.status}: ${xhr.statusText}`);
    } else {
      alert(`Done, got ${xhr.response.size} bytes`);
      // 将blob对象转为可被audio识别的临时URL
      const audioUrl = URL.createObjectURL(xhr.response);
      recordedAudio.src = audioUrl;
      // 处理浏览器自动播放限制
      recordedAudio.play().catch(err => {
        console.error('播放失败:', err);
        alert('播放失败,请检查浏览器自动播放策略');
      });

      document.getElementById("display").innerHTML += " after play sound";
      // 播放结束后释放临时URL,避免内存泄漏
      recordedAudio.onended = () => {
        URL.revokeObjectURL(audioUrl);
      };
    }
  };
  document.getElementById("display").innerHTML += " Server Play clicked";
};

关键修改点

  • 添加xhr.responseType = 'blob':告知XHR以二进制blob格式接收音频数据
  • 使用URL.createObjectURL(xhr.response):把blob转换成浏览器可识别的临时音频URL,赋值给audio的src
  • 给play()添加catch处理:捕捉浏览器自动播放限制导致的错误(现代浏览器要求播放必须由用户交互触发,这里已在点击事件内,符合要求)
  • 添加onended事件释放临时URL:避免长期占用内存

额外说明

如果你的服务器允许直接访问音频文件,完全可以不用XHR下载,直接给recordedAudio.src赋值sounds/test.mp3即可,浏览器会自动处理流式播放,代码更简洁。只有当需要做权限验证、数据预处理等特殊操作时,才需要通过XHR获取音频数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:10:15