Skip to content

Commit

Permalink
Merge pull request #141 from ajinkyapandetekdi/all-1.2
Browse files Browse the repository at this point in the history
IssueId #224272 feat: Audio library RecordRTC update
  • Loading branch information
gouravmore authored Aug 13, 2024
2 parents 10f7fa2 + 3868a38 commit c15f9b6
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 50 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
175 changes: 125 additions & 50 deletions src/utils/AudioCompare.js
Original file line number Diff line number Diff line change
@@ -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);
};
Expand All @@ -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 (
Expand All @@ -80,8 +127,19 @@ const AudioRecorderCompair = (props) => {
{(() => {
if (status === "recording" && recordingInitialized) {
return (
<div style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", margin: "0 auto" }}>
<Box sx={{ cursor: "pointer", height: "38px" }} onClick={handleStop}>
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
margin: "0 auto",
}}
>
<Box
sx={{ cursor: "pointer", height: "38px" }}
onClick={handleStop}
>
<StopButton />
</Box>
<Box style={{ marginTop: "50px", marginBottom: "50px" }}>
Expand All @@ -91,17 +149,33 @@ const AudioRecorderCompair = (props) => {
);
} else {
return (
<div style={{ display: "flex", justifyContent: "space-between", margin: "0 auto" }} className="game-action-button">
<div
style={{
display: "flex",
justifyContent: "space-between",
margin: "0 auto",
}}
className="game-action-button"
>
{(!props.dontShowListen || props.recordedAudio) && (
<>
{!props.pauseAudio ? (
<div role="button" tabIndex="0" onClick={() => { props.playAudio(true); }} aria-label="Play audio">
<div
onClick={() => {
props.playAudio(true);
}}
>
<Box sx={{ cursor: "pointer" }}>
<ListenButton />
</Box>
</div>
) : (
<Box sx={{ cursor: "pointer" }} onClick={() => { props.playAudio(false); }}>
<Box
sx={{ cursor: "pointer" }}
onClick={() => {
props.playAudio(false);
}}
>
<StopButton />
</Box>
)}
Expand All @@ -110,26 +184,27 @@ const AudioRecorderCompair = (props) => {

<div>
{!props.showOnlyListen && (
<Box marginLeft={!props.dontShowListen || props.recordedAudio ? "32px" : "0px"} sx={{ cursor: "pointer" }} onClick={handleMic}>
{!props.recordedAudio ? <SpeakButton /> : <RetryIcon />}
<Box
marginLeft={
!props.dontShowListen || props.recordedAudio
? "32px"
: "0px"
}
sx={{ cursor: "pointer" }}
onClick={handleMic}
>
{!props.recordedAudio ? (
<SpeakButton />
) : (
<RetryIcon onClick={destroyRecording} />
)}
</Box>
)}
</div>
</div>
);
}
})()}
<AudioAnalyser {...audioProps} className="hide">
<div className="btn-box">
<br />
<button className="btn" id="startaudio_compair" onClick={() => controlAudio("recording")}>
Start
</button>
<button className="btn" id="stopaudio_compair" onClick={() => controlAudio("inactive")}>
Stop
</button>
</div>
</AudioAnalyser>
</div>
</div>
);
Expand Down

0 comments on commit c15f9b6

Please sign in to comment.