Javascript 解锁web音频的最佳解决方案

Javascript 解锁web音频的最佳解决方案,javascript,audio,cross-browser,web-audio-api,Javascript,Audio,Cross Browser,Web Audio Api,我一直在想一些关于使用Web Audio API使用JavaScript可以做些什么的想法。我知道,根据用户的浏览器,有时如果没有某种用户手势,它就不允许播放音频。我一直在研究如何做到这一点,它们是非常有用的方法,但问题是一些开发人员找到了不同的方法。例如: 使用audioContext.resume()和audioContext.suspend()方法通过更改网络音频的状态来解锁网络音频: 创建空缓冲区并播放以解锁web音频 我基本上知道这两种方法是如何工作的,但是 我的问题是这里发生了什么,

我一直在想一些关于使用Web Audio API使用JavaScript可以做些什么的想法。我知道,根据用户的浏览器,有时如果没有某种用户手势,它就不允许播放音频。我一直在研究如何做到这一点,它们是非常有用的方法,但问题是一些开发人员找到了不同的方法。例如:

  • 使用
    audioContext.resume()
    audioContext.suspend()
    方法通过更改网络音频的状态来解锁网络音频:
  • 创建空缓冲区并播放以解锁web音频
  • 我基本上知道这两种方法是如何工作的,但是 我的问题是这里发生了什么,有什么区别,哪种方法更好等等? 有人能从
    AudioBufferSourceNode
    向我解释一下这个
    source.playbackState
    吗?我以前从没听说过那里的房产。它甚至没有一篇文章,也没有在文章中被提及。 另外,作为一个额外的问题(你不必回答),如果这两种方法都有用,那么如果你知道我的意思,有可能把它们放在一起吗? 对不起,如果你问得太多的话。谢谢:)

    资源:


    这两种方法都有效,但我发现第一种(用户手势中的恢复上下文)更干净。AudioBufferSource方法是一种严重的黑客攻击,目的是为了向后兼容那些开始以用户手势播放缓冲区的旧站点。如果不从手势启动缓冲区,此方法将不起作用。(我想。)


    您想用哪一个取决于您。

    我无法让它工作。用户手势是强制性的吗?。无法在网页加载时播放声音。我正在使用react js。web audiio规范不需要这个手势,但实际上是这样的。我知道Chrome和Firefox需要它。我不使用react.js,所以我没办法。最坏的情况是:把一个按钮放在某个地方,让用户按下它开始应用程序。让按钮创建上下文或恢复上下文。
    function unlockAudioContext(context) {
        if (context.state !== "suspended") return;
        const b = document.body;
        const events = ["touchstart", "touchend", "mousedown", "keydown"];
        events.forEach(e => b.addEventListener(e, unlock, false));
        function unlock() {context.resume().then(clean);}
        function clean() {events.forEach(e => b.removeEventListener(e, unlock));}
    }
    
    var unlocked = false;
    var context = new (window.AudioContext || window.webkitAudioContext)();
    function init(e) {
        if (unlocked) return;
    
        // create empty buffer and play it
        var buffer = context.createBuffer(1, 1, 22050);
        var source = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
    
        /* 
          Phonograph.js use this method to start it
          source.start(context.currentTime);
    
          paulbakaus.com suggest to use this method to start it
          source.noteOn(0);
        */
    
         source.start(context.currentTime) || source.noteOn(0);
    
         setTimeout(function() {
                 if (!unlocked) {
                     if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) {
                         unlocked = true;
                         window.removeEventListener("touchend", init, false);
                     }
                 }
         }, 0);
    }
    
    window.addEventListener("touchend", init, false);