Javascript Web音频API,使用panNode时出现问题,声音只播放一次

Javascript Web音频API,使用panNode时出现问题,声音只播放一次,javascript,audio,web-audio-api,Javascript,Audio,Web Audio Api,我试图在一个小的测试应用程序中集成一些平移效果到一些声音中。除了一个重要的问题:每个声音只播放一次外,它工作得很好 我尝试了几种方法试图绕过这个问题,但没有成功。问题是,我无法确定问题来自何方。这是我的代码,下面有一些解释 const audio = new Audio('audio/background.mp3'); const footstep = new Audio('audio/footstep1.mp3'); const bumpWall1 = new Audio(`audio/bum

我试图在一个小的测试应用程序中集成一些平移效果到一些声音中。除了一个重要的问题:每个声音只播放一次外,它工作得很好

我尝试了几种方法试图绕过这个问题,但没有成功。问题是,我无法确定问题来自何方。这是我的代码,下面有一些解释

const audio = new Audio('audio/background.mp3');
const footstep = new Audio('audio/footstep1.mp3');
const bumpWall1 = new Audio(`audio/bump-wall1.mp3`);
const bumpWall2 = new Audio(`audio/bump-wall2.mp3`);
const bumpWall3 = new Audio(`audio/bump-wall3.mp3`);
const bumpWall4 = new Audio(`audio/bump-wall4.mp3`);
const bumpWallArray = [bumpWall1, bumpWall2, bumpWall3, bumpWall4];

audio.volume = 0.5;

function play(sound, dir) {
  let audioContext = new AudioContext();
  let pre = document.querySelector('pre');
  let myScript = document.querySelector('script');

  let source = audioContext.createMediaElementSource(sound);

  let panNode = audioContext.createStereoPanner();
  source.connect(panNode);
  panNode.connect(audioContext.destination);
  if (dir === "left") {
    panNode.pan.value = -0.8
  } else if (dir === "right") {
    panNode.pan.value = 0.8;
  } else {
    panNode.pan.value = 0;
  }
  sound.play();
}
因此,基本上,当您调用play()函数时,它会在左侧、右侧或中间播放声音。但每个声音只播放一次。例如,如果足迹播放过一次,则如果我对其调用play()函数,则不会再次播放该足迹

有人能帮我吗?

在您的邮件中,您应该有一条信息,说明以下内容:

未捕获InvalidStateError:未能在“AudioContext”上执行“createMediaElementSource”:HTMLMediaElement先前已连接到其他MediaElementSourceNode

(至少在Chrome中是这样)不能将MediaElement多次连接到MediaElementSourceNode

要避免这种情况,必须断开此MediaElement与MediaElementSourceNode的连接,但是

在您的情况下,最好是直接使用而不是HTMLAudioElements,而且如果您不在文档中附加它们的话

let音频;
const sel=document.getElementById('sel');
//创建单个音频上下文,这些不是小对象
const audioContext=新的audioContext();
取('https://dl.dropboxusercontent.com/s/agepbh2agnduknz/camera.mp3)。然后(resp=>resp.arrayBuffer())
.then(buf=>audioContext.decodeAudioData(buf))
.然后(audioBuffer=>audio=audioBuffer)
.然后(()=>sel.disabled=false)
.catch(console.error);
功能播放(声音、方向){
让source=audioContext.createBufferSource();
source.buffer=声音;
让panNode=audioContext.createStereoPanner();
source.connect(panNode);
panNode.connect(audioContext.destination);
if(dir==“left”){
panNode.pan.value=-0.8
}否则如果(dir==“right”){
panNode.pan.value=0.8;
}否则{
panNode.pan.value=0;
}
source.start(0);
}
sel.onchange=evt=>播放(音频,sel.value)

左边
居中
正确的

是否有任何东西阻止您使用音频缓冲区?这听起来比你现在做的更自然。我不确定。我昨天才知道这件事,所以显然有很多我不知道的。音频缓冲能解决这个问题吗?我将研究音频缓冲区。谢谢好的,非常感谢!我将对此进行研究,尝试理解正在发生的事情,将其实现到我的代码中,并在我成功使其工作后尽快回到这里接受这个答案。谢谢嘿,它起作用了!令人惊叹的。但我不确定我必须如何用几个声音来处理它。我已经试过了,但只能有1个音频上下文。我将尝试从中推断,但无论如何,你应该得到奖励:)谢谢!预取所有资产并将其存储在代码可以访问的地方,我个人可能会使用字典或数组来存储它们。无论如何,只创建audioContext。你可以让自己成为一个预加载帮助程序,它将从url返回AudioBuffer(基本上是我答案顶部的5行,但作为一个函数。好的,我知道了!你可以
获取你想要的任何声音!它可以工作:)我很高兴,很抱歉它直接通过id获取元素,我只在底部添加了声明。。。编辑