我意识到标题可能有点令人困惑,所以让我提供一些背景信息。
我正在编写一个扩展程序来使用 Google Meet 进行一些音频操作,并且在研究了它的行为之后,我发现了一个我似乎无法解决的奇怪问题。
Google Meet 似乎使用三个<audio>
元素来播放音频,每个元素都有自己的 MediaStreams。通过一些测试,似乎:
- 静音该
<audio>
元素会停止 Google Meet 关于谁在说话的音频可视化。 - 交换
.srcObject
两个音频元素的属性然后调用.play()
它们不会影响 Google Meet 的音频可视化。
这些似乎指向 Google Meet 将源 MediaStream 连接到其音频处理图以创建可视化而不是捕获<audio>
元素,因为我可以在不影响可视化的情况下交换 MediaStream。
但是,考虑到过去的信息,我注意到的另一件事似乎没有意义:
MediaStreamAudioSourceNode
从元素的.srcObject
中添加一个新的<audio>
并将其连接到一个AnalyserNode
表明,即使我将<audio>
元素静音,我仍然可以分析通过MediaStream
.
以下是通过浏览器控制台完成的一些示例代码和输出:
ac = new AudioContext();
an = ac.createAnalyser()
sn = ac.createMediaStreamSource(document.querySelectorAll("audio")[0].srcObject)
sn.connect(an)
function analyse(aNode) {
const ret = new Float32Array(aNode.frequencyBinCount);
aNode.getFloatTimeDomainData(ret);
return ret;
}
analyse(an)
// > Float32Array(1024) [ 0.342987060546875, 0.36688232421875, 0.37115478515625, 0.362457275390625, 0.35150146484375, 0.3402099609375, 0.321075439453125, 0.308746337890625, 0.29779052734375, 0.272552490234375, … ]
document.querySelectorAll("audio")[0].muted = true
analyse(an)
// > Float32Array(1024) [ -0.203582763671875, -0.258026123046875, -0.31134033203125, -0.34375, -0.372802734375, -0.396484375, -0.3919677734375, -0.36328125, -0.31689453125, -0.247650146484375, … ]
// Here, I mute the microphone on *my end* through Google Meet.
analyse(an)
// > Float32Array(1024) [ -0.000030517578125, 0, 0, -0.000030517578125, -0.000091552734375, -0.000091552734375, -0.000091552734375, -0.00006103515625, 0, 0.000030517578125, … ]
// The values here are much closer to zero.
如您所见,当音频元素静音时,AnalyserNode 仍然可以接收音频,但 Meet 的可视化会中断。那是我不明白的。这个怎么可能?
当元素被静音时,连接的 AnalyserNode 怎么能不中断<audio>
,但不使用其他东西.captureStream()
呢?
另一个奇怪的事情是它只发生在 Chrome 上。在 Firefox 上,即使音频元素被静音,Meet 的可视化效果也能正常工作。我认为这可能与已知的 Chrome 问题有关,其中 MediaStreams 需要播放<audio>
元素才能将任何内容输出到音频图(https://stackoverflow.com/a/55644983),但我看不出这将如何影响静音 <audio>
元素。