use-audio-capture
Version:
🎙️ A lightweight React hook for audio recording using native Web APIs (MediaRecorder, getUserMedia). Start, stop, pause, resume audio recordings with customizable callbacks. Perfect for voice notes, interviews, podcasts, and real-time audio processing in
109 lines (108 loc) • 3.3 kB
JavaScript
import { useRef as w, useCallback as d } from "react";
function m(e, i) {
if (!e)
throw new Error(i);
}
function g(e) {
return e instanceof Error;
}
const v = (e) => {
const i = w([]), u = w(null), c = w(null), S = d(async () => {
if (typeof window > "u")
return;
m(navigator.mediaDevices, "MediaDevices not supported");
const a = await navigator.mediaDevices.getUserMedia({
audio: !0,
video: !1
});
u.current = a;
const t = new MediaRecorder(a);
t.onstart = async (n) => {
var r;
(r = e == null ? void 0 : e.onStart) == null || r.call(e, n, {
mediaStream: a
});
}, t.onstop = (n) => {
var r;
(r = e == null ? void 0 : e.onStop) == null || r.call(e, n, i.current, {
mediaStream: a
});
}, t.onpause = (n) => {
var r;
(r = e == null ? void 0 : e.onPause) == null || r.call(e, n, i.current, {
mediaStream: a
});
}, t.onerror = (n) => {
var r;
(r = e == null ? void 0 : e.onError) == null || r.call(e, n, {
mediaStream: a,
error: new Error("An error occurred while recording")
});
}, t.onresume = (n) => {
var r;
(r = e == null ? void 0 : e.onResume) == null || r.call(e, n, i.current, {
mediaStream: a
});
}, t.ondataavailable = async (n) => {
var r;
i.current.push(n.data), (r = e == null ? void 0 : e.onChunk) == null || r.call(e, n, {
mediaStream: a
});
}, c.current = t;
}, [e]), h = d(async () => {
var a, t;
try {
if (((a = c.current) == null ? void 0 : a.state) === "recording")
return;
i.current = [], await S(), m(c.current, "MediaRecorder not created"), c.current.start(500);
} catch (n) {
const r = g(n) ? n.message : "Something went wrong during recording";
(t = e == null ? void 0 : e.onError) == null || t.call(e, new Event(r), {
error: n,
mediaStream: u.current
});
}
}, [e, S]), E = d(async () => {
var a, t;
try {
m(c.current, "MediaRecorder not created"), c.current.stop(), (a = u.current) == null || a.getAudioTracks().forEach((n) => n.stop());
} catch (n) {
const r = g(n) ? n.message : "Something went wrong during stopping recording";
(t = e == null ? void 0 : e.onError) == null || t.call(e, new Event(r), {
error: n,
mediaStream: u.current
});
}
}, [e]), f = d(async () => {
var a;
try {
m(c.current, "MediaRecorder not created"), c.current.pause();
} catch (t) {
const n = g(t) ? t.message : "Something went wrong during pausing recording";
(a = e == null ? void 0 : e.onError) == null || a.call(e, new Event(n), {
error: t,
mediaStream: u.current
});
}
}, [e]), y = d(async () => {
var a;
try {
m(c.current, "MediaRecorder not created"), c.current.resume();
} catch (t) {
const n = g(t) ? t.message : "Something went wrong during resuming recording";
(a = e == null ? void 0 : e.onError) == null || a.call(e, new Event(n), {
error: t,
mediaStream: u.current
});
}
}, [e]);
return {
start: h,
stop: E,
pause: f,
resume: y
};
};
export {
v as useAudioCapture
};