Javascript audioContext.suspend()未按预期停止音乐

Javascript audioContext.suspend()未按预期停止音乐,javascript,web-audio-api,Javascript,Web Audio Api,我试图让一些生成性的音乐在理想情况下暂停,但我愿意停止使用Wen Audio Javascript API。我遇到的问题是audioContext.suspend()似乎没有任何作用。所有的文档和示例都表明以下方法可行,但我无法解决这个问题。然而,我对javascript还不熟悉,所以怀疑我在做一些愚蠢的事情 所有控制台日志都证明该函数在第二次单击时启动。我也试过停止,但也不起作用。我用Chrome来测试我的工作,在Safari上试用过,但它甚至没有达到播放曲目的程度 // for cross

我试图让一些生成性的音乐在理想情况下暂停,但我愿意停止使用Wen Audio Javascript API。我遇到的问题是audioContext.suspend()似乎没有任何作用。所有的文档和示例都表明以下方法可行,但我无法解决这个问题。然而,我对javascript还不熟悉,所以怀疑我在做一些愚蠢的事情

所有控制台日志都证明该函数在第二次单击时启动。我也试过停止,但也不起作用。我用Chrome来测试我的工作,在Safari上试用过,但它甚至没有达到播放曲目的程度

// for cross browser
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();

function startLoop(audioBuffer, pan=0, rate=1) {
    let sourceNode = audioContext.createBufferSource();
    let pannerNode = audioContext.createStereoPanner();

    sourceNode.buffer = audioBuffer;
    sourceNode.loop = true;
    sourceNode.loopStart = 11.35;
    sourceNode.loopEnd = 12.1;
    sourceNode.playbackRate.value = rate;
    sourceNode.connect(audioContext.destination);

    pannerNode.pan.value = pan;

    sourceNode.connect(pannerNode);
    pannerNode.connect(audioContext.destination);

    sourceNode.start(0, 0);
}

function playAudio() {
console.log("playAudio")
fetch('Ambition.mp3')
  .then(response => response.arrayBuffer())
  .then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
  .then(audioBuffer => {
    startLoop(audioBuffer,-1);
    startLoop(audioBuffer,1,1.002);
  })
  .catch(e => console.error(e));
}

var playing = "False"

function playOrStop() {
console.log("Playing is set to " + playing)
if (playing === "False") 
    {
    console.log("Play");
    playAudio();
    playing="True";
     }
else {
console.log("Suspend");
//这是一个不起作用的函数

audioContext.suspend().then(function() {
      playing="Suspend";
      console.log("Suspend happened")
        })
     }
}

var b1=document.getElementById("playButton1");
b1.onclick = playOrStop;
第二次单击按钮时,日志上会显示“Suspend Occessed”(暂停发生),但音频不会暂停。 第一次点击的效果和预期的一样。

我执行了你的代码(使用不同的MP3),它在Firefox和Chrome中的效果和预期的一样。我按下按钮,等待声音开始。几秒钟后,我再次按下按钮,声音停止了

但我认为你在Chrome中遇到了一个微妙的错误/功能。当自动播放策略在Chrome中实现时,其目的是尽可能向后兼容。这就是为什么在
AudioScheduledSourceNode
上调用
start()
也可以恢复挂起的上下文

如果按两次按钮,但第一个承诺尚未解决,则在调用
sourceNode.start()
之前,代码将调用
audioContext.suspend()
。即使对
suspend()
的调用起作用,在
AudioScheduledSourceNode
上对
start()
的任何后续调用都会将上下文的状态设置回运行状态

Firefox以不同的方式处理这个问题,大家一致认为Firefox在这个问题上是正确的。规范已经修改以反映()的情况,并且很可能在未来的Chrome版本中得到修复。但是,归档一个bug当然不会有什么坏处

如果要阻止
sourceNode
恢复音频上下文,可以在调用
start()
之前检查上下文的
状态


您的示例在Safari中不起作用,因为它不支持
StereoPannerNode
。我建议使用标准化音频上下文()以实现更好的跨浏览器兼容性,因为我是该库的作者。:-)它还附带了一个在Safari中工作的
StereoPannerNode
实现。

快速阅读,我认为它应该挂起。我会针对你的浏览器提交一个bug。谢谢克里斯-这很有帮助。我搬到了Safari,在那里试了试,效果不错。很高兴知道我没有发疯。
if (audioContext.state === 'running') {
    sourceNode.start(0, 0);
}