如何播放从服务器下载的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
相关产品推荐
相关产品推荐

