MediaRecorder RecordedChunks Empty Issue in React Component - Unable to get Recorded Audio

14 Views Asked by At

Problem: I'm encountering an issue with a React component responsible for recording and sending voice notes. Inside the handleSend function, I'm attempting to reply with the recorded audio file. However, I've noticed that the recordedChunks state, intended to store the recorded audio data, is empty within this function, leading to the failure of reply([file]).

Code Overview:

  • The React component utilizes the MediaRecorder API to record audio.
  • recordedChunks state is utilized to accumulate recorded audio data chunks.
  • Upon calling handleSend, which should dispatch the recorded audio, it checks if recordedChunks has data, but it's found empty at this point.

Expectations: I expect handleSend to send the recorded audio file via the reply function. However, due to recordedChunks being empty, the file isn't sent, leading to unexpected behavior.

Request for Assistance: I'm seeking guidance on how to ensure that recordedChunks contains the recorded audio data within the handleSend function. Any insights into why recordedChunks might be empty at this stage and how to rectify it would be greatly appreciated.

Code Snippet:

function Voicenote({ reply }) {
  const mediaRecorderRef = useRef(null);
  const [isRecording, setIsRecording] = useState(false);
  const [recordedChunks, setRecordedChunks] = useState([]);
  const [selectedFiles, setSelectedFiles] = useState([]);
  const [isPaused, setIsPaused] = useState(false);

  const handleOnClick = async () => {
    if (!isRecording) {
      setIsRecording(true);
      setRecordedChunks([]);

      const mediaRecorder = new MediaRecorder(
        await navigator.mediaDevices.getUserMedia({
          audio: true,
        })
      );

      mediaRecorder.ondataavailable = (e) => {
        if (e.data.size > 0) {
          setRecordedChunks((prev) => [...prev, e.data]);
        }
      };

      mediaRecorder.start();
      mediaRecorderRef.current = mediaRecorder;
    } else {
      setIsRecording(false);
      if (isPaused) {
        setIsPaused(false);
      }

      if (mediaRecorderRef.current) {
        mediaRecorderRef.current.stop();
      }
    }
  };

  const handlePauseResume = () => {
    if (!isPaused) {
      mediaRecorderRef.current.pause();
    } else {
      mediaRecorderRef.current.resume();
    }
    setIsPaused((prev) => !prev);
  };

  const handleDelete = () => {
    setIsRecording(false);
    setIsPaused(false);
    setRecordedChunks([]);

    mediaRecorderRef.current = null;

    if (mediaRecorderRef.current && mediaRecorderRef.current.state === "recording") {
      mediaRecorderRef.current.stop();
    }
  };

  const handleSend = () => {
    if (recordedChunks.length) {
    setIsRecording(false);

    const audioBlob = new Blob(recordedChunks, { type: "audio/wav" });
    const file = new File([audioBlob], `voicenote_${new Date().toISOString()}.wav`, {
      type: "audio/wav",
    });
    reply([file]);
  }
  };

  return (
    <Stack direction="row" alignItems="center" spacing={2}>
      {isRecording ? (
        <>
          <IconButton onClick={handlePauseResume}>
            {isPaused ? <PlayArrow /> : <Pause />}
          </IconButton>
          <IconButton onClick={handleDelete}>
            <Delete />
          </IconButton>
          <IconButton onClick={handleSend}>
            <Send />
          </IconButton>
        </>
      ) : (
        <IconButton onClick={handleOnClick}>
          <Mic />
        </IconButton>
      )}
    </Stack>
  );
}

Can anyone help me to solve this. Thank you.

0

There are 0 best solutions below