@pankajparashar/react-voice-visualizer
Version:
React library for audio recording and visualization using Web Audio API
814 lines (813 loc) • 35 kB
JavaScript
(function(){"use strict";(r=>{var o;try{if(typeof window>"u")return;var i=document.createElement("style");i.appendChild(document.createTextNode(r));const e=(o=document.querySelector('meta[property="csp-nonce"]'))==null?void 0:o.getAttribute("nonce");e&&i.setAttribute("nonce",e),document.head.appendChild(i)}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})(".voice-visualizer__buttons-container{display:flex;justify-content:center;align-items:center;column-gap:20px;row-gap:15px;flex-wrap:wrap;margin-bottom:40px}.voice-visualizer__btn-center{box-sizing:border-box;flex-shrink:0;width:60px;height:60px;padding:0;display:flex;justify-content:center;align-items:center;border-radius:50%;background-color:#fff;border:4px solid #c5c5c5;outline:none;cursor:pointer;transition:border-color .3s,background-color .3s}.voice-visualizer__btn-center:disabled{opacity:.85;cursor:default}.voice-visualizer__btn-center:hover{background-color:#eaeaea;border:4px solid #9f9f9f}.voice-visualizer__btn-center>img{width:auto;height:50%;max-height:30px}.voice-visualizer__btn-center.voice-visualizer__btn-center-pause{background-color:#ff3030}.voice-visualizer__btn-center.voice-visualizer__btn-center-pause:hover{background-color:#ff4f4f}.voice-visualizer__btn-center.voice-visualizer__btn-center-pause>img{height:50%;max-height:16px}.voice-visualizer__btn-center.voice-visualizer__btn-center--border-transparent{border-color:transparent}.voice-visualizer__btn-center.voice-visualizer__btn-center--border-transparent:hover{background-color:#fff}.voice-visualizer__btn-left{box-sizing:border-box;flex-shrink:0;width:60px;height:60px;padding:0;display:flex;justify-content:center;align-items:center;border-radius:50%;background-color:#ff3030;border:4px solid #c5c5c5;outline:none;cursor:pointer;transition:border-color .3s,background-color .3s,opacity .3s}.voice-visualizer__btn-container{min-width:100px;display:flex;justify-content:flex-end}.voice-visualizer__btn-left:hover{background-color:#ff4f4f}.voice-visualizer__btn-left:disabled{opacity:.6;background-color:#ff3030;cursor:default}.voice-visualizer__btn-left.voice-visualizer__btn-left-microphone{background-color:#fff}.voice-visualizer__btn-left.voice-visualizer__btn-left-microphone>img{width:auto;height:50%;max-height:30px}.voice-visualizer__btn-left>img{width:auto;height:50%;max-height:16px}.voice-visualizer__btn-left:hover{border:4px solid #9f9f9f}.voice-visualizer__btn{box-sizing:border-box;min-width:100px;min-height:60px;padding:5px 20px;border-radius:40px;font-size:15px;background-color:#f0f0f0;transition:background-color .3s,opacity .3s}.voice-visualizer__btn:disabled{opacity:.8;background-color:#f0f0f0;cursor:default}.voice-visualizer__btn:hover{background-color:#bebebe}.voice-visualizer__canvas-container{position:relative;width:fit-content;margin:0 auto;overflow:hidden}.voice-visualizer__canvas-container canvas{display:block}.voice-visualizer__canvas-microphone-btn{position:absolute;top:50%;left:50%;width:auto;max-width:12%;min-width:24px;height:50%;max-height:100px;background-color:transparent;border:none;outline:none;transform:translate(-50%,-50%)}.voice-visualizer__canvas-microphone-icon{width:100%;height:100%;will-change:transform;transition:transform .3s}.voice-visualizer__canvas-microphone-btn:hover .voice-visualizer__canvas-microphone-icon{transform:scale(1.03)}.voice-visualizer__canvas-audio-wave-icon{position:absolute;top:50%;left:50%;width:auto;max-width:40%;height:40%;max-height:100px;transform:translate(-118%,-50%) scale(-1)}.voice-visualizer__canvas-audio-wave-icon2{transform:translate(18%,-50%)}.voice-visualizer__canvas-audio-processing{position:absolute;top:50%;left:50%;margin:0;transform:translate(-50%,-50%)}.voice-visualizer__progress-indicator-hovered{position:absolute;top:0;pointer-events:none;height:100%;width:1px;background-color:#85858599}.voice-visualizer__progress-indicator-hovered-time{position:absolute;top:3%;left:1px;width:fit-content;margin:0;padding:0 7px;opacity:.8;font-size:12px;border-radius:0 4px 4px 0;background-color:#575757;text-align:left}.voice-visualizer__progress-indicator-hovered-time.voice-visualizer__progress-indicator-hovered-time-left{left:unset;right:1px;border-radius:4px 0 0 4px}.voice-visualizer__progress-indicator{position:absolute;top:0;pointer-events:none;height:100%;width:1px;background-color:#efefef}.voice-visualizer__progress-indicator-time{position:absolute;top:3%;left:1px;width:fit-content;box-sizing:border-box;min-width:37px;margin:0;padding:0 7px;font-size:12px;border-radius:0 4px 4px 0;text-align:left;color:#000;font-weight:500;background-color:#efefef}.voice-visualizer__progress-indicator-time.voice-visualizer__progress-indicator-time-left{left:unset;right:1px;border-radius:4px 0 0 4px}.voice-visualizer__audio-info-container{box-sizing:border-box;height:55px;display:flex;align-items:center;justify-content:center;gap:30px}.voice-visualizer__audio-info-time{margin:15px 0;min-width:38px;text-align:left}.voice-visualizer__visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:4px solid #c5c5c5;white-space:nowrap;clip-path:inset(100%);clip:rect(0 0 0 0);overflow:hidden}.voice-visualizer__relative{position:relative}.voice-visualizer__spinner-wrapper{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:52px;height:52px;display:flex;justify-content:center;align-items:center}.voice-visualizer__spinner{flex-shrink:0;width:100%;height:100%;border:4px solid rgba(197,197,197,.5);border-radius:50%;border-top-color:#b7b7b7;animation:voice-visualizer__spin 1s ease-in-out infinite;-webkit-animation:voice-visualizer__spin 1s ease-in-out infinite}@keyframes voice-visualizer__spin{to{transform:rotate(360deg)}}@-webkit-keyframes voice-visualizer__spin{to{transform:rotate(360deg)}}")})();
import { jsx as a, jsxs as ne, Fragment as We } from "react/jsx-runtime";
import { useRef as $, useCallback as rt, useState as l, useEffect as j, useLayoutEffect as nt } from "react";
const ke = ({
canvas: e,
backgroundColor: t
}) => {
const r = e.height, n = e.width, s = Math.round(n / 2), h = e.getContext("2d");
return h ? (h.clearRect(0, 0, n, r), t !== "transparent" && (h.fillStyle = t, h.fillRect(0, 0, n, r)), { context: h, height: r, width: n, halfWidth: s }) : null;
}, Ce = ({
context: e,
color: t,
rounded: r,
x: n,
y: s,
w: h,
h: _
}) => {
e.fillStyle = t, e.beginPath(), e.roundRect ? (e.roundRect(n, s, h, _, r), e.fill()) : e.fillRect(n, s, h, _);
}, ct = ({
barsData: e,
canvas: t,
barWidth: r,
gap: n,
backgroundColor: s,
mainBarColor: h,
secondaryBarColor: _,
currentAudioTime: m = 0,
rounded: z,
duration: f
}) => {
const S = ke({ canvas: t, backgroundColor: s });
if (!S) return;
const { context: p, height: d } = S, x = m / f;
e.forEach((v, M) => {
const g = M / e.length, o = x > g;
Ce({
context: p,
color: o ? _ : h,
rounded: z,
x: M * (r + n * r),
y: d / 2 - v.max,
h: v.max * 2,
w: r
});
});
};
function it({
context: e,
color: t,
rounded: r,
width: n,
height: s,
barWidth: h
}) {
Ce({
context: e,
color: t,
rounded: r,
x: n / 2 + h / 2,
y: s / 2 - 1,
h: 2,
w: n - (n / 2 + h / 2)
});
}
const st = ({
audioData: e,
unit: t,
index: r,
index2: n,
canvas: s,
isRecordingInProgress: h,
isPausedRecording: _,
picks: m,
backgroundColor: z,
barWidth: f,
mainBarColor: S,
secondaryBarColor: p,
rounded: d,
animateCurrentPick: x,
fullscreen: v
}) => {
const M = ke({ canvas: s, backgroundColor: z });
if (!M) return;
const { context: g, height: o, width: T, halfWidth: W } = M;
if (e != null && e.length && h) {
const A = Math.max(...e);
if (!_) {
if (n.current >= f) {
n.current = 0;
const b = (o - A / 258 * o) / o * 100, C = (-o + A / 258 * o * 2) / o * 100, X = r.current === f ? {
startY: b,
barHeight: C
} : null;
r.current >= t ? r.current = f : r.current += f, m.length > (v ? T : W) / f && m.pop(), m.unshift(X);
}
n.current += 1;
}
!v && q(), x && Ce({
context: g,
rounded: d,
color: S,
x: v ? T : W,
y: o - A / 258 * o,
h: -o + A / 258 * o * 2,
w: f
});
let P = (v ? T : W) - n.current;
m.forEach((b) => {
b && Ce({
context: g,
color: S,
rounded: d,
x: P,
y: b.startY * o / 100 > o / 2 - 1 ? o / 2 - 1 : b.startY * o / 100,
h: b.barHeight * o / 100 > 2 ? b.barHeight * o / 100 : 2,
w: f
}), P -= f;
});
} else
m.length = 0;
function q() {
it({
context: g,
color: p,
rounded: d,
width: T,
height: o,
barWidth: f
});
}
}, Ze = (e) => {
const t = Math.floor(e / 3600), r = Math.floor(e % 3600 / 60), n = e % 60, s = Math.floor(
(n - Math.floor(n)) * 1e3
);
return t > 0 ? `${String(t).padStart(2, "0")}:${String(r).padStart(
2,
"0"
)}:${String(Math.floor(n)).padStart(2, "0")}:${String(
s
).charAt(0)}` : r > 0 ? `${String(r).padStart(2, "0")}:${String(
Math.floor(n)
).padStart(2, "0")}:${String(s).charAt(0)}` : `${String(Math.floor(n)).padStart(2, "0")}:${String(
s
).charAt(0)}`;
}, ot = (e) => {
const t = Math.floor(e / 1e3), r = Math.floor(t / 3600), n = Math.floor(t % 3600 / 60), s = t % 60;
return r > 0 ? `${String(r).padStart(2, "0")}:${String(n).padStart(
2,
"0"
)}:${String(s).padStart(2, "0")}` : `${String(n).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
};
function qe(e) {
if (typeof e == "string") {
const t = Number(e);
if (!Number.isNaN(t))
return `${Math.trunc(t / 2) * 2}px`;
}
return e;
}
const at = ({
bufferData: e,
height: t,
width: r,
barWidth: n,
gap: s
}) => {
const h = r / (n + s * n), _ = Math.floor(e.length / h), m = t / 2;
let z = [], f = 0;
for (let S = 0; S < h; S++) {
const p = [];
let d = 0;
for (let v = 0; v < _ && S * _ + v < e.length; v++) {
const M = e[S * _ + v];
M > 0 && (p.push(M), d++);
}
const x = p.reduce((v, M) => v + M, 0) / d;
x > f && (f = x), z.push({ max: x });
}
if (m * 0.95 > f * m) {
const S = m * 0.95 / f;
z = z.map((p) => ({
max: p.max > 0.01 ? p.max * S : 1
}));
}
return z;
}, ht = (e) => {
if (!e) return "";
const t = e.match(/audio\/([^;]+)/);
return t && t.length >= 2 ? `.${t[1]}` : "";
}, ut = (e) => {
const t = Math.floor(e / 3600), r = Math.floor(e % 3600 / 60), n = e % 60, s = Math.floor(
(n - Math.floor(n)) * 1e3
);
return t > 0 ? `${String(t).padStart(2, "0")}:${String(r).padStart(
2,
"0"
)}:${String(Math.floor(n)).padStart(2, "0")}}h` : r > 0 ? `${String(r).padStart(2, "0")}:${String(
Math.floor(n)
).padStart(2, "0")}m` : `${String(Math.floor(n)).padStart(2, "0")}:${String(
s
).charAt(0)}${String(s).charAt(1)}s`;
}, lt = (e, t = 250) => {
const r = $();
return rt(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(...n) => {
const s = () => {
clearTimeout(r.current), e(...n);
};
clearTimeout(r.current), r.current = setTimeout(s, t);
},
[e, t]
);
}, mt = (e) => {
onmessage = (t) => {
postMessage(e(t.data));
};
};
function vt({
fn: e,
initialValue: t,
onMessageReceived: r
}) {
const [n, s] = l(t);
return {
result: n,
setResult: s,
run: (_) => {
const m = new Worker(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
URL.createObjectURL(new Blob([`(${mt})(${e})`]))
);
m.onmessage = (z) => {
z.data && (s(z.data), r && r(), m.terminate());
}, m.onerror = (z) => {
console.error(z.message), m.terminate();
}, m.postMessage(_);
}
};
}
const Pe = ({
color: e = "#FFFFFF",
reflect: t
}) => /* @__PURE__ */ a(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0.92 17.54 48.27 14.92",
className: `voice-visualizer__canvas-audio-wave-icon ${t ? "voice-visualizer__canvas-audio-wave-icon2" : ""}`,
children: /* @__PURE__ */ a(
"path",
{
d: "M.92 24.63h.21v.75H.92zm.42-1.39h.21v3.52h-.21zm.43.68h.21v2.17h-.21zM2.2 22h.21v6.01H2.2zm.43-1.27h.21v8.55h-.21zm.43 2.07h.21v4.4h-.21zm.43 1.22h.21v1.97h-.21zm.43.47h.21v1.03h-.21zm.43-1.66h.21v4.35h-.21zm.43-1.74h.21v7.82h-.21zm.43 1.94h.21v3.94h-.21zm.43 1.07h.21v1.81h-.21zm.42-.94h.21v3.68h-.21zm.43.91h.21v1.86h-.21zm.43-.23h.21v2.33h-.21zm.43.46h.21v1.4h-.21zm.43-.7h.21v2.8h-.21zm.43-1.6h.21v6.01h-.21zm.43-2.23h.21v10.46h-.21zm.43-1.4h.21v13.26h-.21zm.43.62h.21v12.02H9.5zm.43 1.64h.21v8.75h-.21zm.43 1.37h.21v6.01h-.21zm.43-1.87H11v9.74h-.21zm.42 1.32h.21v7.1h-.21zm.43-2.64h.21v12.38h-.21zm.43 1.61h.21v9.17h-.21zM12.5 22h.21v6.01h-.21zm.43 1.32h.21v3.37h-.21zm.43-2.51h.21v8.39h-.21zm.43.59H14v7.2h-.21zm.43 1.79h.21v3.62h-.21zm.43.41h.21v2.8h-.21zm.43.57h.21v1.66h-.21zm.43-1.11h.21v3.88h-.21zm.42-2.98h.21v9.84h-.21zm.43 1.06h.21v7.72h-.21zm.43 3.19H17v1.35h-.21zm.86-2.33h.21v6.01h-.21zm-.43 1.4h.21v3.21h-.21zm1.29.15h.21v2.9h-.21zm.43.68h.21v1.55h-.21zm-.86-.76h.21v3.05h-.21zm1.29-.05h.21v3.16h-.21zm.43-.64h.21v4.45h-.21zm.43.38h.21v3.68h-.21zm.42-.49h.21v4.66h-.21zm.43 1.32h.21v2.02h-.21zm.43.37h.21v1.29h-.21zm.43.31h.21v.67h-.21zm.43-.39h.21v1.45h-.21zm.43-1.35h.21v4.14h-.21zm.86.73h.21v2.69h-.21zm-.43.44h.21v1.81h-.21zm1.29-3.45h.21v8.7h-.21zm.43 1.71h.21v5.28h-.21zm-.86-2.3h.21v9.89h-.21zm1.29 3.36h.21v3.16h-.21zM25.8 22h.21v6.01h-.21zm.43 1.42h.21v3.16h-.21zm.43.88h.21v1.4h-.21zm.43-.93h.21v3.26h-.21zm.43-1.37h.21v6.01h-.21zm.43-.93h.21v7.87h-.21zm.43-.76h.21v9.38h-.21zm.43 1.69h.21v6.01h-.21zm.86 1.92h.21v2.17h-.21zm-.43-.6h.21v3.37h-.21zm1.28.05h.21v3.26h-.21zm.43.67h.21v1.91h-.21zm-.85-.51h.21v2.95h-.21zm1.28-.13h.21v3.21h-.21zm.43-1.4h.21v6.01h-.21zm.43-.99h.21v7.98h-.21zm.43 1.77h.21v4.45h-.21zm.43-1.22h.21v6.89h-.21zm.43 1.6h.21v3.68h-.21zm.43-.28h.21v4.25h-.21zm.43-.6h.21v5.44h-.21zm.43-.28h.21v6.01h-.21zm.85 2.02h.21v1.97h-.21zm-.43-.57h.21v3.11h-.21zm1.29.93h.21v1.24h-.21zm.43-.65h.21v2.54h-.21zm-.86-.28h.21v3.11h-.21zm1.29.83h.21v1.45h-.21zm.43-.99h.21v3.42h-.21zm.43-.1h.21v3.62h-.21zm.43-.7h.21v5.02h-.21zm.43.8h.21v3.42h-.21zm.43-1.29h.21v6.01h-.21zm.42-1.71h.21v9.43h-.21zm.43 2.38h.21v4.66h-.21zm.43.65h.21v3.37h-.21zm.86.08h.21v3.21h-.21zm-.43.54h.21v2.12h-.21zm1.29-.05h.21v2.23h-.21zm.43.28h.21v1.66h-.21zm-.86.16h.21v1.35h-.21zm1.29.21h.21v.93h-.21zm.43-6.04h.21v13h-.21zm.43.8h.21v11.4h-.21zm.43-1.76h.21v14.92h-.21zm.42 1.09h.21v12.74h-.21zm.43 1.17h.21v10.41h-.21zm.43 1.32h.21v7.77h-.21zm.43 1.6h.21v4.56h-.21zm.43 1.17h.21v2.23h-.21zm.86-.08h.21v2.38h-.21zm-.43-.34h.21v3.05h-.21zm1.29-.1h.21v3.26h-.21zm.43.93h.21v1.4h-.21zm-.86-.02h.21v1.45h-.21z",
fill: e
}
)
}
), Xe = "data:image/svg+xml,%3csvg%20width='23'%20height='33'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M1.1%2016.72c0%203%20.96%205.8%203.61%207.95a9.96%209.96%200%200%200%206.5%202.17m0%200v4.34h4.34-8.67m4.34-4.34c2.35%200%204.42-.48%206.5-2.17a9.87%209.87%200%200%200%203.61-7.95M11.22%201.82c-1.45%200-2.5.37-3.3.93a5.6%205.6%200%200%200-1.84%202.4c-.9%202.06-1.1%204.77-1.1%207.24%200%202.46.2%205.17%201.1%207.24a5.6%205.6%200%200%200%201.84%202.4c.8.55%201.85.92%203.3.92%201.44%200%202.5-.37%203.29-.93a5.6%205.6%200%200%200%201.84-2.4c.9-2.06%201.1-4.77%201.1-7.23%200-2.47-.2-5.18-1.1-7.24a5.6%205.6%200%200%200-1.84-2.4%205.52%205.52%200%200%200-3.3-.93Z'%20stroke='%23000'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e", ft = ({
color: e = "#000000",
stroke: t = 2,
className: r
}) => /* @__PURE__ */ a(
"svg",
{
viewBox: "0 0 23 33",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
className: r,
children: /* @__PURE__ */ a(
"path",
{
d: "M1.1 16.72c0 3 .96 5.8 3.61 7.95a9.96 9.96 0 0 0 6.5 2.17m0 0v4.34h4.34-8.67m4.34-4.34c2.35 0 4.42-.48 6.5-2.17a9.87 9.87 0 0 0 3.61-7.95M11.22 1.82c-1.45 0-2.5.37-3.3.93a5.6 5.6 0 0 0-1.84 2.4c-.9 2.06-1.1 4.77-1.1 7.24 0 2.46.2 5.17 1.1 7.24a5.6 5.6 0 0 0 1.84 2.4c.8.55 1.85.92 3.3.92 1.44 0 2.5-.37 3.29-.93a5.6 5.6 0 0 0 1.84-2.4c.9-2.06 1.1-4.77 1.1-7.23 0-2.47-.2-5.18-1.1-7.24a5.6 5.6 0 0 0-1.84-2.4 5.52 5.52 0 0 0-3.3-.93Z",
stroke: e,
strokeWidth: t,
strokeLinecap: "round",
strokeLinejoin: "round"
}
)
}
), Ye = "data:image/svg+xml,%3csvg%20width='21'%20height='29'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M14%203.5a3.5%203.5%200%201%201%207%200v22a3.5%203.5%200%201%201-7%200v-22Z'%20fill='%23fff'/%3e%3crect%20width='7'%20height='29'%20rx='3.5'%20fill='%23fff'/%3e%3c/svg%3e", dt = "data:image/svg+xml,%3csvg%20width='26'%20height='24'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18.75%206.16c4.31%202.6%206.46%203.9%206.46%205.84%200%201.95-2.15%203.24-6.46%205.84l-4.84%202.92c-4.31%202.6-6.46%203.89-8.08%202.92-1.62-.98-1.62-3.57-1.62-8.76V9.08c0-5.19%200-7.78%201.62-8.76%201.62-.97%203.77.33%208.08%202.92l4.84%202.92Z'%20fill='%23fff'/%3e%3c/svg%3e", zt = "data:image/svg+xml,%3csvg%20width='27'%20height='25'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3crect%20x='.21'%20width='26'%20height='25'%20rx='5'%20fill='%23fff'/%3e%3c/svg%3e", wt = ({
controls: {
audioRef: e,
audioData: t,
isRecordingInProgress: r,
recordedBlob: n,
duration: s,
currentAudioTime: h,
audioSrc: _,
bufferFromRecordedBlob: m,
togglePauseResume: z,
startRecording: f,
stopRecording: S,
saveAudioFile: p,
isAvailableRecordedAudio: d,
isPausedRecordedAudio: x,
isPausedRecording: v,
isProcessingStartRecording: M,
isProcessingRecordedAudio: g,
isCleared: o,
formattedDuration: T,
formattedRecordingTime: W,
formattedRecordedAudioCurrentTime: q,
clearCanvas: A,
setCurrentAudioTime: P,
isProcessingOnResize: b,
_setIsProcessingOnResize: C,
_setIsProcessingAudioOnComplete: X
},
width: Y = "100%",
height: Me = 200,
speed: $e = 3,
backgroundColor: H = "transparent",
mainBarColor: I = "#FFFFFF",
secondaryBarColor: ce = "#5e5e5e",
barWidth: V = 2,
gap: Z = 1,
rounded: U = 5,
isControlPanelShown: ie = !0,
isDownloadAudioButtonShown: le = !1,
animateCurrentPick: xe = !0,
fullscreen: me = !1,
onlyRecording: se = !1,
isDefaultUIShown: ve = !0,
defaultMicrophoneIconColor: fe = I,
defaultAudioWaveIconColor: G = I,
mainContainerClassName: ye,
canvasContainerClassName: oe,
isProgressIndicatorShown: ae = !se,
progressIndicatorClassName: w,
isProgressIndicatorTimeShown: O = !0,
progressIndicatorTimeClassName: J,
isProgressIndicatorOnHoverShown: he = !se,
progressIndicatorOnHoverClassName: K,
isProgressIndicatorTimeOnHoverShown: F = !0,
progressIndicatorTimeOnHoverClassName: R,
isAudioProcessingTextShown: u = !0,
audioProcessingTextClassName: be,
controlButtonsClassName: Ee,
audioProcessingElem: Te
}) => {
const [de, He] = l(0), [y, Fe] = l(0), [ze, Ie] = l(0), [Q, pe] = l(0), [ee, Le] = l(!1), [Re, te] = l(window.innerWidth), [Ne, ge] = l(!1), we = Re < 768, ue = Math.trunc($e), D = Math.trunc(Z), k = Math.trunc(
we && D > 0 ? V + 1 : V
), c = k + D * k, i = $(null), B = $([]), L = $(ue), Ae = $(k), Ge = $(k), re = $(null), {
result: _e,
setResult: Je,
run: Ke
} = vt({
fn: at,
initialValue: [],
onMessageReceived: et
}), Qe = lt(Be);
j(() => {
if (!re.current) return;
const E = () => {
te(window.innerWidth), d ? (C(!0), ge(!0), Qe()) : Be();
}, N = new ResizeObserver(E);
return N.observe(re.current), () => {
N.disconnect();
};
}, [Y, d]), nt(() => {
i.current && ((L.current >= ue || !t.length) && (L.current = t.length ? 0 : ue, st({
audioData: t,
unit: c,
index: Ae,
index2: Ge,
canvas: i.current,
picks: B.current,
isRecordingInProgress: r,
isPausedRecording: v,
backgroundColor: H,
mainBarColor: I,
secondaryBarColor: ce,
barWidth: k,
rounded: U,
animateCurrentPick: xe,
fullscreen: me
})), L.current += 1);
}, [
i.current,
t,
k,
H,
I,
ce,
U,
me,
ve,
Q
]), j(() => {
var E, N;
if (d)
return ee ? (E = i.current) == null || E.addEventListener("mouseleave", Oe) : (N = i.current) == null || N.addEventListener("mouseenter", Ue), () => {
var Se, De;
ee ? (Se = i.current) == null || Se.removeEventListener("mouseleave", Oe) : (De = i.current) == null || De.removeEventListener("mouseenter", Ue);
};
}, [ee, d]), j(() => {
var N;
if (!m || !i.current || r || Ne)
return;
if (se) {
A();
return;
}
B.current = [];
const E = m.getChannelData(0);
return Ke({
bufferData: E,
height: ze,
width: Q,
barWidth: k,
gap: D
}), (N = i.current) == null || N.addEventListener("mousemove", je), () => {
var Se;
(Se = i.current) == null || Se.removeEventListener(
"mousemove",
je
);
};
}, [
m,
y,
ze,
Z,
V,
Ne
]), j(() => {
if (!(se || !(_e != null && _e.length) || !i.current || g)) {
if (o) {
Je([]);
return;
}
ct({
barsData: _e,
canvas: i.current,
barWidth: k,
gap: D,
backgroundColor: H,
mainBarColor: I,
secondaryBarColor: ce,
currentAudioTime: h,
rounded: U,
duration: s
});
}
}, [
_e,
h,
o,
U,
H,
I,
ce
]), j(() => {
g && i.current && ke({
canvas: i.current,
backgroundColor: H
});
}, [g]);
function Be() {
if (!re.current || !i.current) return;
L.current = ue;
const E = Math.trunc(
re.current.clientHeight * window.devicePixelRatio / 2
) * 2;
Fe(re.current.clientWidth), Ie(E), pe(
Math.round(
re.current.clientWidth * window.devicePixelRatio
)
), ge(!1);
}
function et() {
C(!1), X(!1), e != null && e.current && !b && (e.current.src = _);
}
const Ue = () => {
Le(!0);
}, Oe = () => {
Le(!1);
}, je = (E) => {
He(E.offsetX);
}, tt = (E) => {
if (e != null && e.current && i.current) {
const N = s / y * (E.clientX - i.current.getBoundingClientRect().left);
e.current.currentTime = N, P(N);
}
}, Ve = h / s * y;
return /* @__PURE__ */ ne("div", { className: `voice-visualizer ${ye ?? ""}`, children: [
/* @__PURE__ */ ne(
"div",
{
className: `voice-visualizer__canvas-container ${oe ?? ""}`,
ref: re,
style: { width: qe(Y) },
children: [
/* @__PURE__ */ a(
"canvas",
{
ref: i,
width: Q,
height: ze,
onClick: tt,
style: {
height: qe(Me),
width: y
},
children: "Your browser does not support HTML5 Canvas."
}
),
ve && o && /* @__PURE__ */ ne(We, { children: [
/* @__PURE__ */ a(Pe, { color: G }),
/* @__PURE__ */ a(Pe, { color: G, reflect: !0 }),
/* @__PURE__ */ a(
"button",
{
type: "button",
onClick: f,
className: "voice-visualizer__canvas-microphone-btn",
children: /* @__PURE__ */ a(
ft,
{
color: fe,
stroke: 0.5,
className: "voice-visualizer__canvas-microphone-icon"
}
)
}
)
] }),
u && g && /* @__PURE__ */ a(
"p",
{
className: `voice-visualizer__canvas-audio-processing ${be ?? ""}`,
style: { color: I },
children: Te !== void 0 ? Te : "Processing Audio..."
}
),
ee && d && !g && !we && he && /* @__PURE__ */ a(
"div",
{
className: `voice-visualizer__progress-indicator-hovered ${K ?? ""}`,
style: {
left: de
},
children: F && /* @__PURE__ */ a(
"p",
{
className: `voice-visualizer__progress-indicator-hovered-time
${y - de < 70 ? "voice-visualizer__progress-indicator-hovered-time-left" : ""}
${R ?? ""}`,
children: Ze(
s / y * de
)
}
)
}
),
ae && d && !g && s ? /* @__PURE__ */ a(
"div",
{
className: `voice-visualizer__progress-indicator ${w ?? ""}`,
style: {
left: Ve < y - 1 ? Ve : y - 1
},
children: O && /* @__PURE__ */ a(
"p",
{
className: `voice-visualizer__progress-indicator-time ${y - h * y / s < 70 ? "voice-visualizer__progress-indicator-time-left" : ""} ${J ?? ""}`,
children: q
}
)
}
) : null
]
}
),
ie && /* @__PURE__ */ ne(We, { children: [
/* @__PURE__ */ ne("div", { className: "voice-visualizer__audio-info-container", children: [
r && /* @__PURE__ */ a("p", { className: "voice-visualizer__audio-info-time", children: W }),
s && !g ? /* @__PURE__ */ a("p", { children: T }) : null
] }),
/* @__PURE__ */ ne("div", { className: "voice-visualizer__buttons-container", children: [
r && /* @__PURE__ */ a("div", { className: "voice-visualizer__btn-container", children: /* @__PURE__ */ a(
"button",
{
type: "button",
className: `voice-visualizer__btn-left ${v ? "voice-visualizer__btn-left-microphone" : ""}`,
onClick: z,
children: /* @__PURE__ */ a(
"img",
{
src: v ? Xe : Ye,
alt: v ? "Play" : "Pause"
}
)
}
) }),
!o && /* @__PURE__ */ a(
"button",
{
type: "button",
className: `voice-visualizer__btn-left ${r || M ? "voice-visualizer__visually-hidden" : ""}`,
onClick: z,
disabled: g,
children: /* @__PURE__ */ a(
"img",
{
src: x ? dt : Ye,
alt: x ? "Play" : "Pause"
}
)
}
),
o && /* @__PURE__ */ ne(
"button",
{
type: "button",
className: `voice-visualizer__btn-center voice-visualizer__relative ${M ? "voice-visualizer__btn-center--border-transparent" : ""}`,
onClick: f,
disabled: M,
children: [
M && /* @__PURE__ */ a("div", { className: "voice-visualizer__spinner-wrapper", children: /* @__PURE__ */ a("div", { className: "voice-visualizer__spinner" }) }),
/* @__PURE__ */ a("img", { src: Xe, alt: "Microphone" })
]
}
),
/* @__PURE__ */ a(
"button",
{
type: "button",
className: `voice-visualizer__btn-center voice-visualizer__btn-center-pause ${r ? "" : "voice-visualizer__visually-hidden"}`,
onClick: S,
children: /* @__PURE__ */ a("img", { src: zt, alt: "Stop" })
}
),
!o && /* @__PURE__ */ a(
"button",
{
type: "button",
onClick: A,
className: `voice-visualizer__btn ${Ee ?? ""}`,
disabled: g,
children: "Clear"
}
),
le && n && /* @__PURE__ */ a(
"button",
{
type: "button",
onClick: p,
className: `voice-visualizer__btn ${Ee ?? ""}`,
disabled: g,
children: "Download Audio"
}
)
] })
] })
] });
};
function _t({
onStartRecording: e,
onStopRecording: t,
onPausedRecording: r,
onResumedRecording: n,
onClearCanvas: s,
onEndAudioPlayback: h,
onStartAudioPlayback: _,
onPausedAudioPlayback: m,
onResumedAudioPlayback: z,
onErrorPlayingAudio: f,
shouldHandleBeforeUnload: S = !0
} = {}) {
const [p, d] = l(!1), [x, v] = l(!1), [M, g] = l(new Uint8Array(0)), [o, T] = l(!1), [W, q] = l(null), [A, P] = l(null), [b, C] = l(0), [X, Y] = l(0), [Me, $e] = l(0), [H, I] = l(""), [ce, V] = l(!0), [Z, U] = l(0), [ie, le] = l(!0), [xe, me] = l(!1), [se, ve] = l(!1), [fe, G] = l(null), [ye, oe] = l(!1), ae = $(null), w = $(null), O = $(null), J = $(null), he = $(null), K = $(null), F = $(null), R = $(null), u = $(null), be = !!(A && !o), Ee = ut(Me), Te = ot(b), de = Ze(Z), He = xe || o;
j(() => {
if (!p || x) return;
const i = setInterval(() => {
const B = performance.now();
C((L) => L + (B - X)), Y(B);
}, 1e3);
return () => clearInterval(i);
}, [X, x, p]), j(() => {
if (fe) {
te();
return;
}
}, [fe]), j(() => () => {
te();
}, []), j(() => (!ie && S && window.addEventListener("beforeunload", y), () => {
window.removeEventListener("beforeunload", y);
}), [ie, S]);
const y = (c) => {
c.preventDefault(), c.returnValue = "";
}, Fe = async (c) => {
if (c)
try {
if (c.size === 0)
throw new Error("Error: The audio blob is empty");
const i = URL.createObjectURL(c);
I(i);
const B = await c.arrayBuffer(), Ae = await new AudioContext().decodeAudioData(B);
P(Ae), $e(Ae.duration - 0.06), G(null);
} catch (i) {
console.error("Error processing the audio blob:", i), G(
i instanceof Error ? i : new Error("Error processing the audio blob")
);
}
}, ze = (c) => {
c instanceof Blob && (te(), ve(!0), le(!1), T(!0), d(!1), C(0), v(!1), u.current = new Audio(), q(c), Fe(c));
}, Ie = () => {
oe(!0), navigator.mediaDevices.getUserMedia({ audio: !0 }).then((c) => {
le(!1), oe(!1), d(!0), Y(performance.now()), ae.current = c, O.current = new window.AudioContext(), J.current = O.current.createAnalyser(), he.current = new Uint8Array(
J.current.frequencyBinCount
), K.current = O.current.createMediaStreamSource(c), K.current.connect(J.current), w.current = new MediaRecorder(c), w.current.addEventListener(
"dataavailable",
pe
), w.current.start(), e && e(), Q();
}).catch((c) => {
oe(!1), G(
c instanceof Error ? c : new Error("Error starting audio recording")
);
});
}, Q = () => {
J.current.getByteTimeDomainData(he.current), g(new Uint8Array(he.current)), F.current = requestAnimationFrame(Q);
}, pe = (c) => {
w.current && (w.current = null, u.current = new Audio(), q(c.data), Fe(c.data));
}, ee = () => {
u.current && (U(u.current.currentTime), R.current = requestAnimationFrame(ee));
}, Le = () => {
p || ye || (ie || te(), Ie());
}, Re = () => {
var c;
d(!1), w.current && (w.current.stop(), w.current.removeEventListener(
"dataavailable",
pe
)), (c = ae.current) == null || c.getTracks().forEach((i) => i.stop()), F.current && cancelAnimationFrame(F.current), K.current && K.current.disconnect(), O.current && O.current.state !== "closed" && O.current.close(), T(!0), C(0), v(!1), t && t();
}, te = () => {
var c;
F.current && (cancelAnimationFrame(F.current), F.current = null), R.current && (cancelAnimationFrame(R.current), R.current = null), w.current && (w.current.removeEventListener(
"dataavailable",
pe
), w.current.stop(), w.current = null), (c = ae.current) == null || c.getTracks().forEach((i) => i.stop()), ae.current = null, u != null && u.current && (u.current.removeEventListener("ended", D), u.current.pause(), u.current.src = "", u.current = null), O.current = null, J.current = null, he.current = null, K.current = null, oe(!1), d(!1), ve(!1), T(!1), q(null), P(null), C(0), Y(0), $e(0), I(""), U(0), V(!0), v(!1), me(!1), g(new Uint8Array(0)), G(null), le(!0), s && s();
}, Ne = () => {
if (u.current && u.current.paused) {
const c = u.current.play();
c !== void 0 && c.catch((i) => {
console.error(i), f && f(
i instanceof Error ? i : new Error("Error playing audio")
);
});
}
}, ge = () => {
!u.current || p || (requestAnimationFrame(ee), Ne(), u.current.addEventListener("ended", D), V(!1), _ && Z === 0 && _(), z && Z !== 0 && z());
}, we = () => {
if (!u.current || p) return;
R.current && cancelAnimationFrame(R.current), u.current.removeEventListener("ended", D), u.current.pause(), V(!0);
const c = u.current.currentTime;
U(c), u.current.currentTime = c, m && m();
}, ue = () => {
var c, i, B;
if (p) {
v((L) => !L), ((c = w.current) == null ? void 0 : c.state) === "recording" ? ((i = w.current) == null || i.pause(), C((L) => L + (performance.now() - X)), F.current && cancelAnimationFrame(F.current), r && r()) : (F.current = requestAnimationFrame(Q), (B = w.current) == null || B.resume(), Y(performance.now()), n && n());
return;
}
u.current && be && (u.current.paused ? ge() : we());
}, D = () => {
R.current && cancelAnimationFrame(R.current), V(!0), h && h();
}, k = () => {
var i;
if (!H) return;
const c = document.createElement("a");
c.href = H, c.download = `recorded_audio${ht(
(i = w.current) == null ? void 0 : i.mimeType
)}`, document.body.appendChild(c), c.click(), document.body.removeChild(c), URL.revokeObjectURL(H);
};
return {
audioRef: u,
isRecordingInProgress: p,
isPausedRecording: x,
audioData: M,
recordingTime: b,
isProcessingRecordedAudio: He,
recordedBlob: W,
mediaRecorder: w.current,
duration: Me,
currentAudioTime: Z,
audioSrc: H,
isPausedRecordedAudio: ce,
bufferFromRecordedBlob: A,
isCleared: ie,
isAvailableRecordedAudio: be,
formattedDuration: Ee,
formattedRecordingTime: Te,
formattedRecordedAudioCurrentTime: de,
startRecording: Le,
togglePauseResume: ue,
startAudioPlayback: ge,
stopAudioPlayback: we,
stopRecording: Re,
saveAudioFile: k,
clearCanvas: te,
setCurrentAudioTime: U,
error: fe,
isProcessingOnResize: xe,
isProcessingStartRecording: ye,
isPreloadedBlob: se,
setPreloadedAudioBlob: ze,
_setIsProcessingAudioOnComplete: T,
_setIsProcessingOnResize: me
};
}
export {
wt as VoiceVisualizer,
_t as useVoiceVisualizer
};