我想使用webAudio制作一个简单的VU Meter来指示<video>
元素的音量,其中包含来自网络摄像头的实时流(使用Janus进行流式传输)。我从其他示例中创建了以下函数。在初始化流之后调用它,但analyser.getByteFrequencyData(array);
方法生成的数组全为零。
function meterInit(){
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
videoElement = document.getElementById('remotevideo');
source = audioCtx.createMediaElementSource(videoElement);
analyser = audioCtx.createAnalyser();
analyser.smoothingTimeConstant = 0.2;
analyser.fftSize = 512;
analyser.minDecibels = -200;
source.connect(analyser);
analyser.connect(audioCtx.destination);
javascriptNode = audioCtx.createScriptProcessor(2048, 1, 1);
javascriptNode.connect(audioCtx.destination);
analyser.connect(javascriptNode);
javascriptNode.onaudioprocess = function() {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
var average = getAverageVolume(array)
document.getElementById('vuMeter').value = average;
}
}
function getAverageVolume(array) {
var values = 0;
var average;
var length = array.length;
// get all the frequency amplitudes
for (var i = 0; i < length; i++) {
values += array[i];
}
average = values / length;
return average;
}
答案 0 :(得分:1)
首先获取要使用getByteTimeDomainData的VU表的值,而不是频率。
您的分析仪未提供读数的原因是因为音频未在任何地方路由。脚本处理器节点具有输入和输出数组,您必须将输入数组复制到输出数组以保持信号继续。 这些是onaudioprocess的事件对象的属性。 我建议删除脚本处理器节点,因为它会引入大量的音频延迟,在您的示例+脚本执行时间内至少有2048个样本。 您可以将onaudioprocess中的代码移动到请求动画帧循环中,这将不会导致音频延迟。唯一的缺点是你没有处理每一个样本,所以你可能会错过一个剪辑,你应该能够获得60 fps。 如果检测到剪辑对您的应用程序很重要,您可以在音频数据中查找它们(所有值> 1或<-1的解码音频数据) 基本上所有分析器节点都只给出了完整音频数据的一小部分,并将其从浮点数转换为字节格式。 使用bytetime域数据实际上需要比float更长的时间,因为它内部浮动并且必须转换它。 你可能想要考虑的是VU表主要使用峰值或Rms值,而不是平均值。
答案 1 :(得分:0)
@DavidSherman和@Kaiido - 感谢您的帮助。 @David,我已经将你的标记为正确的答案 - 即使我的剧本还没有实际工作 - 因为这里有一些非常有用的信息。要依次回答你的观点:
<video>
元素,因为上面评论中链接的JS Fiddle有效。我需要回过头来看看我是如何生成<video>
元素的。这很奇怪,因为这有效: var vid = document.getElementById('remotevideo');
vid.muted = !vid.muted;