Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting blob MIME type to wav still results in webM

I followed this article (the code up to step 6) to make an audio recorder as below. After making the audioBlob, I call a custom function to upload the blob. This function works for other file types.

I pass { type: 'audio/wav' } to the Blob constructor. The resulting file indeed pretends to be a wave file, and would play fine in the browser, but not on iOS. I checked with http://checkfiletype.com/ and discovered the file was actually WebM:

enter image description here

How do I ensure the file is in fact a .wav file?

The code as edited from that article:

navigator.mediaDevices.getUserMedia({ audio: true })
  .then(stream => {
    const mediaRecorder = new MediaRecorder(stream);
    mediaRecorder.start();

    const audioChunks = [];
    mediaRecorder.addEventListener("dataavailable", event => {
      audioChunks.push(event.data);
    });

    mediaRecorder.addEventListener("stop", () => {
      const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });

      // Custom upload function
      uploadFile(audioBlob);
    });

    setTimeout(() => {
      mediaRecorder.stop();
    }, 3000);
  });
like image 592
Bart S Avatar asked Jan 02 '23 03:01

Bart S


1 Answers

How do I ensure the file is in fact a .wav file?

Quite easy, no browsers (I know of) does support exporting to wav natively. So you can be sure your file is not a wav file.

The type option of the Blob constructor only says the browser how it should set the MIME-type for further needs (e.g when it will send it to a server). But it doesn't actually change the content you passed as the first argument.

So it won't magically transform your webm file to an other format.

Now, you do have some options to change the format to which the MediaRecorder will output its content, but the set of supported formats / codecs is up to the implementations, and I don't think any browser supports anything else than opus, either in a webm container or in an ogg * one (* FF only).

[edit]: Actually Chrome now supports PCM in webm.

Thanks to the isTypeSupported method, you can very well setup your code to use this format if it ever becomes available, but I personally wouldn't grow too much hope on this, and would look somewhere else if it is required to output a wav file...

const mime = ['audio/wav', 'audio/mpeg', 'audio/webm', 'audio/ogg']
  .filter(MediaRecorder.isTypeSupported)[0];
const recorder = new MediaRecorder(stream, {
  mimeType: mime
});
like image 93
Kaiido Avatar answered Jan 05 '23 19:01

Kaiido