chrisguttandin / extendable-media-recorder

An extendable drop-in replacement for the native MediaRecorder.
MIT License
258 stars 13 forks source link

Electron App fails on MediaRecorder mimeType when using 'audio/wav' #649

Closed fpassa closed 3 years ago

fpassa commented 3 years ago

I'm using the following code in my Electron App:

const {MediaRecorder, register} = require('extendable-media-recorder');
const {connect}  = require ('extendable-media-recorder-wav-encoder');
...
if (navigator.mediaDevices.getUserMedia) {
    aStream = navigator.mediaDevices.getUserMedia({
        audio: {deviceId: deviceA}
    }).then(function(stream) {
        const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/wav' });

When attempting to open the mediaRecorder, I can see the following error in the console:

DOMException: Failed to construct 'MediaRecorder': Failed to initialize native MediaRecorder the type provided (audio/wav) is not supported. at /Users/eapp/node_modules/extendable-media-recorder/build/es5/bundle.js:405:35 at new MediaRecorder (/Users/eapp/node_modules/extendable-media-recorder/build/es5/bundle.js:244:15) at file:///Users/eapp/src/index.js:741:31

chrisguttandin commented 3 years ago

Hi @fpassa,

do you somewhere add the WAV codec? You need to call await register(await connect()) somewhere before you can use it.

Maybe that is already enough to fix the problem.

fpassa commented 3 years ago

Thanks for your quick reply, however, I've no idea how to do it, because there is no documentation available around it. May you please provide documentation/code example?

chrisguttandin commented 3 years ago

It's already part of the example code in the README. I know it's a bit cumbersome to call those functions but it was necessary to separate the MediaRecorder ponyfill from the additional encoders and to allow adding other custom encoders, too.

In your case you could do it while you are waiting for the user media.

Promise.all([
    connect().then(register),
    navigator.mediaDevices.getUserMedia({
        audio: {deviceId: deviceA}
    })
]).then(([, stream]) => {
    const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/wav' });
    // ...
})

I hope that helps.

fpassa commented 3 years ago

Hi Chris, Sorry, but I don't know what README are you talking about.

On the other hands, how should I insert that code snippet in below code?

async function getAudio(deviceA){
    await register(await connect());
    if (navigator.mediaDevices.getUserMedia) {
        aStream = navigator.mediaDevices.getUserMedia({
        audio: {deviceId: deviceA}
    }).then(function(stream) {
        aStream = stream;
        mediaRecorder = new MediaRecorder(stream, {mimeType: 'audio/wav'});
        const recordedChunks=[];

        mediaRecorder.addEventListener('dataavailable', function(e) {
            if (e.data.size > 0) recordedChunks.push(e.data);
        });

        mediaRecorder.addEventListener('stop', function() {
            var buffer = new Blob(recordedChunks, { type: "audio/wav" });
            var filename = path.join(PATH, "testMediaRecorder.wav");    
            fs.writeFileSync(filename,buffer);                
        });

        mediaRecorder.start();
},
    function(err) {
        console.log("The following error occured: " + err.name)
    });
    }
}

Thanks in advance

chrisguttandin commented 3 years ago

I was referring to the README of this repository.

Does the code that you posted above not work? There are some things that could be tweaked but it looks alright to me. Do you get any error?

fpassa commented 3 years ago

Oh I see, sorry about it.

Well, I changed a couple of things as I added a separated setup function like this:

async function setup() {
    await register(await connect());
}
setup();

The mimeType error is gone, it's like accepting the mimetype audio/wav. However, my issue now is that I'm not getting anything saved in the destination file, even though I've data in recordedChunks variable. Just wondering if I still need to call the new Blob or if the encoder returns it already.

Any idea on that?

fpassa commented 3 years ago

I fixed the saveFile issue, but end results is a mono wav, instead of stereo. Should I add something else in the MediaRecorder(stream, {mimeType : "audio/wav"}) function?

fpassa commented 3 years ago

Never mind, fixed already by adding this:

aStream = navigator.mediaDevices.getUserMedia({
            audio: {deviceId: deviceA, channelCount: 2, sampleRate: 48000, volume: 1.0}
chrisguttandin commented 3 years ago

Thanks for reporting back. I'm happy to hear that you solved the issue.