Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use getusermedia media devices in reactJS to record audio

Hi all I try to implement getUserMedia in my reactJS application to record audio.

I struggle to link my mediaRecorder this.state object to the state changement, and make the media devices API get the function I need to provide my application.

When I click on "start the record" on my view, my console return me :

TypeError: this.state.mediaRecorder.start is not a function

  48 | startRecord() {   
  49 |    
  50 | 
  51 |    this.setState({mediaRecorder:this.state.mediaRecorder.start()});   
  52 |    alert("start record function started =, mediaRecorder state : " + this.state.mediaRecorder.state)   
  53 |    console.log(this.state.mediaRecorder.state); // > recording   
  54 |    console.log("recorder started"); View compiled

Here my app.js :

  import React from "react";
// import "./install.js" ;
import "./mediaDevices-getUserMedia-polyfill.js";
class RecorderAPI extends React.Component {
  constructor(props) {
    super(props);
    this.handleDelete = this.handleDelete.bind(this);
    this.startRecord = this.startRecord.bind(this);
    this.stopRecord = this.stopRecord.bind(this);
    this.recordOnStop = this.recordOnStop.bind(this);

      this.state = {
      mediaRecorder : [],
      audioURL : []
      }
  }

  componentDidMount() {
  if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    console.log('getUserMedia supported');
                                          // target
    navigator.mediaDevices.getUserMedia( {audio: true })

      /***** success callback ******/
      // create a media stream
      .then(function (stream) {
        //if callback succeed, the following code will run :

        // create a new Media Recorder instance
        // with MediaRecorder() constructor
        // this instance is the entry point
        // into using the MediaRecorder API
        stream = new MediaRecorder(stream);
        this.setState({ mediaRecorder: stream });
      })/***** error callback *****/
      .catch(function (err) {
        console.log("error : " + err)
      });
  }
  else {
    console.log("getUserMedia : missing")
  }
}


  // launch mediaRecorder.start methods the stream
  // when the record button is pressed:
  startRecord() {


          this.setState({mediaRecorder: this.state.mediaRecorder.start()});
          alert("start record function started =, mediaRecorder state : " + this.state.mediaRecorder.state)
          console.log( this.state.mediaRecorder.state); // > recording
          console.log("recorder started");

          // As recording progresses we
          // collect the audio data via an event handler
          var chunks = []; // we set a container
          this.setState({mediaRecorder: this.state.mediaRecorder.ondataavailable = function (e) {
            chunks.push(e.data);
          }
        });

  }

  // e MediaRecorder.stop() method
  // to stop the recording when the stop button is pressed
  stopRecord() {
    // callback for onStop function
    this.recordOnStop();
    console.log( this.state.mediaRecorder.state);
    console.log("recorder stopped");

  }

  /***** Grabbing and using the blob *****/

  // stop event finalize our blob there
  // from all the chunks we have received:
  recordOnStop() { //  event handler stop of recording
    console.log("recorder stopped");

    var blob = new Blob(this.chunks, { 'type': "audio/ogg ; codecs=opus" })
    this.chunks = [];
    // creates a DOMString containing a URL representing
    // the object given in the parameter
    this.setState({ audioURL: window.URL.createObjectURL(blob)})
  }

  handleDelete(e) {
    var evtTgt = e.target;
    evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
  }



  render() {
    return (

      <div>
        <button className="dashboard">
          Dashboard</button>

        <span className="controlsBar">

          <button onClick={this.startRecord} className="start">
            Start recording
      </button>
          <button onClick={this.stopRecord} className="stop">
            Stop recording</button>
          <button onClick={this.deleteRecord} className="delete">
            Delete recording
      </button>

        </span>
      </div>
    )
  }
}

export default RecorderAPI;
like image 503
Webwoman Avatar asked May 20 '18 02:05

Webwoman


People also ask

How do I record audio on Reactjs?

Recording AudioSet up two buttons and an HTML5 audio tag in the render() function. To start the audio recording call the start() function in the Mp3Recorder which in turn returns a Promise. }; Now the audio starts to record once the above function is called.

How do I use getUserMedia in react?

Try this? import React, { useEffect } from 'react'; const Chat = (props) => { useEffect(() => { var constraints = { video: true, audio: true }; async function getMedia(constraints) { let stream = null; try { stream = await navigator. mediaDevices. getUserMedia(constraints); // console.

How do I use Navigator mediaDevices getUserMedia?

When getUserMedia() is invoked, the browser asks for permission from the user to use the media inputs (camera or microphone or both) connected to the user device. Syntax : navigator. mediaDevices.

What is navigator mediaDevices getUserMedia?

The MediaDevices . getUserMedia() method prompts the user for permission to use a media input which produces a MediaStream with tracks containing the requested types of media.


2 Answers

HERE MY SOLUTION TO MY QUESTION :

/* eslint-env browser */
import React from 'react';
import Bird from "./sounds/birds.mp3"
const audioType = 'audio/*';

class RecordingAPI extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      recording: false,
      audios: [],
    };
  }

  async componentDidMount() {
    const stream = await navigator.mediaDevices.getUserMedia({audio: true});
    // show it to user
    this.audio.src = window.URL.createObjectURL(stream);
    this.audio.play();
    // init recording
    this.mediaRecorder = new MediaRecorder(stream);
    // init data storage for video chunks
    this.chunks = [];
    // listen for data from media recorder
    this.mediaRecorder.ondataavailable = e => {
      if (e.data && e.data.size > 0) {
        this.chunks.push(e.data);
      }
    };
  }

  startRecording(e) {
    e.preventDefault();
    // wipe old data chunks
    this.chunks = [];
    // start recorder with 10ms buffer
    this.mediaRecorder.start(10);
    // say that we're recording
    this.setState({recording: true});
  }

  stopRecording(e) {
    e.preventDefault();
    // stop the recorder
    this.mediaRecorder.stop();
    // say that we're not recording
    this.setState({recording: false});
    // save the video to memory
    this.saveAudio();
  }

  saveAudio() {
    // convert saved chunks to blob
    const blob = new Blob(this.chunks, {type: audioType});
    // generate video url from blob
    const audioURL = window.URL.createObjectURL(blob);
    // append videoURL to list of saved videos for rendering
    const audios = this.state.audios.concat([audioURL]);
    this.setState({audios});
  }

  deleteAudio(audioURL) {
    // filter out current videoURL from the list of saved videos
    const audios = this.state.audios.filter(a => a !== audioURL);
    this.setState({audios});
  }

  render() {
    const {recording, audios} = this.state;

    return (
      <div className="camera">
        <audio


          style={{width: 400}}
          ref={a => {
            this.audio = a;
          }}>
         <p>Audio stream not available. </p>
        </audio>
        <div>
          {!recording && <button onClick={e => this.startRecording(e)}>Record</button>}
          {recording && <button onClick={e => this.stopRecording(e)}>Stop</button>}
        </div>
        <div>
          <h3>Recorded audios:</h3>
          {audios.map((audioURL, i) => (
            <div key={`audio_${i}`}>
              <audio controls style={{width: 200}} src={audioURL}   />
              <div>
                <button onClick={() => this.deleteAudio(audioURL)}>Delete</button>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }
}
export default RecordingAPI
like image 72
Webwoman Avatar answered Sep 27 '22 19:09

Webwoman


Try this?

import React, { useEffect } from 'react';

const Chat = (props) => {
    useEffect(() => {
        var constraints = {
            video: true,
            audio: true
        };
        async function getMedia(constraints) {
            let stream = null;
            try {
                stream = await navigator.mediaDevices.getUserMedia(constraints);
                // console.log(stream.getAudioTracks()[0].getCapabilities()) ;
                localVideoref.current.srcObject = stream;
                localVideoref.current.muted = true;
            } catch (err) {
                /* handle the error */
                console.log(err);
            }
        }

        getMedia(constraints);
    }, []);
    var localVideoref = React.createRef();

    return (
        <div>
            peer component
            <video ref={localVideoref} autoPlay ></video>
        </div>);
}

export default Chat;

Pretty self-explanatory.

like image 32
Anuraag Barde Avatar answered Sep 27 '22 17:09

Anuraag Barde