closeio / mic-recorder-to-mp3

Microphone Recorder to mp3
MIT License
244 stars 138 forks source link

Error when clicked stop #37

Open kurund opened 3 years ago

kurund commented 3 years ago

Hello,

I am using this example: https://github.com/closeio/mic-recorder-to-mp3#how-to-use and converted it to functional component.

I have got the below error after stop action.

TypeError: Cannot read property 'finish' of undefined

 15939 | value: function getMp3() {
  15940 |   var _this3 = this;
  15941 | 
> 15942 |   var finalBuffer = this.lameEncoder.finish();
        | ^  15943 | 
  15944 |   return new Promise(function (resolve, reject) {
  15945 |     if (finalBuffer.length === 0) {

console.log(this.lameEncoder); is null

Any suggestions on how to fix this?

nadavS3 commented 3 years ago

had this problem too , it seems that the variable that holds the MicRecorder element gets reseted after the start. if you debug the code live you can see that when in the start function you indeed have the lameEncoder property on the Mp3Recorder but when leaving the code block that called the start function the lameEncoder property dissappear from the element and that he gets reseted. then when calling the finish function it doesnt have the lameEncoder property at all!. maybe im not understanding the code as i am not one of the contributers so please dont take what i wrote as grunted please.

nadavS3 commented 3 years ago

its me again, i dont know if i had the same problem as yours but for me it was that im using react functional components and i declared the variable like this: const recorder = new MicRecorder({ bitRate: 128 }). i wrote that line of code in the body of that functional component and that means that every render of that component, the variable recorder got resseted to a new MicRecorder and lost it previus values, for me the solution was to put the recorder variable inside a state and thus it wont get re created every render and will hold it previus values. check if you did a similar mistake to mine and somehow lost the actual reference to the actual variable. hope i helped :)

PavithraSutantraa commented 3 years ago

@nadavS3 Thanks for the solution.. Worked for me after changing const Mp3Recorder = new MicRecorder({ bitRate: 128 }); to const [Mp3Recorder, setMp3Recorder] = useState( new MicRecorder({ bitRate: 128 }) );

gordonmaloney commented 3 years ago

Thanks @nadavS3 - had the same issue and your solution worked perfectly. If anyone else would find it useful, here's a full but extremely minimal working template for this as a functional component:

import React, { useState, useEffect } from "react";
import MicRecorder from "mic-recorder-to-mp3";

export const Recorder = () => {
  const [state, setState] = useState({
    isRecording: false,
    blobURL: "",
    isBlocked: false,
  });

  const [Mp3Recorder, setMp3Recorder] = useState(new MicRecorder({ bitRate: 128 }))

  useEffect(() => {
  navigator.getUserMedia(
    { audio: true },
    () => {
      console.log("Permission Granted");
      setState({ isBlocked: false });
    },
    () => {
      console.log("Permission Denied");
      setState({ isBlocked: true });
    }
  );
}, [])

  const start = () => {
    if (state.isBlocked) {
      console.log('Permission Denied');
    } else {
      Mp3Recorder
        .start()
        .then(() => {
          setState({ isRecording: true });
        }).catch((e) => console.error(e));
    }
  };

  const stop = () => {
    Mp3Recorder
      .stop()
      .getMp3()
      .then(([buffer, blob]) => {
        const blobURL = URL.createObjectURL(blob)
        setState({ blobURL, isRecording: false });
      }).catch((e) => console.log(e));
  };

  return (
    <div>
      <button onClick={start} disabled={state.isRecording}>
        Record
      </button>
      <button onClick={stop} disabled={!state.isRecording}>
        Stop
      </button>
      <audio src={state.blobURL} controls="controls" />
    </div>
  );
};
hafiz-asadpbg commented 1 year ago

how to pause and resume the recording