从浏览器访问麦克风 - Javascript

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27846392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:45:16  来源:igfitidea点击:

Access microphone from a browser - Javascript

javascriptaudioweb-audio-apimicrophonerecording

提问by poisonlocc

Is it possible to access the microphone (built-in or auxiliary) from a browser using client-side JavaScript?

是否可以使用客户端 JavaScript 从浏览器访问麦克风(内置或辅助)?

Ideally, it would store the recorded audio in the browser. Thanks!

理想情况下,它会将录制的音频存储在浏览器中。谢谢!

回答by Scott Stensland

Here we capture microphone audio as a Web Audio API event loop buffer using getUserMedia() ... time domain and frequency domain snippets of each audio event loop buffer are printed (viewable in browser console just hit key F12 or ctrl+shift+i )

在这里,我们使用 getUserMedia() 将麦克风音频捕获为 Web Audio API 事件循环缓冲区……打印每个音频事件循环缓冲区的时域和频域片段(在浏览器控制台中只需按 F12 或 ctrl+shift+i 键即可查看)

<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>capture microphone audio into buffer</title>

<script type="text/javascript">


  var webaudio_tooling_obj = function () {

    var audioContext = new AudioContext();

    console.log("audio is starting up ...");

    var BUFF_SIZE = 16384;

    var audioInput = null,
        microphone_stream = null,
        gain_node = null,
        script_processor_node = null,
        script_processor_fft_node = null,
        analyserNode = null;

    if (!navigator.getUserMedia)
            navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
                          navigator.mozGetUserMedia || navigator.msGetUserMedia;

    if (navigator.getUserMedia){

        navigator.getUserMedia({audio:true}, 
          function(stream) {
              start_microphone(stream);
          },
          function(e) {
            alert('Error capturing audio.');
          }
        );

    } else { alert('getUserMedia not supported in this browser.'); }

    // ---

    function show_some_data(given_typed_array, num_row_to_display, label) {

        var size_buffer = given_typed_array.length;
        var index = 0;
        var max_index = num_row_to_display;

        console.log("__________ " + label);

        for (; index < max_index && index < size_buffer; index += 1) {

            console.log(given_typed_array[index]);
        }
    }

    function process_microphone_buffer(event) { // invoked by event loop

        var i, N, inp, microphone_output_buffer;

        microphone_output_buffer = event.inputBuffer.getChannelData(0); // just mono - 1 channel for now

        // microphone_output_buffer  <-- this buffer contains current gulp of data size BUFF_SIZE

        show_some_data(microphone_output_buffer, 5, "from getChannelData");
    }

    function start_microphone(stream){

      gain_node = audioContext.createGain();
      gain_node.connect( audioContext.destination );

      microphone_stream = audioContext.createMediaStreamSource(stream);
      microphone_stream.connect(gain_node); 

      script_processor_node = audioContext.createScriptProcessor(BUFF_SIZE, 1, 1);
      script_processor_node.onaudioprocess = process_microphone_buffer;

      microphone_stream.connect(script_processor_node);

      // --- enable volume control for output speakers

      document.getElementById('volume').addEventListener('change', function() {

          var curr_volume = this.value;
          gain_node.gain.value = curr_volume;

          console.log("curr_volume ", curr_volume);
      });

      // --- setup FFT

      script_processor_fft_node = audioContext.createScriptProcessor(2048, 1, 1);
      script_processor_fft_node.connect(gain_node);

      analyserNode = audioContext.createAnalyser();
      analyserNode.smoothingTimeConstant = 0;
      analyserNode.fftSize = 2048;

      microphone_stream.connect(analyserNode);

      analyserNode.connect(script_processor_fft_node);

      script_processor_fft_node.onaudioprocess = function() {

        // get the average for the first channel
        var array = new Uint8Array(analyserNode.frequencyBinCount);
        analyserNode.getByteFrequencyData(array);

        // draw the spectrogram
        if (microphone_stream.playbackState == microphone_stream.PLAYING_STATE) {

            show_some_data(array, 5, "from fft");
        }
      };
    }

  }(); //  webaudio_tooling_obj = function()



</script>

</head>
<body>

    <p>Volume</p>
    <input id="volume" type="range" min="0" max="1" step="0.1" value="0.5"/>

</body>
</html>

Since this code exposes microphone data as a buffer you could add ability to stream using websockets or simply aggregate each event loop buffer into a monster buffer then download the monster to a file

由于此代码将麦克风数据公开为缓冲区,因此您可以添加使用 websockets 进行流式传输的能力,或者简单地将每个事件循环缓冲区聚合到一个怪物缓冲区中,然后将怪物下载到一个文件中

Notice the call to

注意调用

    var audioContext = new AudioContext();

which indicates its using the Web Audio APIwhich is baked into all modern browsers (including mobile browsers) to provide an extremely powerful audio platform of which tapping into the mic is but a tiny fragment ... NOTEthe CPU usage jumps up due to this demo writing each event loop buffer into browser console log which is for testing only so actual use is far less resource intensive even when you mod this to stream audio to elsewhere

这表明它使用Web Audio API,该API已融入所有现代浏览器(包括移动浏览器),以提供极其强大的音频平台,其中麦克风只是一个小片段......注意CPU 使用率因此而上升演示将每个事件循环缓冲区写入浏览器控制台日志,该日志仅用于测试,因此即使您将其修改为将音频流式传输到其他地方,实际使用的资源密集程度也会大大降低

Links to some Web Audio API documentation

一些 Web Audio API 文档的链接

回答by user2879041

Yes you can.

是的你可以。

Using the getUserMedia()API, you can capture raw audio input from your microphone.

使用getUserMedia()API,您可以捕获来自麦克风的原始音频输入。

https://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/

https://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/