chrisguttandin/extendable-media-recorder

compiled bundle.js for seamless use in browser replacing the default MediaRecorder

tatban opened this issue · 4 comments

I am quite new to js and I am struggling to build a simple browser based audio recording prototype using html and js in front end and python flask as backend. I would like to use your MediaRecorder seamlessly in place of default MediaRecorder to get the output in WAV format (which is currently not happening due to lack of browser support for wav in default MediaRecorder). I don't want to use jspm, so I tried compiling your module using browserify, but could not make it work ultimately. So, could you please provide a compiled bundle.js and also let me know how do I integrate it with my existing code as follows? (I mean what are the minimal changes required to use your MediaRecorder?):

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
</head>
<body>
    <div>
    <form name="form_info" onsubmit="return validate()" action="http://127.0.0.1:5000/demo" method="post" enctype="multipart/form-data">
      User name: <input type="text" name="user_name"><br>
      Audio: <input type="file" name="user_audio"><br><br>
        <input type="file" id="file_mic" style="display:none" name="user_audio_mic">
      OR record audio from mic:<br>
      <button type="button" id="start_recording">start recording</button>
      <button type="button" id="stop_recording">stop recording</button><br><br>
        <audio id="audioOP_mic" controls ></audio>
      <input type="submit">
    </form><br><br>
    <div>
        Message from server: {{ message }}
    </div>
  </div>
    <script>
        navigator
        .mediaDevices
        .getUserMedia({audio: true})
        .then(stream => { handlerFunction(stream) });

    function handlerFunction(stream) {
        rec = new MediaRecorder(stream);
        var formEl = document.querySelector("form");
        var formData = new FormData(formEl);
        var fileEl = document.getElementById("file_mic");

        rec.ondataavailable = e => {
            audioChunks.push(e.data);
            if (rec.state == "inactive") {
                let container = new DataTransfer();
                let blob = new Blob(audioChunks, {type: 'audio/wav'});
                let file = new File([blob], "mic_audio.wav", {type:"audio/wav", lastModified:new Date().getTime()});
                container.items.add(file);
                fileEl.files = container.files;
                var a_url = URL.createObjectURL(blob);
                document.getElementById("audioOP_mic").src = a_url;
                //formData.set("user_audio", blob, "mic_audio.wav");
            }
        }
    }

    start_recording.onclick = e => {
        console.log('Recording started..');
        start_recording.disabled = true;
        stop_recording.disabled = false;
        audioChunks = [];
        rec.start();
    };

    stop_recording.onclick = e => {
        console.log("Recording stopped.");
        start_recording.disabled = false;
        stop_recording.disabled = true;
        rec.stop();
    };
    </script>
    <script>
        function validate() {
            document.getElementById("submit").disabled = true;
            return true;
        }
    </script>
</body>
</html>

Hi @tatban, sorry for the long delay. I plan to add a fully compiled bundle to all my open source packages since this was requested by a couple of people. I just need some time to figure out the "right" format.

chrisguttandin/automation-events#49

In the meantime we could try to solve your specific problem. It looks like you don't reference the browserify bundle in the HTML code you posted above. Could that maybe be the problem? Which code do you use to generate the bundle?

I would love to know how this turned out, as my experiment has a similar structure to tatban's.

I also used browserify. I attached to html script tag as <script type="module" src="wavBundle.js"/>

the js i used as my test bundle source for browserify was:

var extendableMediaRecorder=require('extendable-media-recorder');
var extendableMediaRecorderWavEncoder=require('extendable-media-recorder-wav-encoder');

and I used the following import statements in my main source js:

import { MediaRecorder, register } from './wavBundle.js';
import { connect } from './wavBundle.js';

getting the following error:

Uncaught SyntaxError: The requested module './wavBundle.js' does not provide an export named 'MediaRecorder'

Hi @siriusrex,

I would expect that you need to re-export MediaRecorder, register and connect from './wavBundle.js' in order to import them elsewhere. Where is the error coming from? Is it thrown by Browserify or the browser itself?

Any updates on a pre-bundled version of this library? Like a dist.js? I'm using the code in a script tag in my index.html like this:

<script type="module">
    import { MediaRecorder, register } from 'https://dev.jspm.io/npm:extendable-media-recorder';
    import { connect } from 'https://dev.jspm.io/npm:extendable-media-recorder-wav-encoder';
</script>

but I really need to be able to import it like a normal npm library to use this code. This appears to be the only library that does what I need, so it would be really helpful for myself and others to be able to use this without requiring the addition of a bundler into a project's pipeline.

edit: if it helps, i got it working in react by bundling it in rollup. keep in mind i have never used rollup before now and barely know what i'm doing, so this is probably hot garbage. I also had to add lint ignore comments in the files after bundling. below is my rollup config:


import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';

export default {
  input: 'node_modules/extendable-media-recorder/build/es2019/module.js',
  // input: 'node_modules/extendable-media-recorder-wav-encoder/build/es2019/module.js',
  output: {
    file: 'extendable-media-recorder.dist.js',
    // file: 'extendable-media-recorder-wav-encoder.dist.js',
    format: 'umd', // Use UMD or CJS for compatibility with Node.js module system
    // name: 'extendable-media-recorder-wav-encoder', // Name of the global variable when scripts is included in a HTML page
    name: 'extendable-media-recorder', // Name of the global variable when scripts is included in a HTML page
    exports: 'named',
    globals: {
      react: 'React'
    }
  },
  plugins: [
    resolve(),
    commonjs()
  ],
  external: ['react']
};

and in my react component (files are in src/lib):
import { MediaRecorder, register } from '../lib/extendable-media-recorder.dist.js';
import { connect } from '../lib/extendable-media-recorder-wav-encoder.dist.js';