我正在尝试使一些生成音乐理想地暂停,但我决定停止使用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;
第二次单击按钮-在日志上显示“发生了暂停”,但音频没有暂停。 第一次点击可以正常工作。
答案 0 :(得分:0)
我执行了您的代码(使用其他MP3),并且在Firefox和Chrome中按预期方式工作。我按下按钮,等待声音开始。几秒钟后,我再次按下按钮,声音停止了。
但是我认为您在Chrome中遇到了一个微妙的错误/功能。在Chrome中实施自动播放策略后,该策略应尽可能向后兼容。这就是为什么在start()
上调用AudioScheduledSourceNode
还能恢复暂停的上下文的原因。
如果您两次按下按钮而第一个承诺尚未解决,则您的代码会先调用audioContext.suspend()
,然后再调用sourceNode.start()
。即使对suspend()
的调用有效,随后在start()
上对AudioScheduledSourceNode
的任何调用也会将上下文的状态重新设置为运行。
Firefox的处理方式有所不同,共识是Firefox在这种情况下是正确的。规范已经更改以反映(https://github.com/WebAudio/web-audio-api/pull/1823),并且很可能会在将来的Chrome版本中得到修复。但是,提交一个错误当然不会造成伤害。 https://new.crbug.com
如果要阻止sourceNode
恢复AudioContext,可以在调用state
之前检查上下文的start()
。
if (audioContext.state === 'running') {
sourceNode.start(0, 0);
}
您的示例在Safari中不起作用,因为它不支持StereoPannerNode
。我确实建议使用标准化音频上下文(https://github.com/chrisguttandin/standardized-audio-context),以获得更好的跨浏览器兼容性,因为我是该库的作者。 :-)它还带有StereoPannerNode
实现,可在Safari中使用。