20

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);
    });
George Netu
  • 2,758
  • 4
  • 28
  • 49
user2212461
  • 3,105
  • 8
  • 49
  • 87
  • 1
    Only Chrome requires `https` AFAIK. Firefox still supports `getUserMedia` in `http` for what it's worth. – jib Jan 17 '16 at 02:27
  • 6
    https://web.whatsapp.com/ actually doesn’t provide anything other than letting you launch the WhatsApp native mobile app on your device, right? That is, `https://web.whatsapp.com/` itself doesn’t let you record audio; instead, the WhatsApp native mobile app does. And the reason the WhatsApp native mobile app doesn’t prompt first-time-users to permit microphone access is because users already granted that permission to it when they installed it. And since there’s no separate “install” step for Web apps, they have to prompt for permission at least the first time a user *uses* the Web app. – sideshowbarker Jan 25 '16 at 06:09

3 Answers3

33

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.

octavn
  • 3,154
  • 32
  • 49
George Netu
  • 2,758
  • 4
  • 28
  • 49
  • 1
    recorderjs uses BaseAudioContext.createScriptProcessor() or AudioContext.createJavaScriptNode() - both are obsolete or deprectated. From https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/createScriptProcessor: _Note: As of the August 29 2014 Web Audio API spec publication, this feature has been marked as deprecated, and was replaced by AudioWorklet_ – Kris Jun 21 '20 at 16:36
20

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

Sasi Varunan
  • 2,806
  • 1
  • 23
  • 34
  • hi, is there a way to put the ask permission step after you click start? i dont know why you are creating a record variable before you are recording anyways..? – Edo Edo Nov 29 '19 at 23:25
  • 1
    @EdoEdo, Update the demo – Sasi Varunan Dec 05 '19 at 12:23
  • As far as I understand Recorderjs works not with Web Audio API nodes but with BaseAudioContext.createScriptProcessor() or AudioContext.createJavaScriptNode() - both are obsolete or deprectated. There even is an open issue about it (https://github.com/mattdiamond/Recorderjs/issues/165). – Kris Jun 21 '20 at 16:40
  • Thanks for an actual working example. Even this Google example (https://developers.google.com/web/fundamentals/media/recording-audio) failed to work on my end. – David Okwii Mar 18 '21 at 00:12
2

The getUserMedia() isn't deprecated, deprecated is using it over http. How far I know the only browser which requires https for getUserMedia() right now is Chrome what I think is correct approach.

If you want ssl/tls for your test you can use free version of CloudFlare.

Whatsapp page doesn't provide any recording functions, it just allow you to launch application.

Good article about getUserMedia

Fully working example with use of MediaRecorder

LJ Wadowski
  • 6,424
  • 11
  • 43
  • 76