Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture audio in javascript?

I am currently using getUserMedia(), which is only working on Firefox and Chrome, yet it got deprecated and works only on https (in Chrome). Is there any other/better way to get the speech input in javascript that works on all platforms?

E.g. how do websites like web.whatsapp.com app record audio? getUserMedia() prompts first-time-users to permit audio recording, whereas the Whatsapp application doesn't require the user's permission.

The getUserMedia() I am currently using looks like this:

navigator.getUserMedia(
    {
        "audio": {
            "mandatory": {
                "googEchoCancellation": "false",
                "googAutoGainControl": "false",
                "googNoiseSuppression": "false",
                "googHighpassFilter": "false"
            },
            "optional": []
        },
    }, gotStream, function(e) {
        console.log(e);
    });
like image 762
user2212461 Avatar asked Jan 15 '16 21:01

user2212461


2 Answers

Chrome 60+ does require using https, since getUserMedia is a powerful feature. The API access shouldn't work in non-secure domains, as that API access may get bled over to non-secure actors. Firefox still supports getUserMedia over http, though.

I've been using RecorderJS and it served my purposes well. Here is a code example. (source)

function RecordAudio(stream, cfg) {

  var config = cfg || {};
  var bufferLen = config.bufferLen || 4096;
  var numChannels = config.numChannels || 2;
  this.context = stream.context;
  var recordBuffers = [];
  var recording = false;
  this.node = (this.context.createScriptProcessor ||
    this.context.createJavaScriptNode).call(this.context,
    bufferLen, numChannels, numChannels);

  stream.connect(this.node);
  this.node.connect(this.context.destination);

  this.node.onaudioprocess = function(e) {
    if (!recording) return;
    for (var i = 0; i < numChannels; i++) {
      if (!recordBuffers[i]) recordBuffers[i] = [];
      recordBuffers[i].push.apply(recordBuffers[i], e.inputBuffer.getChannelData(i));
    }
  }

  this.getData = function() {
    var tmp = recordBuffers;
    recordBuffers = [];
    return tmp; // returns an array of array containing data from various channels
  };

  this.start() = function() {
    recording = true;
  };

  this.stop() = function() {
    recording = false;
  };
}

The usage is straightforward:

var recorder = new RecordAudio(userMedia);
recorder.start();
recorder.stop();
var recordedData = recorder.getData()

Edit: You may also want to check this answer if nothing works.

like image 141
George Netu Avatar answered Nov 15 '22 10:11

George Netu


Recorder JS does the easy job for you. It works with Web Audio API nodes

Chrome and Firefox Browsers has evolved now. There is an inbuilt MediaRecoder API which does audio recording for you.

navigator.mediaDevices.getUserMedia({audio:true})
    .then(stream => {
        rec = new MediaRecorder(stream);
        rec.ondataavailable = e => {
            audioChunks.push(e.data);
            if (rec.state == "inactive"){
               // Use blob to create a new Object URL and playback/download
            }
        }
    })
    .catch(e=>console.log(e));

Working demo

MediaRecoder support starts from

Chrome support: 47

Firefox support: 25.0

like image 21
Sasi Varunan Avatar answered Nov 15 '22 10:11

Sasi Varunan