Javascript 如何使用web audio api获取麦克风输入音量值?
我正在使用带有web audio api的麦克风输入,需要获取音量值 现在我已经让麦克风工作了: 另外,我知道有一种方法可以控制音频文件的音量: 但是,如何将这两者结合起来并获得输入体积值呢? 我只需要计算值,不需要操纵它Javascript 如何使用web audio api获取麦克风输入音量值?,javascript,html,google-chrome,html5-audio,web-audio-api,Javascript,Html,Google Chrome,Html5 Audio,Web Audio Api,我正在使用带有web audio api的麦克风输入,需要获取音量值 现在我已经让麦克风工作了: 另外,我知道有一种方法可以控制音频文件的音量: 但是,如何将这两者结合起来并获得输入体积值呢? 我只需要计算值,不需要操纵它 有人知道吗?我在学习HTML 5时,为播放音频做了音量显示 我遵循了这个很棒的教程 //设置分析器 Analyzer=context.createAnalyzer(); Analyzer.smoothingTimeConstant=0.3; Analyzer.fftSi
有人知道吗?我在学习HTML 5时,为播放音频做了音量显示 我遵循了这个很棒的教程
//设置分析器
Analyzer=context.createAnalyzer();
Analyzer.smoothingTimeConstant=0.3;
Analyzer.fftSize=1024;
javascriptNode=context.createScriptProcessor(2048,1,1);
javascriptNode.onaudioprocess=function(){
//获取平均值,bincount为fftsize/2
var阵列=新UINT8阵列(分析仪频率BINCOUNT);
分析仪。GetByTefFrequencyData(阵列);
var average=getAverageVolume(数组)
log('VOLUME:'+average);//这是卷
}
函数getAverageVolume(数组){
var值=0;
var平均值;
var length=array.length;
//获得所有的频率振幅
对于(变量i=0;i
注意:我只是不知道它是否能在来自麦克风的音频输入上工作我在学习HTML 5时为播放音频做了音量显示 我遵循了这个很棒的教程
//设置分析器
Analyzer=context.createAnalyzer();
Analyzer.smoothingTimeConstant=0.3;
Analyzer.fftSize=1024;
javascriptNode=context.createScriptProcessor(2048,1,1);
javascriptNode.onaudioprocess=function(){
//获取平均值,bincount为fftsize/2
var阵列=新UINT8阵列(分析仪频率BINCOUNT);
分析仪。GetByTefFrequencyData(阵列);
var average=getAverageVolume(数组)
log('VOLUME:'+average);//这是卷
}
函数getAverageVolume(数组){
var值=0;
var平均值;
var length=array.length;
//获得所有的频率振幅
对于(变量i=0;i
注意:我只是不知道它是否能在来自麦克风的音频输入上工作想要获得“音量”有两个主要原因:
ScriptProcessor
节点,并且必须迭代onaudioprocess
中缓冲区中的每个样本,以查找高于剪辑级别的绝对值。你也可以确定RMS的水平-只需将每个样本的平方和除以N,然后取平方根不从音频处理中的渲染
,但是-设置在请求动画帧
上访问的值
您还可以使用
AnalyzerNode
来进行液位检测,然后对数据进行平均,就像使用getAverageVolume
时一样。然而,另一个答案是不是ScriptProcessor
的良好使用-事实上,它根本不处理脚本节点,甚至不传递数据,它只是像计时器回调一样使用它。使用requestAnimationFrame
作为可视回调,您将得到更好的服务;不要像这样从内部对音频处理设置布局或视觉参数,否则你会乞求破坏你的音频系统。如果您不需要剪辑检测,只需在AnalyzerNode
上从上方执行getByteFrequencyCount
/getAverageVolume
(但您应该最小化分析仪中的频带数-我认为64是最小值),并且您应该预分配和重用Uint8Array
,而不是每次分配它(这将放大垃圾收集)。想要获取“卷”有两个主要原因:
检测源“剪辑”的时间,即信号的绝对值超过预设水平,通常非常接近1.0,开始剪辑
让用户感觉到他们的信号有多大
我单独列出这些示例的原因是,第一个示例要求您处理每个示例,否则您可能会错过一个短暂的瞬态。为此,您需要使用ScriptProcessor
节点,并且必须迭代onaudioprocess
中缓冲区中的每个示例,以查找上面的绝对值您的剪辑级别。您也可以确定RMS级别-只需将每个样本的平方和除以N,然后取平方根。不要从onaudioprocess
中进行渲染,但是-设置您在requestAnimationFrame
上访问的值
您还可以使用AnalyzerNode
来进行级别检测,然后对数据进行平均,就像使用getAverageVolume
时所做的那样。但是,另一个答案是不是很好地使用了ScriptProcessor
——事实上,它根本不处理脚本节点,甚至不传递数据通过,它只是像计时器回调一样使用它。如果使用requestAnimationFrame
作为可视回调,您将得到更好的服务;永远不要设置布局或
// Create a gain node.
var gainNode = context.createGain();
// Connect the source to the gain node.
source.connect(gainNode);
// Connect the gain node to the destination.
gainNode.connect(context.destination);
// Reduce the volume.
gainNode.gain.value = 0.5;
// setup a analyzer
analyser = context.createAnalyser();
analyser.smoothingTimeConstant = 0.3;
analyser.fftSize = 1024;
javascriptNode = context.createScriptProcessor(2048, 1, 1);
javascriptNode.onaudioprocess = function() {
// get the average, bincount is fftsize / 2
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
var average = getAverageVolume(array)
console.log('VOLUME:' + average); //here's the volume
}
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;
}
var audioContext = new (window.AudioContext || window.webkitAudioContext)()
var mediaStreamSource = null
var meter = null
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({audio: true}).then((stream) => {
mediaStreamSource = audioContext.createMediaStreamSource(stream)
meter = createAudioMeter(audioContext)
mediaStreamSource.connect(meter)
})
}
function createAudioMeter(audioContext, clipLevel, averaging, clipLag) {
const processor = audioContext.createScriptProcessor(512)
processor.onaudioprocess = volumeAudioProcess
processor.clipping = false
processor.lastClip = 0
processor.volume = 0
processor.clipLevel = clipLevel || 0.98
processor.averaging = averaging || 0.95
processor.clipLag = clipLag || 750
// this will have no effect, since we don't copy the input to the output,
// but works around a current Chrome bug.
processor.connect(audioContext.destination)
processor.checkClipping = function () {
if (!this.clipping) {
return false
}
if ((this.lastClip + this.clipLag) < window.performance.now()) {
this.clipping = false
}
return this.clipping
}
processor.shutdown = function () {
this.disconnect()
this.onaudioprocess = null
}
return processor
}
function volumeAudioProcess(event) {
const buf = event.inputBuffer.getChannelData(0)
const bufLength = buf.length
let sum = 0
let x
// Do a root-mean-square on the samples: sum up the squares...
for (var i = 0; i < bufLength; i++) {
x = buf[i]
if (Math.abs(x) >= this.clipLevel) {
this.clipping = true
this.lastClip = window.performance.now()
}
sum += x * x
}
// ... then take the square root of the sum.
const rms = Math.sqrt(sum / bufLength)
// Now smooth this out with the averaging factor applied
// to the previous sample - take the max here because we
// want "fast attack, slow release."
this.volume = Math.max(rms, this.volume * this.averaging)
document.getElementById('audio-value').innerHTML = this.volume
}