Search code examples
javascriptreactjsaudioxmlhttprequestblob

Send audio from ReactMediaRecorder to a server


I'm trying to program a Client, that can record audio data and then send it to a server.

I don't have much experience in front-end development. I was told to use React and so I'm trying to use ReactMediaRecorder (https://github.com/avasthaathraya/react-media-recorder).


  render () {
        return (
            <ReactMediaRecorder
                audio
                whenStopped={blobUrl=>this.setState({audio: blobUrl })}
                render={({startRecording, stopRecording, mediaBlob }) => (
                    <div>
                        <button id="recorder" className="button" onClick={startRecording}>Start Recording</button>
                        <button className="button" onClick={() => {stopRecording();this.upload()}}>Stop Recording</button>
                        <audio id="player" src={mediaBlob} controls />
                    </div>
                )}
            />
        )
    }



    upload() {
        console.log("upload was called with blob " + this.state.audio)
        //if (false) {
        if (this.state.audio != null) {
            console.log("got here, type of audio is " + this.state.audio)


            var xhr = new XMLHttpRequest();
            var filename = new Date().toISOString();
            xhr.onload = function (e) {
                if (this.readyState === 4) {
                    console.log("Server returned: ", e.target.responseText);
                }
            };
            var fd = new FormData();
            fd.append("audio_data", this.state.audio, filename);
            xhr.open("POST", "http://127.0.0.1:3000", true);
            xhr.send(fd);
        }
    }

At first it seemed very straightforward. But I don't get why I can't send the mediaBlob. The formData.append says, that this.state.audio is not of type Blob. So I checked it's type in the console log, and found out it is of type stringContent. I tried to create a Blob from that by using new Blob() but failed. I also fail to find information of this type.

Does somebody know what to do?


Solution

  • Ok I finally got it. The mistake was, that mediaBlob is actually not blob, but a blob Url. So first we need to load it and then we can send it. I changed my upload function to:

    upload(mediaBlob) {
        if (this.state.audio != null) {
            //load blob
            var xhr_get_audio = new XMLHttpRequest();
            xhr_get_audio.open('GET', mediaBlob, true);
            xhr_get_audio.responseType = 'blob';
            xhr_get_audio.onload = function(e) {
                if (this.status == 200) {
                    var blob = this.response;
                    //send the blob to the server
                    var xhr_send = new XMLHttpRequest();
                    var filename = new Date().toISOString();
                    xhr_get_audio.onload = function (e) {
                        if (this.readyState === 4) {
                            console.log("Server returned: ", e.target.responseText);
                        }
                    };
                    var fd = new FormData();
                    fd.append("audio_data",blob, filename);
                    xhr_send.open("POST", "http://localhost/uploadAudio", 
                    true);
                    xhr_send.send(fd);
                }
            };
            xhr_get_audio.send();
        }
    } 
    

    Now it works fine.