hackingbeauty / react-mic

Record audio from a user's microphone and display a cool visualization.
https://hackingbeauty.github.io/react-mic/
450 stars 157 forks source link

several issues in copy/pasted example in create-react-app #91

Closed borjanavarro closed 4 years ago

borjanavarro commented 4 years ago

I've just pasted the example and run it in a create-react-app instance, simply I've just added a download button. Recordings sometimes are not working I don't know why. There are two warnings in my console log, could be related. Besides the fact that red icon in tab doesn't disappear and onData function still logs data chunks when I stop the recording, so that makes me think that recording isn't stopped.

I'm using MacOS 10.15.3 and Chrome 80.0.3987.149 and react 16.13.1

import React from 'react';
import { ReactMic } from 'react-mic';

export class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      record: false
    }
  }

  startRecording = () => {
    navigator.mediaDevices.getUserMedia({ audio: true, video: false })
      .then( () => {
        this.setState({ record: true });
      });
  }

  stopRecording = () => {
    this.setState({ record: false });
  }

  onData(recordedBlob) {
    console.log('chunk of real-time data is: ', recordedBlob);
  }

  onStop(recordedBlob) {
    console.log('recordedBlob is: ', recordedBlob);
    const downloadLink = document.getElementById('download');
    downloadLink.href = URL.createObjectURL(recordedBlob.blob);
    downloadLink.download = "example";
  }

  render() {
    return (
      <div>
        <ReactMic
          record={this.state.record}
          className="sound-wave"
          onStop={this.onStop}
          onData={this.onData}
          strokeColor="#000000"
          backgroundColor="#FF4081" />
        <button onClick={this.startRecording} type="button">Start</button>
        <button onClick={this.stopRecording} type="button">Stop</button>
        <a id="download">Download</a> 
      </div>
    );
  }
}

export default App;
Screenshot 2020-03-26 at 00 53 59
hackingbeauty commented 4 years ago

@borjanavarro I am not experiencing similar issues. Have you checked out the demo app that is using React-Mic? The red dot disappears after recording stops, and onData does not continue to run after recording has stopped.

Demo app: https://hackingbeauty.github.io/react-mic/

ryanrouleau commented 4 years ago

I'm having the same issue as above.

When I copy over the example code to an empty page it works flawlessly, when I add it to a page with other stuff going on it breaks (red icon doesn't disappear, returned blob is corrupted/unreadable).

I noticed that the onStart() callback is being called twice immediately when it doesn't work (even though recording only goes from false -> true once). Have a strong feeling of what's happening is that two renders take place immediately when recording goes from false -> true (I have an effect fire off when that happens causing the next render). So this causes ReactMic to render twice before the navigator.mediaDevices.getUserMedia(constraints) promise resolves and initializes mediaRecorder in MicrophoneRecorder.js. Sooo then it initializes itself twice causing problems. Haven't looked at the code here in the library enough to know how to fix it but in the mean time I think I'll be able to modify my client code enough to prevent the immediate re-render. Will report back if that fixes it.

ryanrouleau commented 4 years ago

Hey yeah that was the problem. I'll send a small pr in the coming days to fix it. Should be as a simple as moving the call to microphoneRecorder.startRecording() up into a componentDidUpdate in ReactMic.js and only calling it if recording went from false to true. Probably be worth it to do the same for stopRecording as well.