UNPKG

use-audio-record

Version:
110 lines (107 loc) 3.28 kB
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