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