繁体   English   中英

获取用户音频时的 Google Chrome Javascript 问题 - 不允许启动 AudioContext

[英]Google Chrome Javascript issue in getting user audio - The AudioContext was not allowed to start

我有这个 Javascript 代码,当用户点击麦克风按钮时,我用它来捕获用户的音频输入。 此代码适用于 Mozila Firefox,但当我在 Google Chrome 中使用它时,它不起作用并在控制台中显示此警告/错误 - The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.

var r = function() {
            var e = {}
              , t = void 0
              , n = getBotConfig()
              , r = new Audio("data:audio/wav;base64,")
              , o = !1;
            if (!n.isIE()) {
                window.AudioContext = window.AudioContext || window.webkitAudioContext;
                var i = new AudioContext;
                e.toggleRecording = function(e, t, n, r, s, a, c) {
                    e.classList.contains("recording") ? (e.classList.remove("recording"),
                    o = !1,
                    t.emit("end-recording", {
                        session_id: a,
                        bot_id: c
                    }),
                    document.getElementById("btnToggle").setAttribute("style", "background-color:transparent"),
                    document.getElementsByClassName("fa-microphone")[0] && document.getElementsByClassName("fa-microphone")[0].setAttribute("style", "color:" + s)) : (e.classList.add("recording"),
                    o = !0,
                    t.emit("start-recording", {
                        numChannels: 1,
                        bps: 16,
                        fps: parseInt(i.sampleRate),
                        session_id: a,
                        bot_id: c
                    }),
                    document.getElementById("btnToggle").setAttribute("style", "background-color:" + n),
                    document.getElementsByClassName("fa-microphone")[0] && document.getElementsByClassName("fa-microphone")[0].setAttribute("style", "color:" + r))
                }
                ,
                e.onAudioTTS = function(e) {
                    try {
                        r.pause(),
                        c(e)
                    } catch (t) {
                        c(e)
                    }
                }
                ,
                e.initAudio = function(e, n, r) {
                    console.log("audio initiated"),
                    t = e,
                    navigator.getUserMedia || (navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia),
                    navigator.cancelAnimationFrame || (navigator.cancelAnimationFrame = navigator.webkitCancelAnimationFrame || navigator.mozCancelAnimationFrame),
                    navigator.requestAnimationFrame || (navigator.requestAnimationFrame = navigator.webkitRequestAnimationFrame || navigator.mozRequestAnimationFrame),
                    navigator.getUserMedia({
                        audio: !0
                    }, a, function(e) {
                        alert("Error getting audio"),
                        console.log(e)
                    })
                }
                ;
                var s = function(e) {
                    var t = i.createChannelSplitter(2)
                      , n = i.createChannelMerger(2);
                    return e.connect(t),
                    t.connect(n, 0, 0),
                    t.connect(n, 0, 1),
                    n
                }
                  , a = function(e) {
                    var n = i.createGain()
                      , r = i.createMediaStreamSource(e)
                      , a = r;
                    a = s(a),
                    a.connect(n);
                    var c = (i.createScriptProcessor || i.createJavaScriptNode).call(i, 1024, 1, 1);
                    c.onaudioprocess = function(e) {
                        if (o) {
                            for (var n = e.inputBuffer.getChannelData(0), r = new ArrayBuffer(2 * n.length), i = new DataView(r), s = 0, a = 0; s < n.length; s++,
                            a += 2) {
                                var c = Math.max(-1, Math.min(1, n[s]));
                                i.setInt16(a, c < 0 ? 32768 * c : 32767 * c, !0)
                            }
                            t.emit("write-audio", r)
                        }
                    }
                    ,
                    n.connect(c),
                    c.connect(i.destination);
                    var u = i.createGain();
                    u.gain.value = 0,
                    n.connect(u),
                    u.connect(i.destination)
                }
                  , c = function(e) {
                    r.src = "data:audio/wav;base64," + e,
                    r.play()
                };
                return e
            }
        };

警告/错误出现在行var i = new AudioContext; . 它以前也可以在 Google Chrome 浏览器上运行,但现在无法运行。 Google 开发者页面上的描述说必须使用resume()但我不确定我应该如何以及在哪里执行此操作。

你应该能够在调用play()之前在某个地方调用resume() play() 重要的是在用户操作/事件中调用它 - 就像单击麦克风按钮一样。

关键点:如果在文档接收到用户手势之前创建了一个 AudioContext,它将在“暂停”状态下创建,并且您需要在接收到用户手势后调用 resume()。

来自https://developers.google.com/web/updates/2017/09/autoplay-policy-changes

它以前也可以在 Google Chrome 浏览器上运行,但现在无法运行。

最近在 chrome 更新中实施了新政策。

如果您的问题与访问麦克风时的 p5.js 有关,请在setup执行此操作

function setup() {
  mic = new p5.AudioIn();
  mic.start();
  getAudioContext().resume();
}

或者在文档中添加touchStarted函数。 您必须单击网页才能触发此功能。

function touchStarted() {
  getAudioContext().resume();
}

暂无
暂无

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

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