35

I'm having an issue getting a captured blob from the mediaRecorder api to playback in Chrome (it works in Firefox). Not sure if it's a bug in Chrome.

The error it reports:

undefined:1 Uncaught (in promise) DOMException: Unable to decode audio data

 window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = (navigator.getUserMedia ||
                          navigator.webkitGetUserMedia ||
                          navigator.mozGetUserMedia ||
                          navigator.msGetUserMedia);

var context = new AudioContext();

var record = document.querySelector('#record');
var stop = document.querySelector('#stop');

if (navigator.getUserMedia) {
  console.log('getUserMedia supported.');

  var constraints = {
    audio: true
  };
  var chunks = [];

  var onSuccess = function(stream) {
    var mediaRecorder = new MediaRecorder(stream);
    record.onclick = function() {
      mediaRecorder.start();
      console.log(mediaRecorder.state);
      console.log("recorder started");
      record.style.background = "red";
      stop.disabled = false;
      record.disabled = true;
    }

    stop.onclick = function() {
      mediaRecorder.stop();
      console.log(mediaRecorder.state);
      console.log("recorder stopped");
      record.style.background = "";
      record.style.color = "";

      stop.disabled = true;
      record.disabled = false;
    }

    mediaRecorder.onstop = function(e) {
      console.log("onstop() called.", e);

      var blob = new Blob(chunks, {
        'type': 'audio/wav'
      });
      chunks = [];

      var reader = new FileReader();
      reader.addEventListener("loadend", function() {
        context.decodeAudioData(reader.result, function(buffer) {
          playsound(buffer);
        },
        function(e) {
          console.log("error ", e)
        });
      });
      reader.readAsArrayBuffer(blob);
    }

    mediaRecorder.ondataavailable = function(e) {
      chunks.push(e.data);
    }
  }

  var onError = function(err) {
    console.log('The following error occured: ' + err);
  }

  navigator.getUserMedia(constraints, onSuccess, onError);

} else {
  console.log('getUserMedia not supported on your browser!');
}

function playsound(thisbuffer) {
  var source = context.createBufferSource();
  source.buffer = thisbuffer;
  source.connect(context.destination);
  source.start(0);
}
<button id="record">record</button>
<button id="stop">stop</button>
jib
  • 34,243
  • 11
  • 80
  • 138
Nigel Skeels
  • 359
  • 3
  • 5
  • 1
    Don't suppose it was always throwing an error on context.decodeAudioData()? Did you ever manage to fix this as I can't seem to get it working in chrome. – rtn May 24 '16 at 15:55
  • 1
    I'm seeing the same thing. One thing that might work: try using audio/webm (or whatever your MediaRecoder mimetype is) instead of audio/wav? – Boris Smus May 31 '16 at 22:56
  • Broken because of: https://bugs.chromium.org/p/chromium/issues/detail?id=482934 – Boris Smus Jun 01 '16 at 00:24
  • Can maybe check against the mozilla documentation? https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder – Kim T Apr 01 '17 at 03:49
  • I am no longer getting this bug in Chrome 76 – Matt Ellen Aug 28 '19 at 16:02

2 Answers2

1

I have used your code exactly the way it is. Everything is working fine in Chrome browser.

This issue was fixed when bug https://codereview.chromium.org/1579693006/ was closed and added to the Chrome pipeline.

This is no longer an issue.

0

To close the loop on this, I suspect this was due to the Chrome bug documented in a comment above. It appears this bug was fixed several years ago and should no longer be a problem as WebAudio now uses ffmpeg for decoding.

James Tomasino
  • 3,357
  • 1
  • 18
  • 37