用网络音频api播放简单的声音

joo*_*bla 5 javascript audio html5 web-audio-api

我一直在尝试按照一些教程中的步骤,使用按钮使用Web Audio API回放一个简单的,编码的本地wav或mp3文件.我的代码如下(testAudioAPI.js):

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var myBuffer;

clickme = document.getElementById('clickme');
clickme.addEventListener('click',clickHandler);

var request = new XMLHttpRequest();

request.open('GET', 'WoodeBlock_SMan_B.wav', true);

request.responseType = 'arraybuffer';

// Decode asynchronously
request.onload = function() {
  context.decodeAudioData(request.response, function(theBuffer) {
    myBuffer = theBuffer;
  }, onError);
}
request.send();

function playSound(buffer) {
  var source = context.createBufferSource(), g = context.createGain();
  source.buffer = buffer;
  source.start(0);
  g.gain.value = 0.5;
  source.connect(g);
  g.connect(context.destination);
}

function clickHandler(e) {
    playSound(myBuffer);
}
Run Code Online (Sandbox Code Playgroud)

HTML文件看起来像这样:

    <!doctype html>
<html>
    <body>
        <button id="clickme">Play</button>
        <script src='testAudioAPI.js'></script>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

但是,无论如何都没有声音.我已经尝试了几个片段,但我仍然无法弄明白.当我尝试通过创建振荡器节点来合成声音来生成声音时,我确实听到了声音,但是没有来自本地文件的缓冲区.这会是什么问题?谢谢你们.

Kev*_*nis 6

本地文件,对吧?你只是从文件系统中抓取它们(例如"file://"),还是运行本地Web服务器?

根据我的记忆,直接从文件系统提供服务在大多数(所有?)浏览器中都违反了CORS - 这将阻止您的AJAX请求成功.

也许尝试使用python -m SimpleHTTPServer或类似的服务页面,然后在http:// localhost:8000访问它.

据我所知,你的所有代码看起来都很好.


wei*_* ou 6

现代 ES6 的简约方法。

  1. 新的音频上下文();
  2. 上下文.createBufferSource();
  3. source.buffer = 音频缓冲区;audioBuffer通过fetch请求ArrayBuffer数据,然后decodeAudioData解码到AudioBuffer。
  4. 源.start()
<button id="start">playSound</button>
Run Code Online (Sandbox Code Playgroud)
const audioPlay = async url => {
  const context = new AudioContext();
  const source = context.createBufferSource();
  const audioBuffer = await fetch(url)
    .then(res => res.arrayBuffer())
    .then(ArrayBuffer => context.decodeAudioData(ArrayBuffer));

  source.buffer = audioBuffer;
  source.connect(context.destination);
  source.start();
};

document.querySelector('#start').onclick = () => audioPlay('music/music.mp3');
Run Code Online (Sandbox Code Playgroud)

停止播放: source.stop();

Web Audio API 无法自动播放,需要通过事件触发。

创建多个AudioContext对象会导致错误,您应该注销然后创建它们。

无法构建“AudioContext”:硬件上下文数量达到最大值

const audioPlay = (() => {
  let context = null;
  return async url => {
    if (context) context.close();
    context = new AudioContext();
    const source = context.createBufferSource();
    source.buffer = await fetch(url)
      .then(res => res.arrayBuffer())
      .then(arrayBuffer => context.decodeAudioData(arrayBuffer));
    source.connect(context.destination);
    source.start();
  };
})();

document.querySelector('#start').onclick = () => audioPlay('music/music.mp3');
Run Code Online (Sandbox Code Playgroud)