From 3868a381d032304d894b9bd47886a11299e80cea Mon Sep 17 00:00:00 2001 From: Ajinkya Pande Date: Tue, 13 Aug 2024 17:35:52 +0530 Subject: [PATCH] IssueId #224272 feat: Audio library RecordRTC update --- package.json | 1 + src/utils/AudioCompare.js | 175 +++++++++++++++++++++++++++----------- 2 files changed, 126 insertions(+), 50 deletions(-) diff --git a/package.json b/package.json index 7948ced6..403073cc 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "react-virtualized": "^9.22.3", "react-virtualized-auto-sizer": "^1.0.6", "react-window": "^1.8.6", + "recordrtc": "^5.6.2", "redux": "^4.1.2", "redux-saga": "^1.1.3", "sass": "^1.44.0", diff --git a/src/utils/AudioCompare.js b/src/utils/AudioCompare.js index 90f38655..ed95e3f3 100644 --- a/src/utils/AudioCompare.js +++ b/src/utils/AudioCompare.js @@ -1,22 +1,20 @@ import React, { useState } from "react"; -import AudioAnalyser from "react-audio-analyser"; +import RecordRTC from "recordrtc"; import { Box } from "@mui/material"; import { ListenButton, RetryIcon, SpeakButton, StopButton } from "./constants"; import RecordVoiceVisualizer from "./RecordVoiceVisualizer"; -import useAudioDetection from "./useAudioDetection"; const AudioRecorderCompair = (props) => { - const { startDetection, stopDetection, isSilent, isRunning, audioDetected } = useAudioDetection(); const [status, setStatus] = useState(""); const [audioSrc, setAudioSrc] = useState(""); const [recordingInitialized, setRecordingInitialized] = useState(false); - const audioType = "audio/wav"; + const [recorder, setRecorder] = useState(null); const controlAudio = async (status) => { if (status === "recording") { - await startDetection(); + startRecording(); } else { - stopDetection(); + stopRecording(); } setStatus(status); }; @@ -30,48 +28,97 @@ const AudioRecorderCompair = (props) => { if (props.setEnableNext) { props.setEnableNext(false); } - document.getElementById("startaudio_compair").click(); resetRecording(); + controlAudio("recording"); }; const handleStop = () => { if (props.setEnableNext) { props.setEnableNext(true); } - document.getElementById("stopaudio_compair").click(); + controlAudio("inactive"); }; - const audioProps = { - audioType, - status, - audioSrc, - timeslice: 1000, - startCallback: (e) => { - setAudioSrc(""); - setRecordingInitialized(true); - props.setRecordedAudio(""); - }, - pauseCallback: (e) => {}, - stopCallback: (e) => { - const temp_audioSrc = window.URL.createObjectURL(e); - setAudioSrc(temp_audioSrc); - if (!audioDetected) { + const startRecording = () => { + navigator.mediaDevices + .getUserMedia({ + audio: {}, + }) + .then((stream) => { + const audioContext = new (window.AudioContext || + window.webkitAudioContext)(); + + const recorder = RecordRTC(stream, { + type: "audio", + mimeType: "audio/wav", + recorderType: RecordRTC.StereoAudioRecorder, + desiredSampRate: 16000, // Lower sample rate for voice recording + numberOfAudioChannels: 1, // Force mono recording + audioContext: audioContext, + }); + + recorder.startRecording(); + setRecorder(recorder); + setRecordingInitialized(true); + props.setRecordedAudio(""); + }) + .catch((error) => { + console.error("Error accessing microphone:", error); props?.setOpenMessageDialog({ - message: "Please Speak Louder and Clear", + message: + "Microphone access denied or not working. Please check your settings.", isError: true, }); - if (props.setEnableNext) { - props.setEnableNext(false); + }); + }; + + const stopRecording = () => { + if (recorder) { + recorder.stopRecording(() => { + const blob = recorder.getBlob(); + const temp_audioSrc = window.URL.createObjectURL(blob); + setAudioSrc(temp_audioSrc); + + // Validate the blob + if (blob.size < 1000) { + console.error("Recording too short or no audio detected"); + // props?.setOpenMessageDialog({ + // message: "Please Speak Louder and Clear", + // isError: true, + // }); + if (props.setEnableNext) { + props.setEnableNext(false); + } + return; } - } else { + props.setRecordedAudio(temp_audioSrc); + setRecordingInitialized(false); + }); + } + }; + + React.useEffect(() => { + if (props.isNextButtonCalled) { + destroyRecording(); + } + }, [props.isNextButtonCalled]); + + const destroyRecording = () => { + if (recorder) { + recorder.destroy(); + if (audioSrc) { + URL.revokeObjectURL(audioSrc); + setAudioSrc(""); } + setRecorder(null); setRecordingInitialized(false); - }, - onRecordCallback: (e) => {}, - errorCallback: (err) => {}, - backgroundColor: "hsla(0, 100%, 0%, 0)", - strokeColor: "#73DD24", + setStatus(""); + props.setRecordedAudio(""); + if (props.setEnableNext) { + props.setEnableNext(false); + } + } }; return ( @@ -80,8 +127,19 @@ const AudioRecorderCompair = (props) => { {(() => { if (status === "recording" && recordingInitialized) { return ( -
- +
+ @@ -91,17 +149,33 @@ const AudioRecorderCompair = (props) => { ); } else { return ( -
+
{(!props.dontShowListen || props.recordedAudio) && ( <> {!props.pauseAudio ? ( -
{ props.playAudio(true); }} aria-label="Play audio"> +
{ + props.playAudio(true); + }} + >
) : ( - { props.playAudio(false); }}> + { + props.playAudio(false); + }} + > )} @@ -110,8 +184,20 @@ const AudioRecorderCompair = (props) => {
{!props.showOnlyListen && ( - - {!props.recordedAudio ? : } + + {!props.recordedAudio ? ( + + ) : ( + + )} )}
@@ -119,17 +205,6 @@ const AudioRecorderCompair = (props) => { ); } })()} - -
-
- - -
-
);