简体   繁体   English

如何确保webaudio源停止

[英]How can you make sure webaudio source stops

I have a button that when clicked should stop the audio from playing. 我有一个按钮,单击时应停止播放音频。 My first try it didn't stop the song so I added the while statement. 我的第一次尝试并没有停止这首歌,所以我添加了while语句。 Now not only does it not stop the song but the while loops repetitively and freezes the page. 现在不仅不停止歌曲,而且while循环重复并冻结页面。 This only happens when it's the first song (IE: Autoplay was blocked by chrome so clicking anything but stop gets routed through playNext(); and works fine from there). 只有当它是第一首歌时才会发生这种情况(IE:Autoplay被chrome阻止,所以点击任何东西但是停止通过playNext()进行路由;并且从那里工作正常)。

So say you click Next or Last to start the song. 所以说你点击下一个或最后一个来开始这首歌。 If you click stop before getting to the second song it keeps playing. 如果你在进入第二首歌之前点击停止它继续播放。 If the user then clicks next it plays both songs and stop will only work on the second song. 如果用户然后点击下一个,则播放两首歌曲并且停止仅对第二首歌曲起作用。

playStop(); playStop(); is the one that doesn't stop it. 是一个不能阻止它的人。

//Controls
//Play A Song Again
function playLast() {
    if (context.state == 'running') {
        sourceNode.stop(0);
    }
        console.log(data);
    code = 0;
    if (lastData == null) {
        playNext();
    } else {
        codeRoute();
    }
}
//Stop Playing
function playStop(){
    code = 2;
    while (context.state == 'running') {
        sourceNode.stop(0);
    }
}
//Play Next Song
//Step 1
function playNext(){

        if(context.state == 'running'){
            code =0;
            playFunct();

}else{
    code =1;//0; to play last song.
    console.log(code)
    codeRoute();
}
}

If you need more info than above, the full code is on this page broken up for each step the file takes. 如果您需要的信息多于上述信息,则此页面上的完整代码将针对文件所采用的每个步骤进行细分。

I think the problem is that you store each AudioBufferSourceNode with the same global sourceNode variable. 我认为问题在于您使用相同的全局sourceNode变量存储每个AudioBufferSourceNode。 When you assign a new AudioBufferSourceNode to the same variable by executing sourceNode = context.createBufferSource(); 通过执行sourceNode = context.createBufferSource();时将新的AudioBufferSourceNode分配给同一个变量sourceNode = context.createBufferSource(); you do effectively loose any reference to the previously created AudioBufferSourceNode. 你有效地松开了对先前创建的AudioBufferSourceNode的任何引用。 However that doesn't mean that it will stop playing. 然而,这并不意味着它将停止播放。 It just means that you can't stop it anymore. 这只意味着你不能再阻止它了。

From what I can tell by reading the referenced source code partOne() will be executed on page load. 通过阅读引用的源代码,我可以看出, partOne()将在页面加载时执行。 If the http request succeeds playFirst() gets called and will create and start the first AudioBufferSourceNode. 如果http请求成功,则playFirst()并创建并启动第一个AudioBufferSourceNode。 When autoplay blocks your site there will be no sound but the AudioBufferSourceNode is still scheduled to be started as soon as the AudioContext is going to be resumed. 当自动播放阻止您的站点时,将没有声音,但AudioBufferSourceNode仍然计划在AudioContext恢复后立即启动。

If I understand your code correctly it calls playFunct() on a user interaction to resume the AudioContext. 如果我正确理解您的代码,则会在用户交互上调用playFunct()以恢复AudioContext。 If that happens it will create and start a new AudioBufferSourceNode. 如果发生这种情况,它将创建并启动一个新的AudioBufferSourceNode。 At the same time you loose any reference to the previously created AudioBufferSourceNode which will now also start to play as the AudioContext gets resumed. 同时你松开了对先前创建的AudioBufferSourceNode的任何引用,现在它也将在AudioContext恢复时开始播放。

A brute force solution would be to simply make sure a previously started AudioBufferSourceNode gets stopped whenever you create a new one. 一个强力解决方案是简单地确保以前启动的AudioBufferSourceNode在您创建新的AudioBufferSourceNode时停止。 Just append one line before creating the AudioBufferSourceNode like this. 只需在创建AudioBufferSourceNode之前附加一行,就像这样。

if (sourceNode) {
    sourceNode.stop();
}
sourceNode = context.createBufferSource();

However it might be better to refactor the code to only call it when necessary. 但是,重构代码以在必要时仅调用它可能更好。

It hasn't anything to do with the answer to your question but in your initial code example you expected the state of the AudioContext to change when you stop an AudioBufferSourceNode. 它与您的问题的答案没有任何关系,但在您的初始代码示例中,您希望在停止AudioBufferSourceNode时更改AudioContext的状态。 This is actually not the case. 事实并非如此。 An AudioContext keeps on running unless you call suspend() or close() even if every associated AudioBufferSourceNode is stopped and it doesn't produce any sound anymore. 除非您调用suspend()close()否则AudioContext将继续运行,即使每个关联的AudioBufferSourceNode都已停止且它不再产生任何声音。 It will keep on running forever. 它将继续保持运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM