如何使用web audio api获取麦克风输入音量值?

kik*_*unk 22 javascript html5 google-chrome html5-audio web-audio-api

我正在使用带有网络音频api的麦克风输入,需要获得音量值.

现在我已经让麦克风工作了:http: //updates.html5rocks.com/2012/09/Live-Web-Audio-Input-Enabled

另外,我知道有一种操纵音频文件的方法:http: //www.html5rocks.com/en/tutorials/webaudio/intro/

    // 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;
Run Code Online (Sandbox Code Playgroud)

但是如何将这两者结合起来并获得输入音量值?我只需要价值,不需要操纵它.

有人知道吗?

cwi*_*lso 22

想要获得"音量"有两个主要原因:1)检测源"剪辑"的时间 - 即信号的绝对值超过预设水平,通常非常接近1.0,它将开始削波.2)让用户感觉他们的信号有多大声.

我单独列出这些的原因是因为第一个需要您处理每个样本 - 因为您可能会错过短暂的瞬态.为此,您需要使用ScriptProcessor节点,并且您必须遍历onaudioprocess内缓冲区中的每个样本,以查找高于剪辑级别的绝对值.您可以确定RMS水平 - 只需将每个样本的平方和除以N并取平方根.但是,请勿在onaudioprocess中渲染 - 设置您在requestAnimationFrame上访问的值.

您还可以使用AnalyserNode进行电平检测,并将数据平均化,就像上面的答案在getAverageVolume中所做的那样.但是,上面的答案并不能很好地利用ScriptProcessor - 事实上,它根本不对脚本节点进行处理,甚至不传递数据,它只是像计时器回调一样使用它.使用requestAnimationFrame作为可视回调,您将获得更好的服务; 不要像这样在onaudioprocess里面设置布局或视觉参数,或者你要求捶打你的音频系统.如果您不需要剪辑检测,只需在AnalyserNode上从上面执行getByteFrequencyCount/getAverageVolume(但您应该最小化Analyzer中的波段数 - 我认为64是最小的),您应该预先分配和重用Uint8Array而不是每次都分配它(这会增加垃圾收集).

  • 为什么使用“getByteFrequencyData”而不是“getByteTimeDomainData”? (3认同)
  • 有什么“快速”方法可以达到峰值水平吗?我希望这是 AnalyserNode 的一个基本功能(除了 RMS 之外)。它为我们解决了 FFT 的所有麻烦,但没有提供简单峰值或 RMS 仪表所需的基础知识。ScriptProcessorNode 仍然是最快的方法吗?如果是这样,恐怕它太慢了,无法一次用于多个频道。召唤你的专业知识并希望奇迹出现。:-) (2认同)

小智 8

虽然有点晚了,但还是希望能帮到你。

h5_get_microphone_volume

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
}
Run Code Online (Sandbox Code Playgroud)

  • this.volume 的单位是什么?数据库?某物的百分比? (6认同)
  • 我投了赞成票,但上面的代码是由 Chris Wilson @cwilso 编写的。请参阅:https://github.com/cwilso/volume-meter (2认同)

Mp *_*ega 6

当我学习HTML 5时,我为播放音频做了音量显示.

我按照这个很棒的教程

http://www.smartjava.org/content/exploring-html5-web-audio-visualizing-sound

 // 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;
  }
Run Code Online (Sandbox Code Playgroud)

注意:我只是不知道它是否适用于来自麦克风的音频输入