use-audio-record
Version:
<!-- automd:badges color=yellow -->
110 lines (107 loc) • 3.28 kB
JavaScript
import { useRef, useState, useEffect } from 'react';
import { g as getMimeType, S as SAMPLING_RATE, w as webmFixDuration } from './shared/use-audio-record.97f55604.mjs';
function useAudioRecorder(options = {}) {
const { mimeType = getMimeType(), sampleRate = SAMPLING_RATE } = options;
const streamRef = useRef(null);
const mediaRecorderRef = useRef(null);
const chunksRef = useRef([]);
const [recording, setRecording] = useState(false);
const [duration, setDuration] = useState(0);
const [recordedBlob, setRecordedBlob] = useState(null);
const initRecorder = async () => {
if (!streamRef.current) {
streamRef.current = await navigator.mediaDevices.getUserMedia({
audio: true
});
}
};
const [recordedAudioBuffer, setRecordedAudioBuffer] = useState(null);
const startRecording = async (completeCallback) => {
setRecordedBlob(null);
const startTime = Date.now();
try {
if (!streamRef.current) {
await initRecorder();
}
const mediaRecorder = new MediaRecorder(streamRef.current, {
mimeType
});
mediaRecorderRef.current = mediaRecorder;
mediaRecorder.addEventListener("dataavailable", async (event) => {
if (event.data.size > 0) {
chunksRef.current.push(event.data);
}
if (mediaRecorder.state === "inactive") {
const duration2 = Date.now() - startTime;
let blob = new Blob(chunksRef.current, {
type: mediaRecorder.mimeType
});
if (getMimeType() === "audio/webm") {
blob = await webmFixDuration(blob, duration2, blob.type);
}
setRecordedBlob(blob);
if (!recordedBlob?.size) {
return;
}
const fileReader = new FileReader();
fileReader.onloadend = async () => {
const audioCTX = new AudioContext({
sampleRate
});
setRecordedAudioBuffer(
await audioCTX.decodeAudioData(fileReader.result)
);
completeCallback?.();
};
fileReader.readAsArrayBuffer(recordedBlob);
chunksRef.current = [];
}
});
mediaRecorder.start();
setRecording(true);
} catch (error) {
console.error("Error accessing microphone:", error);
}
};
const stopRecording = () => {
if (mediaRecorderRef.current && mediaRecorderRef.current.state === "recording") {
mediaRecorderRef.current.stop();
setDuration(0);
setRecording(false);
}
};
useEffect(() => {
if (recording) {
const timer = setInterval(() => {
setDuration((prevDuration) => prevDuration + 1);
}, 1e3);
return () => {
clearInterval(timer);
};
}
return () => {
};
}, [recording]);
const handleToggleRecording = (completeCallback) => {
if (recording) {
stopRecording();
} else {
startRecording(completeCallback);
}
};
return {
streamRef,
mediaRecorderRef,
recording,
duration,
recordedBlob,
recordedAudioBuffer,
chunksRef,
initRecorder,
startRecording,
stopRecording,
handleToggleRecording
};
}
export { useAudioRecorder };
//# sourceMappingURL=react.mjs.map