gpt4 book ai didi

javascript - AudioNode.disconnect() 后跟 .connect() 在 Safari 中不起作用

转载 作者:行者123 更新时间:2023-12-02 22:41:37 27 4
gpt4 key购买 nike

我构建了一个语音助手演示,它获取麦克风数据,将其传递给分析器,然后使用 .getByteFrequencyData() 显示视觉效果。其工作原理如下:

  1. 按麦克风按钮连接麦克风输入
  2. 释放麦克风按钮会断开麦克风流,并播放响应的 MP3。
  3. 当 MP3 结束时:返回待机状态,等待按下新按钮再次开始步骤 1。

现场版本:https://dyadstudios.com/playground/daysi/

我实现这一目标的方法如下:

var audioContext = (window.AudioContext) ? new AudioContext() : new window["webkitAudioContext"]();
var analyser = audioContext.createAnalyser();
analyser.fftSize = Math.pow(2, 9); // 512
var sourceMic = undefined; // Microphone stream source
var sourceMp3 = undefined; // MP3 buffer source

// Browser requests mic access
window.navigator.mediaDevices.getUserMedia({audio: true}).then((stream) => {
sourceMic = audioContext.createMediaStreamSource(stream)
})

// 1. Mic button pressed, start listening
listen() {
audioContext.resume();

// Connect mic to analyser
if (sourceMic) {
sourceMic.connect(analyser);
}
}

// 2. Disconnect mic, play mp3
answer(mp3AudioBuffer) {
if (sourceMic) {
// Disconnect mic to prevent audio feedback
sourceMic.disconnect();
}

// Play mp3
sourceMp3 = audioContext.createBufferSource();
sourceMp3.onended = mp3StreamEnded;
sourceMp3.buffer = mp3AudioBuffer;
sourceMp3.connect(analyser);
sourceMp3.start(0);

// Connect to speakers to hear MP3
analyser.connect(audioContext.destination);
}

// 3. MP3 has ended
mp3StreamEnded() {
sourceMp3.disconnect();

// Disconnect speakers (prevents mic feedback)
analyser.disconnect();
}

它在 Firefox 和 Chrome 上运行得很好,但 OSX Safari 12.1 仅在我第一次按下按钮时获取麦克风数据。每当我第二次按下麦克风按钮时,分析​​仪不再获取麦克风数据,但 MP3 数据仍然有效。似乎将麦克风的 AudioNode 连接、断开和重新连接到分析仪会以某种方式破坏它。我查了一下,Safari支持AudioNode.connect()以及AudioNode.disconnect() 。我知道 Safari 的 WebAudio 实现有点过时,是否有解决方法来解决此问题?

最佳答案

Safari 中确实存在一个错误,如果 MediaStreamAudioSourceNode 断开连接一段时间,它会导致它丢弃信号。只要您可能再次需要它,就可以通过不断开连接来避免这种情况。您可以使用 GainNode 来使信号静音。

您可以通过引入一个新变量来控制音量来做到这一点。

const sourceMicVolume = audioContext.createGain();

sourceMicVolume.gain.value = 0;

然后,当您实例化 sourceMic 时,您需要立即连接所有内容。

sourceMic = audioContext.createMediaStreamSource(stream);

sourceMic.connect(sourceMicVolume);
sourceMicVolume.connect(analyser);

在事件处理程序中,您只需设置增益的音量,而不是(断开)连接节点。在 listen() 函数中,如下所示:

if (sourceMic) {
sourceMicVolume.gain.value = 1;
}

answer() 函数中,它看起来像这样:

if (sourceMic) {
sourceMicVolume.gain.value = 0;
}

关于javascript - AudioNode.disconnect() 后跟 .connect() 在 Safari 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58564669/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com