UNPKG

react-music-waveform

Version:
874 lines (873 loc) 25.2 kB
import de, { forwardRef as le, createElement as ee, useEffect as Q, useState as F, useRef as re } from "react"; var Z = { exports: {} }, U = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var te; function fe() { if (te) return U; te = 1; var t = Symbol.for("react.transitional.element"), r = Symbol.for("react.fragment"); function o(n, l, s) { var a = null; if (s !== void 0 && (a = "" + s), l.key !== void 0 && (a = "" + l.key), "key" in l) { s = {}; for (var c in l) c !== "key" && (s[c] = l[c]); } else s = l; return l = s.ref, { $$typeof: t, type: n, key: a, ref: l !== void 0 ? l : null, props: s }; } return U.Fragment = r, U.jsx = o, U.jsxs = o, U; } var q = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var oe; function pe() { return oe || (oe = 1, process.env.NODE_ENV !== "production" && function() { function t(e) { if (e == null) return null; if (typeof e == "function") return e.$$typeof === L ? null : e.displayName || e.name || null; if (typeof e == "string") return e; switch (e) { case E: return "Fragment"; case D: return "Profiler"; case b: return "StrictMode"; case W: return "Suspense"; case M: return "SuspenseList"; case I: return "Activity"; } if (typeof e == "object") switch (typeof e.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), e.$$typeof) { case k: return "Portal"; case P: return (e.displayName || "Context") + ".Provider"; case j: return (e._context.displayName || "Context") + ".Consumer"; case N: var i = e.render; return e = e.displayName, e || (e = i.displayName || i.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e; case O: return i = e.displayName || null, i !== null ? i : t(e.type) || "Memo"; case C: i = e._payload, e = e._init; try { return t(e(i)); } catch { } } return null; } function r(e) { return "" + e; } function o(e) { try { r(e); var i = !1; } catch { i = !0; } if (i) { i = console; var f = i.error, g = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object"; return f.call( i, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", g ), r(e); } } function n(e) { if (e === E) return "<>"; if (typeof e == "object" && e !== null && e.$$typeof === C) return "<...>"; try { var i = t(e); return i ? "<" + i + ">" : "<...>"; } catch { return "<...>"; } } function l() { var e = A.A; return e === null ? null : e.getOwner(); } function s() { return Error("react-stack-top-frame"); } function a(e) { if (Y.call(e, "key")) { var i = Object.getOwnPropertyDescriptor(e, "key").get; if (i && i.isReactWarning) return !1; } return e.key !== void 0; } function c(e, i) { function f() { H || (H = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", i )); } f.isReactWarning = !0, Object.defineProperty(e, "key", { get: f, configurable: !0 }); } function u() { var e = t(this.type); return J[e] || (J[e] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), e = this.props.ref, e !== void 0 ? e : null; } function d(e, i, f, g, S, w, x, T) { return f = w.ref, e = { $$typeof: h, type: e, key: i, props: w, _owner: S }, (f !== void 0 ? f : null) !== null ? Object.defineProperty(e, "ref", { enumerable: !1, get: u }) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(e, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(e, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: x }), Object.defineProperty(e, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: T }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e; } function p(e, i, f, g, S, w, x, T) { var m = i.children; if (m !== void 0) if (g) if (K(m)) { for (g = 0; g < m.length; g++) v(m[g]); Object.freeze && Object.freeze(m); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else v(m); if (Y.call(i, "key")) { m = t(e); var $ = Object.keys(i).filter(function(G) { return G !== "key"; }); g = 0 < $.length ? "{key: someKey, " + $.join(": ..., ") + ": ...}" : "{key: someKey}", V[m + g] || ($ = 0 < $.length ? "{" + $.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, g, m, $, m ), V[m + g] = !0); } if (m = null, f !== void 0 && (o(f), m = "" + f), a(i) && (o(i.key), m = "" + i.key), "key" in i) { f = {}; for (var B in i) B !== "key" && (f[B] = i[B]); } else f = i; return m && c( f, typeof e == "function" ? e.displayName || e.name || "Unknown" : e ), d( e, m, w, S, l(), f, x, T ); } function v(e) { typeof e == "object" && e !== null && e.$$typeof === h && e._store && (e._store.validated = 1); } var R = de, h = Symbol.for("react.transitional.element"), k = Symbol.for("react.portal"), E = Symbol.for("react.fragment"), b = Symbol.for("react.strict_mode"), D = Symbol.for("react.profiler"), j = Symbol.for("react.consumer"), P = Symbol.for("react.context"), N = Symbol.for("react.forward_ref"), W = Symbol.for("react.suspense"), M = Symbol.for("react.suspense_list"), O = Symbol.for("react.memo"), C = Symbol.for("react.lazy"), I = Symbol.for("react.activity"), L = Symbol.for("react.client.reference"), A = R.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, Y = Object.prototype.hasOwnProperty, K = Array.isArray, z = console.createTask ? console.createTask : function() { return null; }; R = { "react-stack-bottom-frame": function(e) { return e(); } }; var H, J = {}, X = R["react-stack-bottom-frame"].bind( R, s )(), _ = z(n(s)), V = {}; q.Fragment = E, q.jsx = function(e, i, f, g, S) { var w = 1e4 > A.recentlyCreatedOwnerStacks++; return p( e, i, f, !1, g, S, w ? Error("react-stack-top-frame") : X, w ? z(n(e)) : _ ); }, q.jsxs = function(e, i, f, g, S) { var w = 1e4 > A.recentlyCreatedOwnerStacks++; return p( e, i, f, !0, g, S, w ? Error("react-stack-top-frame") : X, w ? z(n(e)) : _ ); }; }()), q; } var ae; function me() { return ae || (ae = 1, process.env.NODE_ENV === "production" ? Z.exports = fe() : Z.exports = pe()), Z.exports; } var y = me(); /** * @license lucide-react v0.518.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const he = (t) => t.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), xe = (t) => t.replace( /^([A-Z])|[\s-_]+(\w)/g, (r, o, n) => n ? n.toUpperCase() : o.toLowerCase() ), ne = (t) => { const r = xe(t); return r.charAt(0).toUpperCase() + r.slice(1); }, ce = (...t) => t.filter((r, o, n) => !!r && r.trim() !== "" && n.indexOf(r) === o).join(" ").trim(), be = (t) => { for (const r in t) if (r.startsWith("aria-") || r === "role" || r === "title") return !0; }; /** * @license lucide-react v0.518.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ var ge = { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }; /** * @license lucide-react v0.518.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const ve = le( ({ color: t = "currentColor", size: r = 24, strokeWidth: o = 2, absoluteStrokeWidth: n, className: l = "", children: s, iconNode: a, ...c }, u) => ee( "svg", { ref: u, ...ge, width: r, height: r, stroke: t, strokeWidth: n ? Number(o) * 24 / Number(r) : o, className: ce("lucide", l), ...!s && !be(c) && { "aria-hidden": "true" }, ...c }, [ ...a.map(([d, p]) => ee(d, p)), ...Array.isArray(s) ? s : [s] ] ) ); /** * @license lucide-react v0.518.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const ue = (t, r) => { const o = le( ({ className: n, ...l }, s) => ee(ve, { ref: s, iconNode: r, className: ce( `lucide-${he(ne(t))}`, `lucide-${t}`, n ), ...l }) ); return o.displayName = ne(t), o; }; /** * @license lucide-react v0.518.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const ye = [ ["rect", { x: "14", y: "4", width: "4", height: "16", rx: "1", key: "zuxfzm" }], ["rect", { x: "6", y: "4", width: "4", height: "16", rx: "1", key: "1okwgv" }] ], ke = ue("pause", ye); /** * @license lucide-react v0.518.0 - ISC * * This source code is licensed under the ISC license. * See the LICENSE file in the root directory of this source tree. */ const Ee = [["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]], Re = ue("play", Ee), se = (t) => { if (!t || isNaN(t)) return "0:00"; const r = Math.floor(t / 60), o = Math.floor(t % 60); return `${r}:${o < 10 ? "0" : ""}${o}`; }, we = async (t, r = 90) => { try { const n = await (await fetch(t)).arrayBuffer(), a = (await new (window.AudioContext || window.webkitAudioContext)().decodeAudioData(n)).getChannelData(0), c = [], u = Math.floor(a.length / r); for (let p = 0; p < r; p++) { const v = p * u; let R = 0, h = 0; for (let E = v; E < v + u && E < a.length; E++) R += Math.abs(a[E]), h++; const k = h > 0 ? R / h : 0; c.push(k); } const d = Math.max(...c); return c.map((p) => d > 0 ? p / d : 0); } catch (o) { return console.error("Error analyzing audio file:", o), Array(r).fill(0.1); } }, je = (t, r) => { let o; return (...n) => { clearTimeout(o), o = setTimeout(() => t(...n), r); }; }, Te = (t, r, o, n, l, s) => { Q(() => { const a = t.current; if (!a) return; const c = () => { l(a.duration); }, u = () => { n(a.currentTime), s(a.currentTime / a.duration); }, d = () => { o(!1), s(0), n(0); }, p = () => o(!1), v = () => o(!0); return a.addEventListener("loadedmetadata", c), a.addEventListener("timeupdate", u), a.addEventListener("ended", d), a.addEventListener("pause", p), a.addEventListener("play", v), a.readyState >= 1 && l(a.duration), () => { a.removeEventListener("loadedmetadata", c), a.removeEventListener("timeupdate", u), a.removeEventListener("ended", d), a.removeEventListener("pause", p), a.removeEventListener("play", v); }; }, [r, t, o, n, l, s]); }, Ce = (t, r, o) => { const [n, l] = F([]); return Q(() => { (async () => { if (t) try { const a = 2 + o, c = Math.floor(r / a), u = await we(t, Math.max(c, 10)); l(u); } catch (a) { console.error("Failed to load waveform data:", a); const c = 2 + o, u = Math.floor(r / c); l(Array(Math.max(u, 10)).fill(0.1)); } })(); }, [t, r, o]), n; }, Se = (t) => { const [r, o] = F(1), [n, l] = F(!1), s = re(null); return Q(() => { const u = (d) => { s.current && !s.current.contains(d.target) && l(!1); }; return document.addEventListener("mousedown", u), () => { document.removeEventListener("mousedown", u); }; }, []), { playbackRate: r, showSpeedDropdown: n, speedControlRef: s, changePlaybackRate: (u) => { const d = t.current; d && (d.playbackRate = u, o(u), l(!1)); }, toggleSpeedDropdown: () => { l(!n); } }; }, ie = { viridara: { primary: "#1DB954", progress: "#1ed760" }, solmara: { primary: "#ff5500", progress: "#ef6c05" }, aurevia: { primary: "#007AFF", progress: "#0056D6" }, minimal: { light: { primary: "#666666", progress: "#000000" }, dark: { primary: "#999999", progress: "#FFFFFF" } } }, _e = (t, r, o, n, l) => { let s; t === "minimal" ? s = ie.minimal[r] : s = ie[t]; const a = r === "light", c = a ? "#FFFFFF" : "#000000", u = a ? "#000000" : "#FFFFFF", d = { background: o || c, primary: n || s.primary, progress: l || s.progress, text: u }, p = d.progress, v = "#FFFFFF"; return { background: d.background, primary: d.primary, progress: d.progress, text: d.text, playButton: { backgroundColor: p, color: v, width: "32px", height: "32px", minWidth: "32px", minHeight: "32px", borderRadius: "50%", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", transition: "all 0.2s ease", flexShrink: 0 }, playButtonIcon: v, timestamp: { color: d.text, fontSize: "11px", fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', fontWeight: "600", letterSpacing: "0.3px", whiteSpace: "nowrap", flexShrink: 0 }, speedControl: { color: d.text, fontSize: "13px", fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', fontWeight: "700", padding: "4px 8px", cursor: "pointer", borderRadius: "4px", transition: "background-color 0.2s ease, color 0.2s ease", whiteSpace: "nowrap", display: "flex", alignItems: "center", height: "20px" }, speedDropdown: { position: "absolute", top: "calc(100% + 6px)", right: 0, backgroundColor: "rgba(50, 50, 50, 0.9)", borderRadius: "6px", padding: "4px 0", minWidth: "60px", zIndex: 10, boxShadow: "0 2px 8px rgba(0,0,0,0.3)", listStyle: "none", margin: 0 }, speedOption: { color: "#FFFFFF", fontSize: "12px", fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', fontWeight: "600", padding: "6px 10px", cursor: "pointer", borderRadius: "3px", transition: "background-color 0.15s ease", textAlign: "center" } }; }, Me = (t, r, o, n, l, s, a) => { if (t.length === 0) return null; const c = t.length; let u; switch (s) { case "aurevia": u = Math.max( (r - n * (c - 1)) / c * 2, 6 ); break; case "solmara": u = Math.max( (r - n * (c - 1)) / c * 1.2, 3 ); break; case "viridara": u = Math.max((r - n * (c - 1)) / c, 2); break; case "minimal": u = Math.max( (r - n * (c - 1)) / c * 1, 1 ); break; default: u = Math.max((r - n * (c - 1)) / c, 2); } const d = s === "aurevia" ? n * 1.5 : n, p = s === "aurevia" ? Math.min(u, 8) : u; return t.map((v, R) => { let h = v * o, k = 0; switch (s) { case "viridara": h = Math.max(h * 0.8, 2), k = (o - h) / 2; break; case "solmara": h = h * 0.9, k = o - h; break; case "aurevia": h = Math.max(h * 0.95, 4), k = (o - h) / 2; break; case "minimal": h = Math.max(h * 0.6, 1), k = (o - h) / 2; break; } const E = R * (p + d), D = (E + p / 2) / r, j = l >= D, P = E / r, N = (E + p) / r, W = l >= P && l < N; let M = a.primary, O = s === "minimal" ? 0.4 : 0.6; if (j) M = a.progress, O = 1; else if (W) { M = a.progress; const I = (l - P) / (N - P); O = 0.6 + 0.4 * Math.max(0, Math.min(1, I)); } let C = 0; switch (s) { case "viridara": C = p / 2; break; case "aurevia": C = 2; break; case "solmara": C = 1; break; case "minimal": C = 0; break; } return /* @__PURE__ */ y.jsx( "rect", { x: E, y: k, width: p, height: h, fill: M, rx: C, opacity: O, style: { transition: "all 0.15s ease", transformOrigin: "center", willChange: "fill, opacity" } }, R ); }); }, Ae = ({ playbackRate: t, showSpeedDropdown: r, speedControlRef: o, themeStyles: n, toggleSpeedDropdown: l, changePlaybackRate: s }) => { const a = [0.5, 0.75, 1, 1.25, 1.5, 2], c = { ...n.speedDropdown, opacity: r ? 1 : 0, visibility: r ? "visible" : "hidden", transform: r ? "translateY(0)" : "translateY(-10px)", transition: "opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease", pointerEvents: r ? "auto" : "none" }; return /* @__PURE__ */ y.jsxs( "div", { ref: o, style: { position: "relative", flexShrink: 0 }, onClick: l, children: [ /* @__PURE__ */ y.jsxs("span", { style: n.speedControl, children: [ t, "x" ] }), /* @__PURE__ */ y.jsx("ul", { style: c, children: a.map((u) => /* @__PURE__ */ y.jsxs( "li", { style: { ...n.speedOption, backgroundColor: t === u ? "rgba(255,255,255,0.2)" : "transparent" }, onClick: (d) => { d.stopPropagation(), s(u); }, onMouseEnter: (d) => { d.currentTarget.style.backgroundColor = "rgba(255,255,255,0.15)"; }, onMouseLeave: (d) => { d.currentTarget.style.backgroundColor = t === u ? "rgba(255,255,255,0.2)" : "transparent"; }, children: [ u, "x" ] }, u )) }) ] } ); }, Pe = ({ src: t, style: r = "viridara", theme: o = "dark", height: n = 80, width: l = 600, barSpacing: s = 2, primaryColor: a, progressColor: c, backgroundColor: u, showControls: d = !0, showTimestamp: p = !0, showSpeedControl: v = !0, showBackground: R = !0, className: h = "" }) => { const k = re(null), E = re(null), [b, D] = F(1), [j, P] = F(!1), [N, W] = F(0), [M, O] = F(0), [C, I] = F(0); Q(() => { const x = () => { const T = window.innerWidth; let m = 1; T <= 320 ? m = 0.5 : T <= 480 ? m = 0.65 : T <= 768 ? m = 0.8 : T <= 1024 && (m = 0.9), D(m); }; return x(), window.addEventListener("resize", x), () => window.removeEventListener("resize", x); }, []); const L = Math.floor(l * b), A = Math.floor(n * b), Y = Math.max(1, Math.floor(s * b)), K = Se( k ), { playbackRate: z, speedControlRef: H, ...J } = K, X = Ce(t, L, Y); Te( k, t, P, W, O, I ); const _ = _e( r, o, u, a, c ), V = async () => { const x = k.current; if (x) try { j ? x.pause() : await x.play(); } catch (T) { console.error("Error playing audio:", T); } }, e = (x) => { const T = k.current; if (!T || !M) return; const m = x.currentTarget.getBoundingClientRect(), B = (x.clientX - m.left) / L, G = B * M; T.currentTime = G, W(G), I(B); }, i = { backgroundColor: R ? _.background : "transparent", padding: `${Math.floor(8 * b)}px ${Math.floor(12 * b)}px`, borderRadius: `${Math.floor(12 * b)}px`, display: "flex", alignItems: "center", gap: `${Math.floor(6 * b)}px`, width: "fit-content", maxWidth: "100%", boxSizing: "border-box", minHeight: A + Math.floor(16 * b), maxHeight: A + Math.floor(16 * b), boxShadow: R ? "0 2px 8px rgba(0,0,0,0.15)" : "none", fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', position: "relative", marginBottom: v ? `${Math.floor(120 * b)}px` : "0" }, f = { width: `${L}px`, height: `${A}px`, display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", flexShrink: 0, position: "relative" }, g = { ..._.playButton, width: `${Math.floor(32 * b)}px`, height: `${Math.floor(32 * b)}px` }, S = { ..._.timestamp, width: `${Math.floor(45 * b)}px`, textAlign: "center", flexShrink: 0, minWidth: `${Math.floor(45 * b)}px`, fontSize: `${Math.floor(12 * b)}px` }, w = Math.floor(16 * b); return /* @__PURE__ */ y.jsxs("div", { className: h, style: i, children: [ /* @__PURE__ */ y.jsx("audio", { ref: k, src: t, preload: "metadata" }), d && /* @__PURE__ */ y.jsx( "button", { onClick: V, style: g, onMouseEnter: (x) => { x.currentTarget.style.transform = "scale(1.1)"; }, onMouseLeave: (x) => { x.currentTarget.style.transform = "scale(1)"; }, "aria-label": j ? "Pause" : "Play", children: j ? /* @__PURE__ */ y.jsx(ke, { size: w, fill: _.playButtonIcon }) : /* @__PURE__ */ y.jsx( Re, { size: w, fill: _.playButtonIcon, style: { marginLeft: "1px" } } ) } ), p && /* @__PURE__ */ y.jsx("div", { style: S, children: se(N) }), /* @__PURE__ */ y.jsx("div", { style: f, children: /* @__PURE__ */ y.jsx( "svg", { ref: E, width: L, height: A, style: { cursor: "pointer", display: "block" }, onClick: e, onMouseEnter: (x) => { x.currentTarget.style.opacity = "0.9"; }, onMouseLeave: (x) => { x.currentTarget.style.opacity = "1"; }, role: "slider", "aria-label": "Audio progress", "aria-valuenow": Math.round(C * 100), "aria-valuemin": 0, "aria-valuemax": 100, children: Me( X, L, A, Y, C, r, _ ) } ) }), p && /* @__PURE__ */ y.jsx("div", { style: S, children: se(M) }), d && v && /* @__PURE__ */ y.jsx("div", { style: { position: "relative", zIndex: 1e3 }, children: /* @__PURE__ */ y.jsx( Ae, { playbackRate: z, speedControlRef: H, themeStyles: _, ...J } ) }) ] }); }; export { Pe as AudioWaveform, je as debounce, se as formatTime }; //# sourceMappingURL=index.es.js.map