@lucaismyname/ginger 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +80 -2
  2. package/dist/{GingerSplitContexts-4YZ-OJ9V.js → GingerSplitContexts-BzBExb95.js} +22 -21
  3. package/dist/GingerSplitContexts-BzBExb95.js.map +1 -0
  4. package/dist/GingerSplitContexts-C7puo0M7.cjs +2 -0
  5. package/dist/GingerSplitContexts-C7puo0M7.cjs.map +1 -0
  6. package/dist/analyzer/liveAudioGraph.d.ts +14 -0
  7. package/dist/analyzer/liveAudioGraph.d.ts.map +1 -0
  8. package/dist/analyzer/useGingerLiveAnalyzer.d.ts +21 -0
  9. package/dist/analyzer/useGingerLiveAnalyzer.d.ts.map +1 -0
  10. package/dist/audio/GingerPlayer.d.ts.map +1 -1
  11. package/dist/audio/GingerPlayer.test.d.ts +2 -0
  12. package/dist/audio/GingerPlayer.test.d.ts.map +1 -0
  13. package/dist/client.cjs +1 -1
  14. package/dist/client.js +21 -18
  15. package/dist/context/GingerContext.d.ts +2 -1
  16. package/dist/context/GingerContext.d.ts.map +1 -1
  17. package/dist/context/GingerProvider.d.ts.map +1 -1
  18. package/dist/context/GingerSplitContexts.d.ts +2 -1
  19. package/dist/context/GingerSplitContexts.d.ts.map +1 -1
  20. package/dist/core/playbackReducer.d.ts.map +1 -1
  21. package/dist/core/queue.d.ts.map +1 -1
  22. package/dist/experimental-gapless/index.cjs +1 -1
  23. package/dist/experimental-gapless/index.js +1 -1
  24. package/dist/ginger-BTPRqWHs.js +1621 -0
  25. package/dist/ginger-BTPRqWHs.js.map +1 -0
  26. package/dist/ginger-BiI69vrn.cjs +2 -0
  27. package/dist/ginger-BiI69vrn.cjs.map +1 -0
  28. package/dist/hooks/hooks.test.d.ts +2 -0
  29. package/dist/hooks/hooks.test.d.ts.map +1 -0
  30. package/dist/hooks/useGinger.d.ts +1 -0
  31. package/dist/hooks/useGinger.d.ts.map +1 -1
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.d.ts +4 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +21 -18
  36. package/dist/internal/fft.d.ts +7 -0
  37. package/dist/internal/fft.d.ts.map +1 -0
  38. package/dist/internal/fft.test.d.ts +2 -0
  39. package/dist/internal/fft.test.d.ts.map +1 -0
  40. package/dist/media/useMediaSession.d.ts.map +1 -1
  41. package/dist/media/useMediaSession.test.d.ts +2 -0
  42. package/dist/media/useMediaSession.test.d.ts.map +1 -0
  43. package/dist/testing/helpers.d.ts +21 -0
  44. package/dist/testing/helpers.d.ts.map +1 -0
  45. package/dist/testing/index.cjs +19 -19
  46. package/dist/testing/index.cjs.map +1 -1
  47. package/dist/testing/index.d.ts +2 -7
  48. package/dist/testing/index.d.ts.map +1 -1
  49. package/dist/testing/index.js +33 -4
  50. package/dist/testing/index.js.map +1 -1
  51. package/dist/testing/renderGinger.d.ts +8 -0
  52. package/dist/testing/renderGinger.d.ts.map +1 -0
  53. package/dist/types.d.ts +5 -0
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/useSeekDrag-Br1V0Vao.js +290 -0
  56. package/dist/useSeekDrag-Br1V0Vao.js.map +1 -0
  57. package/dist/useSeekDrag-aS7uk26h.cjs +2 -0
  58. package/dist/useSeekDrag-aS7uk26h.cjs.map +1 -0
  59. package/dist/waveform/analyzeAudioFile.d.ts +31 -0
  60. package/dist/waveform/analyzeAudioFile.d.ts.map +1 -0
  61. package/dist/waveform/analyzeAudioFile.test.d.ts +2 -0
  62. package/dist/waveform/analyzeAudioFile.test.d.ts.map +1 -0
  63. package/dist/waveform/index.cjs +1 -1
  64. package/dist/waveform/index.cjs.map +1 -1
  65. package/dist/waveform/index.d.ts +4 -0
  66. package/dist/waveform/index.d.ts.map +1 -1
  67. package/dist/waveform/index.js +207 -23
  68. package/dist/waveform/index.js.map +1 -1
  69. package/dist/waveform/useAudioFileAnalysis.d.ts +8 -0
  70. package/dist/waveform/useAudioFileAnalysis.d.ts.map +1 -0
  71. package/package.json +4 -1
  72. package/dist/GingerSplitContexts-4YZ-OJ9V.js.map +0 -1
  73. package/dist/GingerSplitContexts-Bze1Bqe2.cjs +0 -2
  74. package/dist/GingerSplitContexts-Bze1Bqe2.cjs.map +0 -1
  75. package/dist/ginger-DYoHDn8T.cjs +0 -2
  76. package/dist/ginger-DYoHDn8T.cjs.map +0 -1
  77. package/dist/ginger-Dntdd6zH.js +0 -1599
  78. package/dist/ginger-Dntdd6zH.js.map +0 -1
  79. package/dist/useSeekDrag-DBzoym0-.cjs +0 -2
  80. package/dist/useSeekDrag-DBzoym0-.cjs.map +0 -1
  81. package/dist/useSeekDrag-jLsYA-uG.js +0 -174
  82. package/dist/useSeekDrag-jLsYA-uG.js.map +0 -1
@@ -0,0 +1,8 @@
1
+ import { ReactNode } from 'react';
2
+ import { Track } from '../types';
3
+ import { RenderGingerProviderOptions } from './helpers';
4
+ export type RenderGingerOptions = RenderGingerProviderOptions & {
5
+ tracks?: Track[];
6
+ };
7
+ export declare function renderGinger(ui: ReactNode, options?: RenderGingerOptions): import('@testing-library/react').RenderResult<typeof import("@testing-library/dom/types/queries"), HTMLElement, HTMLElement>;
8
+ //# sourceMappingURL=renderGinger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderGinger.d.ts","sourceRoot":"","sources":["../../src/testing/renderGinger.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,MAAM,mBAAmB,GAAG,2BAA2B,GAAG;IAC9D,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB,CAAC;AAEF,wBAAgB,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,GAAE,mBAAwB,gIAQ5E"}
package/dist/types.d.ts CHANGED
@@ -164,6 +164,11 @@ export type GingerAction = {
164
164
  } | {
165
165
  type: "SET_PLAYLIST_META";
166
166
  payload: PlaylistMeta | null;
167
+ } | {
168
+ type: "SET_PLAYBACK_MODE";
169
+ payload: PlaybackMode;
170
+ } | {
171
+ type: "MEDIA_SOURCE_CLEARED";
167
172
  } | {
168
173
  type: "MEDIA_ERROR";
169
174
  payload: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,290 @@
1
+ import { useMemo as M, useState as P, useRef as L, useCallback as Q, useLayoutEffect as Y, useEffect as I } from "react";
2
+ import { b as R, u as q, g as W, c as Z } from "./GingerSplitContexts-BzBExb95.js";
3
+ import { r as _, h as $, p as j, i as ee, j as te, b as ne, k as re } from "./ginger-BTPRqWHs.js";
4
+ function se() {
5
+ const n = R(), t = q();
6
+ return M(
7
+ () => {
8
+ const e = W(n, t);
9
+ return {
10
+ state: e,
11
+ currentTrack: re(e),
12
+ playbackUi: ne(e),
13
+ duration: te(e),
14
+ remaining: ee(e),
15
+ progress: j(e),
16
+ artworkUrl: $(e),
17
+ albumLine: _(e),
18
+ play: n.play,
19
+ pause: n.pause,
20
+ togglePlayPause: n.togglePlayPause,
21
+ seek: t.seek,
22
+ setVolume: t.setVolume,
23
+ setMuted: t.setMuted,
24
+ toggleMute: t.toggleMute,
25
+ setPlaybackRate: t.setPlaybackRate,
26
+ next: n.next,
27
+ prev: n.prev,
28
+ setRepeatMode: n.setRepeatMode,
29
+ cycleRepeat: n.cycleRepeat,
30
+ toggleShuffle: n.toggleShuffle,
31
+ setQueue: n.setQueue,
32
+ insertTrackAt: n.insertTrackAt,
33
+ removeTrackAt: n.removeTrackAt,
34
+ moveTrack: n.moveTrack,
35
+ enqueueNext: n.enqueueNext,
36
+ playTrackAt: n.playTrackAt,
37
+ selectTrackAt: n.selectTrackAt,
38
+ setPlaylistMeta: n.setPlaylistMeta,
39
+ setPlaybackMode: n.setPlaybackMode,
40
+ init: n.init,
41
+ audioRef: t.audioRef,
42
+ dispatch: n.dispatch
43
+ };
44
+ },
45
+ [n, t]
46
+ );
47
+ }
48
+ const B = /* @__PURE__ */ new WeakMap();
49
+ function ce(n) {
50
+ const t = 2 ** Math.round(Math.log2(n));
51
+ return Math.min(32768, Math.max(32, t));
52
+ }
53
+ function oe(n, t) {
54
+ let e = B.get(n);
55
+ if (!e) {
56
+ const i = window.AudioContext ?? window.webkitAudioContext;
57
+ if (!i)
58
+ throw new Error("Web Audio API is not available");
59
+ const l = new i(), y = l.createMediaElementSource(n);
60
+ e = { context: l, source: y, consumers: /* @__PURE__ */ new Map(), nextId: 0 }, B.set(n, e);
61
+ }
62
+ const { context: s, source: o } = e, c = s.createAnalyser();
63
+ c.fftSize = ce(t.fftSize), c.smoothingTimeConstant = t.smoothingTimeConstant, c.minDecibels = t.minDecibels, c.maxDecibels = t.maxDecibels, o.connect(c);
64
+ const r = e.consumers.size === 0;
65
+ r && c.connect(s.destination);
66
+ const a = e.nextId;
67
+ return e.nextId += 1, e.consumers.set(a, { analyser: c, isPlaybackSink: r }), { id: a, context: s, analyser: c };
68
+ }
69
+ function V(n, t) {
70
+ const e = B.get(n);
71
+ if (!e) return;
72
+ const s = e.consumers.get(t);
73
+ if (!s) return;
74
+ const { analyser: o, isPlaybackSink: c } = s;
75
+ if (o.disconnect(), e.consumers.delete(t), e.consumers.size === 0) {
76
+ try {
77
+ e.source.disconnect();
78
+ } catch {
79
+ }
80
+ e.context.close(), B.delete(n);
81
+ return;
82
+ }
83
+ if (c) {
84
+ const r = e.consumers.values().next().value;
85
+ r && (r.analyser.connect(e.context.destination), r.isPlaybackSink = !0);
86
+ }
87
+ }
88
+ const G = new Uint8Array(0), N = new Uint8Array(0);
89
+ function me(n = {}) {
90
+ const {
91
+ enabled: t = !0,
92
+ fftSize: e = 2048,
93
+ smoothingTimeConstant: s = 0.8,
94
+ minDecibels: o = -100,
95
+ maxDecibels: c = -30
96
+ } = n, { audioRef: r, state: a } = se(), i = M(
97
+ () => ({
98
+ fftSize: e,
99
+ smoothingTimeConstant: s,
100
+ minDecibels: o,
101
+ maxDecibels: c
102
+ }),
103
+ [e, s, o, c]
104
+ ), [l, y] = P(0), [m, u] = P(null), [x, g] = P(!1), [S, T] = P({ frequencyBinCount: 0, sampleRate: 0 }), d = L(G), k = L(N), J = Q(async () => {
105
+ const v = w.current;
106
+ v && v.state === "suspended" && await v.resume();
107
+ }, []), w = L(null), C = L(null);
108
+ return Y(() => {
109
+ if (!t || typeof window > "u")
110
+ return;
111
+ let v = !1, D = null, E = null, F = 0;
112
+ const U = () => {
113
+ const f = w.current;
114
+ f && g(f.state === "suspended");
115
+ }, z = () => {
116
+ if (v) return;
117
+ const f = C.current, h = d.current, p = k.current;
118
+ f && h.length > 0 && p.length > 0 && (f.getByteFrequencyData(h), f.getByteTimeDomainData(p), y((A) => A + 1)), F = requestAnimationFrame(z);
119
+ }, K = () => {
120
+ const f = r.current;
121
+ if (!f || v) return "no-element";
122
+ try {
123
+ const { id: h, context: p, analyser: A } = oe(f, i);
124
+ D = h, E = f, w.current = p, C.current = A, g(p.state === "suspended"), u(null), p.addEventListener("statechange", U);
125
+ const b = A.frequencyBinCount, O = A.fftSize;
126
+ return d.current = new Uint8Array(b), k.current = new Uint8Array(O), T({ frequencyBinCount: b, sampleRate: p.sampleRate }), F = requestAnimationFrame(z), "ok";
127
+ } catch (h) {
128
+ const p = h instanceof Error ? h.message : "Failed to attach live analyser";
129
+ return u(p), w.current = null, C.current = null, d.current = G, k.current = N, T({ frequencyBinCount: 0, sampleRate: 0 }), "error";
130
+ }
131
+ }, X = K();
132
+ if (X !== "ok") {
133
+ let f = 0;
134
+ const h = 120;
135
+ let p = 0;
136
+ const A = () => {
137
+ if (v) return;
138
+ const b = K();
139
+ b === "ok" || b === "error" || (p += 1, !(p >= h) && (f = requestAnimationFrame(A)));
140
+ };
141
+ return X === "no-element" && (f = requestAnimationFrame(A)), () => {
142
+ var b;
143
+ v = !0, cancelAnimationFrame(f), cancelAnimationFrame(F), D != null && E && V(E, D), (b = w.current) == null || b.removeEventListener("statechange", U), w.current = null, C.current = null, d.current = G, k.current = N;
144
+ };
145
+ }
146
+ return () => {
147
+ var f;
148
+ v = !0, cancelAnimationFrame(F), D != null && E && V(E, D), (f = w.current) == null || f.removeEventListener("statechange", U), w.current = null, C.current = null, d.current = G, k.current = N, T({ frequencyBinCount: 0, sampleRate: 0 });
149
+ };
150
+ }, [t, r, i, a.currentIndex]), {
151
+ frequencyData: d.current,
152
+ timeDomainData: k.current,
153
+ frequencyBinCount: S.frequencyBinCount,
154
+ sampleRate: S.sampleRate,
155
+ isSuspended: x,
156
+ error: m,
157
+ resume: J
158
+ };
159
+ }
160
+ function de(n = !0, t = {}) {
161
+ const { togglePlayPause: e, next: s, prev: o } = R(), { toggleMute: c } = q(), r = t.mute;
162
+ I(() => {
163
+ if (!n || typeof window > "u") return;
164
+ const a = (t.playPause ?? " ").toLowerCase(), i = (t.next ?? "ArrowRight").toLowerCase(), l = (t.previous ?? "ArrowLeft").toLowerCase(), y = r == null ? void 0 : r.toLowerCase(), m = (u) => {
165
+ const x = u.target;
166
+ if (x && (["INPUT", "TEXTAREA", "SELECT"].includes(x.tagName) || x.isContentEditable)) return;
167
+ const g = u.key.toLowerCase();
168
+ g === a ? (u.preventDefault(), e()) : g === i ? (u.preventDefault(), s()) : g === l ? (u.preventDefault(), o()) : y && g === y && (u.preventDefault(), c());
169
+ };
170
+ return window.addEventListener("keydown", m), () => window.removeEventListener("keydown", m);
171
+ }, [t.next, t.playPause, t.previous, n, r, s, o, c, e]);
172
+ }
173
+ function pe() {
174
+ const { tracks: n, currentIndex: t } = R(), { currentTime: e, seek: s } = q(), o = M(() => {
175
+ var a;
176
+ return [...((a = n[t]) == null ? void 0 : a.chapters) ?? []].filter((i) => i && Number.isFinite(i.startSeconds) && i.startSeconds >= 0).sort((i, l) => i.startSeconds - l.startSeconds);
177
+ }, [t, n]), c = M(() => {
178
+ if (o.length === 0) return -1;
179
+ for (let r = o.length - 1; r >= 0; r -= 1)
180
+ if (e >= o[r].startSeconds) return r;
181
+ return -1;
182
+ }, [e, o]);
183
+ return {
184
+ list: o,
185
+ activeIndex: c,
186
+ active: c >= 0 ? o[c] ?? null : null,
187
+ seekTo: (r) => {
188
+ const a = o[r];
189
+ a && s(a.startSeconds);
190
+ }
191
+ };
192
+ }
193
+ const H = /\[(\d{1,2}):(\d{2})(?:\.(\d{1,3}))?\]/g;
194
+ function ae(n) {
195
+ const t = [];
196
+ for (const e of n.split(/\r?\n/)) {
197
+ const s = [...e.matchAll(H)];
198
+ if (s.length === 0) continue;
199
+ const o = e.replace(H, "").trim();
200
+ for (const c of s) {
201
+ const r = Number(c[1] ?? 0), a = Number(c[2] ?? 0), i = Number((c[3] ?? "0").padEnd(3, "0")), l = r * 60 + a + i / 1e3;
202
+ Number.isFinite(l) && l >= 0 && t.push({ time: l, text: o });
203
+ }
204
+ }
205
+ return t.sort((e, s) => e.time - s.time);
206
+ }
207
+ function ye() {
208
+ const { tracks: n, currentIndex: t } = R(), { currentTime: e } = q(), s = n[t], o = M(() => s ? Array.isArray(s.lyricsTimed) && s.lyricsTimed.length > 0 ? [...s.lyricsTimed].filter((r) => Number.isFinite(r.time) && r.time >= 0).sort((r, a) => r.time - a.time) : typeof s.lyrics == "string" ? ae(s.lyrics) : [] : [], [s]), c = M(() => {
209
+ for (let r = o.length - 1; r >= 0; r -= 1)
210
+ if (e >= o[r].time) return r;
211
+ return -1;
212
+ }, [e, o]);
213
+ return {
214
+ lines: o,
215
+ activeIndex: c,
216
+ activeLine: c >= 0 ? o[c] ?? null : null
217
+ };
218
+ }
219
+ function ge(n) {
220
+ const { durationMs: t, stopAfterTracks: e, respectPause: s = !0, enabled: o = !0, onFire: c } = n, { currentIndex: r, pause: a, isPaused: i } = R(), l = L(e ?? 0), y = L(r);
221
+ I(() => {
222
+ l.current = e ?? 0;
223
+ }, [e]), I(() => {
224
+ if (!o || !t || t <= 0 || s && i) return;
225
+ const m = setTimeout(() => {
226
+ a(), c == null || c();
227
+ }, t);
228
+ return () => clearTimeout(m);
229
+ }, [t, o, i, c, a, s]), I(() => {
230
+ if (!o || !e || e <= 0) return;
231
+ const m = y.current;
232
+ y.current = r, r !== m && (l.current -= 1, l.current <= 0 && (a(), c == null || c()));
233
+ }, [r, o, c, a, e]);
234
+ }
235
+ function ke(n = !1) {
236
+ const t = Z(), e = L(t);
237
+ I(() => {
238
+ if (!n || typeof console > "u") return;
239
+ const s = e.current;
240
+ s !== t && console.debug("[ginger]", {
241
+ from: {
242
+ currentIndex: s.currentIndex,
243
+ isPaused: s.isPaused,
244
+ currentTime: s.currentTime,
245
+ repeatMode: s.repeatMode
246
+ },
247
+ to: {
248
+ currentIndex: t.currentIndex,
249
+ isPaused: t.isPaused,
250
+ currentTime: t.currentTime,
251
+ repeatMode: t.repeatMode
252
+ }
253
+ }), e.current = t;
254
+ }, [n, t]);
255
+ }
256
+ function ie(n) {
257
+ return Math.max(0, Math.min(1, n));
258
+ }
259
+ function ve(n) {
260
+ const t = q(), e = R(), { seek: s } = t, [o, c] = P(0), [r, a] = P(!1), i = j(W(e, t)), l = r ? o : i, y = Q(
261
+ (m) => {
262
+ if (!(n > 0)) return;
263
+ const u = m.currentTarget, x = u.getBoundingClientRect(), g = (d) => {
264
+ const k = ie((d - x.left) / x.width);
265
+ c(k), s(k * n);
266
+ };
267
+ a(!0), u.setPointerCapture(m.pointerId), g(m.clientX);
268
+ const S = (d) => g(d.clientX), T = (d) => {
269
+ g(d.clientX), a(!1), u.releasePointerCapture(m.pointerId), u.removeEventListener("pointermove", S), u.removeEventListener("pointerup", T), u.removeEventListener("pointercancel", T);
270
+ };
271
+ u.addEventListener("pointermove", S), u.addEventListener("pointerup", T), u.addEventListener("pointercancel", T);
272
+ },
273
+ [n, s]
274
+ );
275
+ return { fraction: o, displayFraction: l, isDragging: r, onPointerDown: y };
276
+ }
277
+ export {
278
+ oe as a,
279
+ pe as b,
280
+ ke as c,
281
+ V as d,
282
+ de as e,
283
+ me as f,
284
+ ye as g,
285
+ ge as h,
286
+ ve as i,
287
+ ae as p,
288
+ se as u
289
+ };
290
+ //# sourceMappingURL=useSeekDrag-Br1V0Vao.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSeekDrag-Br1V0Vao.js","sources":["../src/hooks/useGinger.ts","../src/analyzer/liveAudioGraph.ts","../src/analyzer/useGingerLiveAnalyzer.ts","../src/hooks/useGingerKeyboardShortcuts.ts","../src/hooks/useGingerChapters.ts","../src/internal/lyrics.ts","../src/hooks/useGingerLyricsSync.ts","../src/hooks/useGingerSleepTimer.ts","../src/hooks/useGingerDebugLog.ts","../src/hooks/useSeekDrag.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { gingerStateFromContextValues, useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\nimport {\n derivePlaybackUiState,\n effectiveDuration,\n effectiveRemaining,\n getCurrentTrack,\n progressFraction,\n resolvedAlbumLine,\n resolvedArtwork,\n} from \"../internal/selectors\";\n\nexport function useGinger() {\n const pb = useGingerPlayback();\n const md = useGingerMedia();\n\n return useMemo(\n () => {\n const state = gingerStateFromContextValues(pb, md);\n return {\n state,\n currentTrack: getCurrentTrack(state),\n playbackUi: derivePlaybackUiState(state),\n duration: effectiveDuration(state),\n remaining: effectiveRemaining(state),\n progress: progressFraction(state),\n artworkUrl: resolvedArtwork(state),\n albumLine: resolvedAlbumLine(state),\n play: pb.play,\n pause: pb.pause,\n togglePlayPause: pb.togglePlayPause,\n seek: md.seek,\n setVolume: md.setVolume,\n setMuted: md.setMuted,\n toggleMute: md.toggleMute,\n setPlaybackRate: md.setPlaybackRate,\n next: pb.next,\n prev: pb.prev,\n setRepeatMode: pb.setRepeatMode,\n cycleRepeat: pb.cycleRepeat,\n toggleShuffle: pb.toggleShuffle,\n setQueue: pb.setQueue,\n insertTrackAt: pb.insertTrackAt,\n removeTrackAt: pb.removeTrackAt,\n moveTrack: pb.moveTrack,\n enqueueNext: pb.enqueueNext,\n playTrackAt: pb.playTrackAt,\n selectTrackAt: pb.selectTrackAt,\n setPlaylistMeta: pb.setPlaylistMeta,\n setPlaybackMode: pb.setPlaybackMode,\n init: pb.init,\n audioRef: md.audioRef,\n dispatch: pb.dispatch,\n };\n },\n [pb, md],\n );\n}\n","/** One MediaElementAudioSourceNode per HTMLAudioElement; multiple AnalyserNodes may tap the source. */\n\nexport type LiveAnalyserOptions = {\n fftSize: number;\n smoothingTimeConstant: number;\n minDecibels: number;\n maxDecibels: number;\n};\n\ntype Consumer = {\n analyser: AnalyserNode;\n /** This analyser is wired to `audioContext.destination` so the graph is audible. */\n isPlaybackSink: boolean;\n};\n\ntype ElementEntry = {\n context: AudioContext;\n source: MediaElementAudioSourceNode;\n consumers: Map<number, Consumer>;\n nextId: number;\n};\n\nconst entries = new WeakMap<HTMLAudioElement, ElementEntry>();\n\nfunction clampFftSize(n: number): number {\n const p = 2 ** Math.round(Math.log2(n));\n return Math.min(32768, Math.max(32, p));\n}\n\nexport function attachLiveAnalyser(\n element: HTMLAudioElement,\n options: LiveAnalyserOptions,\n): { id: number; context: AudioContext; analyser: AnalyserNode } {\n let entry = entries.get(element);\n if (!entry) {\n const Context = window.AudioContext ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!Context) {\n throw new Error(\"Web Audio API is not available\");\n }\n const context = new Context();\n const source = context.createMediaElementSource(element);\n entry = { context, source, consumers: new Map(), nextId: 0 };\n entries.set(element, entry);\n }\n\n const { context, source } = entry;\n const analyser = context.createAnalyser();\n analyser.fftSize = clampFftSize(options.fftSize);\n analyser.smoothingTimeConstant = options.smoothingTimeConstant;\n analyser.minDecibels = options.minDecibels;\n analyser.maxDecibels = options.maxDecibels;\n\n source.connect(analyser);\n\n const isFirst = entry.consumers.size === 0;\n if (isFirst) {\n analyser.connect(context.destination);\n }\n\n const id = entry.nextId;\n entry.nextId += 1;\n entry.consumers.set(id, { analyser, isPlaybackSink: isFirst });\n\n return { id, context, analyser };\n}\n\nexport function detachLiveAnalyser(element: HTMLAudioElement, id: number): void {\n const entry = entries.get(element);\n if (!entry) return;\n\n const consumer = entry.consumers.get(id);\n if (!consumer) return;\n\n const { analyser, isPlaybackSink } = consumer;\n analyser.disconnect();\n entry.consumers.delete(id);\n\n if (entry.consumers.size === 0) {\n try {\n entry.source.disconnect();\n } catch {\n // ignore\n }\n void entry.context.close();\n entries.delete(element);\n return;\n }\n\n if (isPlaybackSink) {\n const first = entry.consumers.values().next().value as Consumer | undefined;\n if (first) {\n first.analyser.connect(entry.context.destination);\n first.isPlaybackSink = true;\n }\n }\n}\n","import { useCallback, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useGinger } from \"../hooks/useGinger\";\nimport { attachLiveAnalyser, detachLiveAnalyser, type LiveAnalyserOptions } from \"./liveAudioGraph\";\n\nexport type UseGingerLiveAnalyzerOptions = {\n /** When false, the analyser is detached and no frames are read. Default true. */\n enabled?: boolean;\n fftSize?: number;\n smoothingTimeConstant?: number;\n minDecibels?: number;\n maxDecibels?: number;\n};\n\nexport type UseGingerLiveAnalyzerResult = {\n /** Byte frequency data (0–255); length equals `frequencyBinCount`. Updated each animation frame while enabled. */\n frequencyData: Uint8Array;\n /** Byte time-domain data (0–255); length equals `fftSize`. */\n timeDomainData: Uint8Array;\n frequencyBinCount: number;\n sampleRate: number;\n isSuspended: boolean;\n error: string | null;\n resume: () => Promise<void>;\n};\n\nconst emptyFreq = new Uint8Array(0);\nconst emptyTime = new Uint8Array(0);\n\nexport function useGingerLiveAnalyzer(options: UseGingerLiveAnalyzerOptions = {}): UseGingerLiveAnalyzerResult {\n const {\n enabled = true,\n fftSize = 2048,\n smoothingTimeConstant = 0.8,\n minDecibels = -100,\n maxDecibels = -30,\n } = options;\n\n const { audioRef, state } = useGinger();\n const opts = useMemo<LiveAnalyserOptions>(\n () => ({\n fftSize,\n smoothingTimeConstant,\n minDecibels,\n maxDecibels,\n }),\n [fftSize, smoothingTimeConstant, minDecibels, maxDecibels],\n );\n\n const [frame, setFrame] = useState(0);\n const [error, setError] = useState<string | null>(null);\n const [isSuspended, setIsSuspended] = useState(false);\n const [meta, setMeta] = useState({ frequencyBinCount: 0, sampleRate: 0 });\n\n const freqRef = useRef<Uint8Array>(emptyFreq);\n const timeRef = useRef<Uint8Array>(emptyTime);\n\n const resume = useCallback(async () => {\n const ctx = contextHolderRef.current;\n if (ctx && ctx.state === \"suspended\") {\n await ctx.resume();\n }\n }, []);\n\n const contextHolderRef = useRef<AudioContext | null>(null);\n const analyserHolderRef = useRef<AnalyserNode | null>(null);\n\n useLayoutEffect(() => {\n if (!enabled || typeof window === \"undefined\") {\n return;\n }\n\n let cancelled = false;\n let consumerId: number | null = null;\n let element: HTMLAudioElement | null = null;\n let rafId = 0;\n\n const onStateChange = () => {\n const ctx = contextHolderRef.current;\n if (ctx) setIsSuspended(ctx.state === \"suspended\");\n };\n\n const runLoop = () => {\n if (cancelled) return;\n const a = analyserHolderRef.current;\n const fq = freqRef.current;\n const td = timeRef.current;\n if (a && fq.length > 0 && td.length > 0) {\n a.getByteFrequencyData(fq as Uint8Array<ArrayBuffer>);\n a.getByteTimeDomainData(td as Uint8Array<ArrayBuffer>);\n setFrame((n) => n + 1);\n }\n rafId = requestAnimationFrame(runLoop);\n };\n\n type AttachOutcome = \"ok\" | \"no-element\" | \"error\";\n\n const attach = (): AttachOutcome => {\n const el = audioRef.current;\n if (!el || cancelled) return \"no-element\";\n try {\n const { id, context, analyser } = attachLiveAnalyser(el, opts);\n consumerId = id;\n element = el;\n contextHolderRef.current = context;\n analyserHolderRef.current = analyser;\n setIsSuspended(context.state === \"suspended\");\n setError(null);\n\n context.addEventListener(\"statechange\", onStateChange);\n\n const n = analyser.frequencyBinCount;\n const fft = analyser.fftSize;\n freqRef.current = new Uint8Array(n);\n timeRef.current = new Uint8Array(fft);\n setMeta({ frequencyBinCount: n, sampleRate: context.sampleRate });\n\n rafId = requestAnimationFrame(runLoop);\n return \"ok\";\n } catch (e) {\n const msg = e instanceof Error ? e.message : \"Failed to attach live analyser\";\n setError(msg);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n setMeta({ frequencyBinCount: 0, sampleRate: 0 });\n return \"error\";\n }\n };\n\n const first = attach();\n if (first !== \"ok\") {\n let retryRaf = 0;\n const maxAttempts = 120;\n let attempts = 0;\n\n const retryLoop = () => {\n if (cancelled) return;\n const out = attach();\n if (out === \"ok\" || out === \"error\") return;\n attempts += 1;\n if (attempts >= maxAttempts) return;\n retryRaf = requestAnimationFrame(retryLoop);\n };\n\n if (first === \"no-element\") {\n retryRaf = requestAnimationFrame(retryLoop);\n }\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(retryRaf);\n cancelAnimationFrame(rafId);\n if (consumerId != null && element) {\n detachLiveAnalyser(element, consumerId);\n }\n contextHolderRef.current?.removeEventListener(\"statechange\", onStateChange);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n };\n }\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(rafId);\n if (consumerId != null && element) {\n detachLiveAnalyser(element, consumerId);\n }\n contextHolderRef.current?.removeEventListener(\"statechange\", onStateChange);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n setMeta({ frequencyBinCount: 0, sampleRate: 0 });\n };\n }, [enabled, audioRef, opts, state.currentIndex]);\n\n void frame;\n\n return {\n frequencyData: freqRef.current,\n timeDomainData: timeRef.current,\n frequencyBinCount: meta.frequencyBinCount,\n sampleRate: meta.sampleRate,\n isSuspended,\n error,\n resume,\n };\n}\n","import { useEffect } from \"react\";\nimport { useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerKeyboardShortcutBindings = {\n playPause?: string;\n next?: string;\n previous?: string;\n mute?: string;\n};\n\nexport function useGingerKeyboardShortcuts(\n enabled = true,\n bindings: GingerKeyboardShortcutBindings = {},\n): void {\n const { togglePlayPause, next, prev } = useGingerPlayback();\n const { toggleMute } = useGingerMedia();\n\n const muteBinding = bindings.mute;\n\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n const playPause = (bindings.playPause ?? \" \").toLowerCase();\n const nextKey = (bindings.next ?? \"ArrowRight\").toLowerCase();\n const prevKey = (bindings.previous ?? \"ArrowLeft\").toLowerCase();\n const muteKey = muteBinding?.toLowerCase();\n\n const onKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (target && ([\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName) || target.isContentEditable)) return;\n const key = event.key.toLowerCase();\n if (key === playPause) {\n event.preventDefault();\n togglePlayPause();\n } else if (key === nextKey) {\n event.preventDefault();\n next();\n } else if (key === prevKey) {\n event.preventDefault();\n prev();\n } else if (muteKey && key === muteKey) {\n event.preventDefault();\n toggleMute();\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [bindings.next, bindings.playPause, bindings.previous, enabled, muteBinding, next, prev, toggleMute, togglePlayPause]);\n}\n","import { useMemo } from \"react\";\nimport { useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerChapter = {\n title: string;\n startSeconds: number;\n};\n\nexport type GingerChapterState = {\n list: GingerChapter[];\n activeIndex: number;\n active: GingerChapter | null;\n seekTo: (index: number) => void;\n};\n\nexport function useGingerChapters(): GingerChapterState {\n const { tracks, currentIndex } = useGingerPlayback();\n const { currentTime, seek } = useGingerMedia();\n\n const list = useMemo(() => {\n const chapters = tracks[currentIndex]?.chapters ?? [];\n return [...chapters]\n .filter((item) => item && Number.isFinite(item.startSeconds) && item.startSeconds >= 0)\n .sort((a, b) => a.startSeconds - b.startSeconds);\n }, [currentIndex, tracks]);\n\n const activeIndex = useMemo(() => {\n if (list.length === 0) return -1;\n for (let i = list.length - 1; i >= 0; i -= 1) {\n if (currentTime >= list[i]!.startSeconds) return i;\n }\n return -1;\n }, [currentTime, list]);\n\n return {\n list,\n activeIndex,\n active: activeIndex >= 0 ? list[activeIndex] ?? null : null,\n seekTo: (index: number) => {\n const chapter = list[index];\n if (chapter) seek(chapter.startSeconds);\n },\n };\n}\n","export type TimedLyricLine = {\n time: number;\n text: string;\n};\n\nconst lrcTag = /\\[(\\d{1,2}):(\\d{2})(?:\\.(\\d{1,3}))?\\]/g;\n\nexport function parseLrc(lrc: string): TimedLyricLine[] {\n const lines: TimedLyricLine[] = [];\n for (const rawLine of lrc.split(/\\r?\\n/)) {\n const matches = [...rawLine.matchAll(lrcTag)];\n if (matches.length === 0) continue;\n const text = rawLine.replace(lrcTag, \"\").trim();\n for (const m of matches) {\n const minutes = Number(m[1] ?? 0);\n const seconds = Number(m[2] ?? 0);\n const millis = Number((m[3] ?? \"0\").padEnd(3, \"0\"));\n const time = minutes * 60 + seconds + millis / 1000;\n if (Number.isFinite(time) && time >= 0) {\n lines.push({ time, text });\n }\n }\n }\n return lines.sort((a, b) => a.time - b.time);\n}\n","import { useMemo } from \"react\";\nimport { useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\nimport { parseLrc, type TimedLyricLine } from \"../internal/lyrics\";\n\nexport type GingerLyricsSyncState = {\n lines: TimedLyricLine[];\n activeIndex: number;\n activeLine: TimedLyricLine | null;\n};\n\nexport function useGingerLyricsSync(): GingerLyricsSyncState {\n const { tracks, currentIndex } = useGingerPlayback();\n const { currentTime } = useGingerMedia();\n const currentTrack = tracks[currentIndex];\n\n const lines = useMemo(() => {\n if (!currentTrack) return [];\n if (Array.isArray(currentTrack.lyricsTimed) && currentTrack.lyricsTimed.length > 0) {\n return [...currentTrack.lyricsTimed]\n .filter((line) => Number.isFinite(line.time) && line.time >= 0)\n .sort((a, b) => a.time - b.time);\n }\n if (typeof currentTrack.lyrics === \"string\") {\n return parseLrc(currentTrack.lyrics);\n }\n return [];\n }, [currentTrack]);\n\n const activeIndex = useMemo(() => {\n for (let i = lines.length - 1; i >= 0; i -= 1) {\n if (currentTime >= lines[i]!.time) return i;\n }\n return -1;\n }, [currentTime, lines]);\n\n return {\n lines,\n activeIndex,\n activeLine: activeIndex >= 0 ? lines[activeIndex] ?? null : null,\n };\n}\n","import { useEffect, useRef } from \"react\";\nimport { useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerSleepTimerOptions = {\n durationMs?: number;\n stopAfterTracks?: number;\n respectPause?: boolean;\n enabled?: boolean;\n onFire?: () => void;\n};\n\nexport function useGingerSleepTimer(options: GingerSleepTimerOptions): void {\n const { durationMs, stopAfterTracks, respectPause = true, enabled = true, onFire } = options;\n const { currentIndex, pause, isPaused } = useGingerPlayback();\n const remainingTracksRef = useRef(stopAfterTracks ?? 0);\n const prevIndexRef = useRef(currentIndex);\n\n useEffect(() => {\n remainingTracksRef.current = stopAfterTracks ?? 0;\n }, [stopAfterTracks]);\n\n useEffect(() => {\n if (!enabled || !durationMs || durationMs <= 0) return;\n if (respectPause && isPaused) return;\n const id = setTimeout(() => {\n pause();\n onFire?.();\n }, durationMs);\n return () => clearTimeout(id);\n }, [durationMs, enabled, isPaused, onFire, pause, respectPause]);\n\n useEffect(() => {\n if (!enabled || !stopAfterTracks || stopAfterTracks <= 0) return;\n const prev = prevIndexRef.current;\n prevIndexRef.current = currentIndex;\n if (currentIndex === prev) return;\n remainingTracksRef.current -= 1;\n if (remainingTracksRef.current <= 0) {\n pause();\n onFire?.();\n }\n }, [currentIndex, enabled, onFire, pause, stopAfterTracks]);\n}\n","import { useEffect, useRef } from \"react\";\nimport { useGingerState } from \"../context/GingerSplitContexts\";\n\nexport function useGingerDebugLog(enabled = false): void {\n const state = useGingerState();\n const prevRef = useRef(state);\n\n useEffect(() => {\n if (!enabled || typeof console === \"undefined\") return;\n const prev = prevRef.current;\n if (prev !== state) {\n console.debug(\"[ginger]\", {\n from: {\n currentIndex: prev.currentIndex,\n isPaused: prev.isPaused,\n currentTime: prev.currentTime,\n repeatMode: prev.repeatMode,\n },\n to: {\n currentIndex: state.currentIndex,\n isPaused: state.isPaused,\n currentTime: state.currentTime,\n repeatMode: state.repeatMode,\n },\n });\n }\n prevRef.current = state;\n }, [enabled, state]);\n}\n","import { useCallback, useState } from \"react\";\nimport type { PointerEvent as ReactPointerEvent } from \"react\";\nimport { useGingerMedia, useGingerPlayback, gingerStateFromContextValues } from \"../context/GingerSplitContexts\";\nimport { progressFraction } from \"../internal/selectors\";\n\nexport type SeekDragState = {\n /** Raw drag fraction — only updated during an active drag gesture. */\n fraction: number;\n /** Blended fraction: follows live playback when idle, drag position when dragging. */\n displayFraction: number;\n isDragging: boolean;\n onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;\n};\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nexport function useSeekDrag(duration: number): SeekDragState {\n const media = useGingerMedia();\n const playback = useGingerPlayback();\n const { seek } = media;\n const [fraction, setFraction] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n\n const liveFraction = progressFraction(gingerStateFromContextValues(playback, media));\n const displayFraction = isDragging ? fraction : liveFraction;\n\n const onPointerDown = useCallback(\n (event: ReactPointerEvent<HTMLElement>) => {\n if (!(duration > 0)) return;\n const target = event.currentTarget;\n const rect = target.getBoundingClientRect();\n const update = (clientX: number) => {\n const ratio = clamp01((clientX - rect.left) / rect.width);\n setFraction(ratio);\n seek(ratio * duration);\n };\n setIsDragging(true);\n target.setPointerCapture(event.pointerId);\n update(event.clientX);\n const onMove = (moveEvent: PointerEvent) => update(moveEvent.clientX);\n const onUp = (upEvent: PointerEvent) => {\n update(upEvent.clientX);\n setIsDragging(false);\n target.releasePointerCapture(event.pointerId);\n target.removeEventListener(\"pointermove\", onMove);\n target.removeEventListener(\"pointerup\", onUp);\n target.removeEventListener(\"pointercancel\", onUp);\n };\n target.addEventListener(\"pointermove\", onMove);\n target.addEventListener(\"pointerup\", onUp);\n target.addEventListener(\"pointercancel\", onUp);\n },\n [duration, seek],\n );\n\n return { fraction, displayFraction, isDragging, onPointerDown };\n}\n"],"names":["useGinger","pb","useGingerPlayback","md","useGingerMedia","useMemo","state","gingerStateFromContextValues","getCurrentTrack","derivePlaybackUiState","effectiveDuration","effectiveRemaining","progressFraction","resolvedArtwork","resolvedAlbumLine","entries","clampFftSize","p","attachLiveAnalyser","element","options","entry","Context","context","source","analyser","isFirst","id","detachLiveAnalyser","consumer","isPlaybackSink","first","emptyFreq","emptyTime","useGingerLiveAnalyzer","enabled","fftSize","smoothingTimeConstant","minDecibels","maxDecibels","audioRef","opts","frame","setFrame","useState","error","setError","isSuspended","setIsSuspended","meta","setMeta","freqRef","useRef","timeRef","resume","useCallback","ctx","contextHolderRef","analyserHolderRef","useLayoutEffect","cancelled","consumerId","rafId","onStateChange","runLoop","a","fq","td","n","attach","el","fft","e","msg","retryRaf","maxAttempts","attempts","retryLoop","out","_a","useGingerKeyboardShortcuts","bindings","togglePlayPause","next","prev","toggleMute","muteBinding","useEffect","playPause","nextKey","prevKey","muteKey","onKeyDown","event","target","key","useGingerChapters","tracks","currentIndex","currentTime","seek","list","item","b","activeIndex","i","index","chapter","lrcTag","parseLrc","lrc","lines","rawLine","matches","text","m","minutes","seconds","millis","time","useGingerLyricsSync","currentTrack","line","useGingerSleepTimer","durationMs","stopAfterTracks","respectPause","onFire","pause","isPaused","remainingTracksRef","prevIndexRef","useGingerDebugLog","useGingerState","prevRef","clamp01","value","useSeekDrag","duration","media","playback","fraction","setFraction","isDragging","setIsDragging","liveFraction","displayFraction","onPointerDown","rect","update","clientX","ratio","onMove","moveEvent","onUp","upEvent"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";const a=require("react"),d=require("./GingerSplitContexts-C7puo0M7.cjs"),b=require("./ginger-BiI69vrn.cjs");function V(){const n=d.useGingerPlayback(),t=d.useGingerMedia();return a.useMemo(()=>{const e=d.gingerStateFromContextValues(n,t);return{state:e,currentTrack:b.getCurrentTrack(e),playbackUi:b.derivePlaybackUiState(e),duration:b.effectiveDuration(e),remaining:b.effectiveRemaining(e),progress:b.progressFraction(e),artworkUrl:b.resolvedArtwork(e),albumLine:b.resolvedAlbumLine(e),play:n.play,pause:n.pause,togglePlayPause:n.togglePlayPause,seek:t.seek,setVolume:t.setVolume,setMuted:t.setMuted,toggleMute:t.toggleMute,setPlaybackRate:t.setPlaybackRate,next:n.next,prev:n.prev,setRepeatMode:n.setRepeatMode,cycleRepeat:n.cycleRepeat,toggleShuffle:n.toggleShuffle,setQueue:n.setQueue,insertTrackAt:n.insertTrackAt,removeTrackAt:n.removeTrackAt,moveTrack:n.moveTrack,enqueueNext:n.enqueueNext,playTrackAt:n.playTrackAt,selectTrackAt:n.selectTrackAt,setPlaylistMeta:n.setPlaylistMeta,setPlaybackMode:n.setPlaybackMode,init:n.init,audioRef:t.audioRef,dispatch:n.dispatch}},[n,t])}const q=new WeakMap;function j(n){const t=2**Math.round(Math.log2(n));return Math.min(32768,Math.max(32,t))}function X(n,t){let e=q.get(n);if(!e){const i=window.AudioContext??window.webkitAudioContext;if(!i)throw new Error("Web Audio API is not available");const f=new i,k=f.createMediaElementSource(n);e={context:f,source:k,consumers:new Map,nextId:0},q.set(n,e)}const{context:s,source:o}=e,c=s.createAnalyser();c.fftSize=j(t.fftSize),c.smoothingTimeConstant=t.smoothingTimeConstant,c.minDecibels=t.minDecibels,c.maxDecibels=t.maxDecibels,o.connect(c);const r=e.consumers.size===0;r&&c.connect(s.destination);const u=e.nextId;return e.nextId+=1,e.consumers.set(u,{analyser:c,isPlaybackSink:r}),{id:u,context:s,analyser:c}}function N(n,t){const e=q.get(n);if(!e)return;const s=e.consumers.get(t);if(!s)return;const{analyser:o,isPlaybackSink:c}=s;if(o.disconnect(),e.consumers.delete(t),e.consumers.size===0){try{e.source.disconnect()}catch{}e.context.close(),q.delete(n);return}if(c){const r=e.consumers.values().next().value;r&&(r.analyser.connect(e.context.destination),r.isPlaybackSink=!0)}}const D=new Uint8Array(0),I=new Uint8Array(0);function J(n={}){const{enabled:t=!0,fftSize:e=2048,smoothingTimeConstant:s=.8,minDecibels:o=-100,maxDecibels:c=-30}=n,{audioRef:r,state:u}=V(),i=a.useMemo(()=>({fftSize:e,smoothingTimeConstant:s,minDecibels:o,maxDecibels:c}),[e,s,o,c]),[f,k]=a.useState(0),[g,l]=a.useState(null),[S,v]=a.useState(!1),[P,T]=a.useState({frequencyBinCount:0,sampleRate:0}),p=a.useRef(D),h=a.useRef(I),Q=a.useCallback(async()=>{const x=w.current;x&&x.state==="suspended"&&await x.resume()},[]),w=a.useRef(null),R=a.useRef(null);return a.useLayoutEffect(()=>{if(!t||typeof window>"u")return;let x=!1,C=null,E=null,G=0;const F=()=>{const m=w.current;m&&v(m.state==="suspended")},z=()=>{if(x)return;const m=R.current,A=p.current,y=h.current;m&&A.length>0&&y.length>0&&(m.getByteFrequencyData(A),m.getByteTimeDomainData(y),k(M=>M+1)),G=requestAnimationFrame(z)},B=()=>{const m=r.current;if(!m||x)return"no-element";try{const{id:A,context:y,analyser:M}=X(m,i);C=A,E=m,w.current=y,R.current=M,v(y.state==="suspended"),l(null),y.addEventListener("statechange",F);const L=M.frequencyBinCount,W=M.fftSize;return p.current=new Uint8Array(L),h.current=new Uint8Array(W),T({frequencyBinCount:L,sampleRate:y.sampleRate}),G=requestAnimationFrame(z),"ok"}catch(A){const y=A instanceof Error?A.message:"Failed to attach live analyser";return l(y),w.current=null,R.current=null,p.current=D,h.current=I,T({frequencyBinCount:0,sampleRate:0}),"error"}},U=B();if(U!=="ok"){let m=0;const A=120;let y=0;const M=()=>{if(x)return;const L=B();L==="ok"||L==="error"||(y+=1,!(y>=A)&&(m=requestAnimationFrame(M)))};return U==="no-element"&&(m=requestAnimationFrame(M)),()=>{var L;x=!0,cancelAnimationFrame(m),cancelAnimationFrame(G),C!=null&&E&&N(E,C),(L=w.current)==null||L.removeEventListener("statechange",F),w.current=null,R.current=null,p.current=D,h.current=I}}return()=>{var m;x=!0,cancelAnimationFrame(G),C!=null&&E&&N(E,C),(m=w.current)==null||m.removeEventListener("statechange",F),w.current=null,R.current=null,p.current=D,h.current=I,T({frequencyBinCount:0,sampleRate:0})}},[t,r,i,u.currentIndex]),{frequencyData:p.current,timeDomainData:h.current,frequencyBinCount:P.frequencyBinCount,sampleRate:P.sampleRate,isSuspended:S,error:g,resume:Q}}function O(n=!0,t={}){const{togglePlayPause:e,next:s,prev:o}=d.useGingerPlayback(),{toggleMute:c}=d.useGingerMedia(),r=t.mute;a.useEffect(()=>{if(!n||typeof window>"u")return;const u=(t.playPause??" ").toLowerCase(),i=(t.next??"ArrowRight").toLowerCase(),f=(t.previous??"ArrowLeft").toLowerCase(),k=r==null?void 0:r.toLowerCase(),g=l=>{const S=l.target;if(S&&(["INPUT","TEXTAREA","SELECT"].includes(S.tagName)||S.isContentEditable))return;const v=l.key.toLowerCase();v===u?(l.preventDefault(),e()):v===i?(l.preventDefault(),s()):v===f?(l.preventDefault(),o()):k&&v===k&&(l.preventDefault(),c())};return window.addEventListener("keydown",g),()=>window.removeEventListener("keydown",g)},[t.next,t.playPause,t.previous,n,r,s,o,c,e])}function Y(){const{tracks:n,currentIndex:t}=d.useGingerPlayback(),{currentTime:e,seek:s}=d.useGingerMedia(),o=a.useMemo(()=>{var u;return[...((u=n[t])==null?void 0:u.chapters)??[]].filter(i=>i&&Number.isFinite(i.startSeconds)&&i.startSeconds>=0).sort((i,f)=>i.startSeconds-f.startSeconds)},[t,n]),c=a.useMemo(()=>{if(o.length===0)return-1;for(let r=o.length-1;r>=0;r-=1)if(e>=o[r].startSeconds)return r;return-1},[e,o]);return{list:o,activeIndex:c,active:c>=0?o[c]??null:null,seekTo:r=>{const u=o[r];u&&s(u.startSeconds)}}}const K=/\[(\d{1,2}):(\d{2})(?:\.(\d{1,3}))?\]/g;function H(n){const t=[];for(const e of n.split(/\r?\n/)){const s=[...e.matchAll(K)];if(s.length===0)continue;const o=e.replace(K,"").trim();for(const c of s){const r=Number(c[1]??0),u=Number(c[2]??0),i=Number((c[3]??"0").padEnd(3,"0")),f=r*60+u+i/1e3;Number.isFinite(f)&&f>=0&&t.push({time:f,text:o})}}return t.sort((e,s)=>e.time-s.time)}function Z(){const{tracks:n,currentIndex:t}=d.useGingerPlayback(),{currentTime:e}=d.useGingerMedia(),s=n[t],o=a.useMemo(()=>s?Array.isArray(s.lyricsTimed)&&s.lyricsTimed.length>0?[...s.lyricsTimed].filter(r=>Number.isFinite(r.time)&&r.time>=0).sort((r,u)=>r.time-u.time):typeof s.lyrics=="string"?H(s.lyrics):[]:[],[s]),c=a.useMemo(()=>{for(let r=o.length-1;r>=0;r-=1)if(e>=o[r].time)return r;return-1},[e,o]);return{lines:o,activeIndex:c,activeLine:c>=0?o[c]??null:null}}function _(n){const{durationMs:t,stopAfterTracks:e,respectPause:s=!0,enabled:o=!0,onFire:c}=n,{currentIndex:r,pause:u,isPaused:i}=d.useGingerPlayback(),f=a.useRef(e??0),k=a.useRef(r);a.useEffect(()=>{f.current=e??0},[e]),a.useEffect(()=>{if(!o||!t||t<=0||s&&i)return;const g=setTimeout(()=>{u(),c==null||c()},t);return()=>clearTimeout(g)},[t,o,i,c,u,s]),a.useEffect(()=>{if(!o||!e||e<=0)return;const g=k.current;k.current=r,r!==g&&(f.current-=1,f.current<=0&&(u(),c==null||c()))},[r,o,c,u,e])}function $(n=!1){const t=d.useGingerState(),e=a.useRef(t);a.useEffect(()=>{if(!n||typeof console>"u")return;const s=e.current;s!==t&&console.debug("[ginger]",{from:{currentIndex:s.currentIndex,isPaused:s.isPaused,currentTime:s.currentTime,repeatMode:s.repeatMode},to:{currentIndex:t.currentIndex,isPaused:t.isPaused,currentTime:t.currentTime,repeatMode:t.repeatMode}}),e.current=t},[n,t])}function ee(n){return Math.max(0,Math.min(1,n))}function te(n){const t=d.useGingerMedia(),e=d.useGingerPlayback(),{seek:s}=t,[o,c]=a.useState(0),[r,u]=a.useState(!1),i=b.progressFraction(d.gingerStateFromContextValues(e,t)),f=r?o:i,k=a.useCallback(g=>{if(!(n>0))return;const l=g.currentTarget,S=l.getBoundingClientRect(),v=p=>{const h=ee((p-S.left)/S.width);c(h),s(h*n)};u(!0),l.setPointerCapture(g.pointerId),v(g.clientX);const P=p=>v(p.clientX),T=p=>{v(p.clientX),u(!1),l.releasePointerCapture(g.pointerId),l.removeEventListener("pointermove",P),l.removeEventListener("pointerup",T),l.removeEventListener("pointercancel",T)};l.addEventListener("pointermove",P),l.addEventListener("pointerup",T),l.addEventListener("pointercancel",T)},[n,s]);return{fraction:o,displayFraction:f,isDragging:r,onPointerDown:k}}exports.attachLiveAnalyser=X;exports.detachLiveAnalyser=N;exports.parseLrc=H;exports.useGinger=V;exports.useGingerChapters=Y;exports.useGingerDebugLog=$;exports.useGingerKeyboardShortcuts=O;exports.useGingerLiveAnalyzer=J;exports.useGingerLyricsSync=Z;exports.useGingerSleepTimer=_;exports.useSeekDrag=te;
2
+ //# sourceMappingURL=useSeekDrag-aS7uk26h.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSeekDrag-aS7uk26h.cjs","sources":["../src/hooks/useGinger.ts","../src/analyzer/liveAudioGraph.ts","../src/analyzer/useGingerLiveAnalyzer.ts","../src/hooks/useGingerKeyboardShortcuts.ts","../src/hooks/useGingerChapters.ts","../src/internal/lyrics.ts","../src/hooks/useGingerLyricsSync.ts","../src/hooks/useGingerSleepTimer.ts","../src/hooks/useGingerDebugLog.ts","../src/hooks/useSeekDrag.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { gingerStateFromContextValues, useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\nimport {\n derivePlaybackUiState,\n effectiveDuration,\n effectiveRemaining,\n getCurrentTrack,\n progressFraction,\n resolvedAlbumLine,\n resolvedArtwork,\n} from \"../internal/selectors\";\n\nexport function useGinger() {\n const pb = useGingerPlayback();\n const md = useGingerMedia();\n\n return useMemo(\n () => {\n const state = gingerStateFromContextValues(pb, md);\n return {\n state,\n currentTrack: getCurrentTrack(state),\n playbackUi: derivePlaybackUiState(state),\n duration: effectiveDuration(state),\n remaining: effectiveRemaining(state),\n progress: progressFraction(state),\n artworkUrl: resolvedArtwork(state),\n albumLine: resolvedAlbumLine(state),\n play: pb.play,\n pause: pb.pause,\n togglePlayPause: pb.togglePlayPause,\n seek: md.seek,\n setVolume: md.setVolume,\n setMuted: md.setMuted,\n toggleMute: md.toggleMute,\n setPlaybackRate: md.setPlaybackRate,\n next: pb.next,\n prev: pb.prev,\n setRepeatMode: pb.setRepeatMode,\n cycleRepeat: pb.cycleRepeat,\n toggleShuffle: pb.toggleShuffle,\n setQueue: pb.setQueue,\n insertTrackAt: pb.insertTrackAt,\n removeTrackAt: pb.removeTrackAt,\n moveTrack: pb.moveTrack,\n enqueueNext: pb.enqueueNext,\n playTrackAt: pb.playTrackAt,\n selectTrackAt: pb.selectTrackAt,\n setPlaylistMeta: pb.setPlaylistMeta,\n setPlaybackMode: pb.setPlaybackMode,\n init: pb.init,\n audioRef: md.audioRef,\n dispatch: pb.dispatch,\n };\n },\n [pb, md],\n );\n}\n","/** One MediaElementAudioSourceNode per HTMLAudioElement; multiple AnalyserNodes may tap the source. */\n\nexport type LiveAnalyserOptions = {\n fftSize: number;\n smoothingTimeConstant: number;\n minDecibels: number;\n maxDecibels: number;\n};\n\ntype Consumer = {\n analyser: AnalyserNode;\n /** This analyser is wired to `audioContext.destination` so the graph is audible. */\n isPlaybackSink: boolean;\n};\n\ntype ElementEntry = {\n context: AudioContext;\n source: MediaElementAudioSourceNode;\n consumers: Map<number, Consumer>;\n nextId: number;\n};\n\nconst entries = new WeakMap<HTMLAudioElement, ElementEntry>();\n\nfunction clampFftSize(n: number): number {\n const p = 2 ** Math.round(Math.log2(n));\n return Math.min(32768, Math.max(32, p));\n}\n\nexport function attachLiveAnalyser(\n element: HTMLAudioElement,\n options: LiveAnalyserOptions,\n): { id: number; context: AudioContext; analyser: AnalyserNode } {\n let entry = entries.get(element);\n if (!entry) {\n const Context = window.AudioContext ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!Context) {\n throw new Error(\"Web Audio API is not available\");\n }\n const context = new Context();\n const source = context.createMediaElementSource(element);\n entry = { context, source, consumers: new Map(), nextId: 0 };\n entries.set(element, entry);\n }\n\n const { context, source } = entry;\n const analyser = context.createAnalyser();\n analyser.fftSize = clampFftSize(options.fftSize);\n analyser.smoothingTimeConstant = options.smoothingTimeConstant;\n analyser.minDecibels = options.minDecibels;\n analyser.maxDecibels = options.maxDecibels;\n\n source.connect(analyser);\n\n const isFirst = entry.consumers.size === 0;\n if (isFirst) {\n analyser.connect(context.destination);\n }\n\n const id = entry.nextId;\n entry.nextId += 1;\n entry.consumers.set(id, { analyser, isPlaybackSink: isFirst });\n\n return { id, context, analyser };\n}\n\nexport function detachLiveAnalyser(element: HTMLAudioElement, id: number): void {\n const entry = entries.get(element);\n if (!entry) return;\n\n const consumer = entry.consumers.get(id);\n if (!consumer) return;\n\n const { analyser, isPlaybackSink } = consumer;\n analyser.disconnect();\n entry.consumers.delete(id);\n\n if (entry.consumers.size === 0) {\n try {\n entry.source.disconnect();\n } catch {\n // ignore\n }\n void entry.context.close();\n entries.delete(element);\n return;\n }\n\n if (isPlaybackSink) {\n const first = entry.consumers.values().next().value as Consumer | undefined;\n if (first) {\n first.analyser.connect(entry.context.destination);\n first.isPlaybackSink = true;\n }\n }\n}\n","import { useCallback, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useGinger } from \"../hooks/useGinger\";\nimport { attachLiveAnalyser, detachLiveAnalyser, type LiveAnalyserOptions } from \"./liveAudioGraph\";\n\nexport type UseGingerLiveAnalyzerOptions = {\n /** When false, the analyser is detached and no frames are read. Default true. */\n enabled?: boolean;\n fftSize?: number;\n smoothingTimeConstant?: number;\n minDecibels?: number;\n maxDecibels?: number;\n};\n\nexport type UseGingerLiveAnalyzerResult = {\n /** Byte frequency data (0–255); length equals `frequencyBinCount`. Updated each animation frame while enabled. */\n frequencyData: Uint8Array;\n /** Byte time-domain data (0–255); length equals `fftSize`. */\n timeDomainData: Uint8Array;\n frequencyBinCount: number;\n sampleRate: number;\n isSuspended: boolean;\n error: string | null;\n resume: () => Promise<void>;\n};\n\nconst emptyFreq = new Uint8Array(0);\nconst emptyTime = new Uint8Array(0);\n\nexport function useGingerLiveAnalyzer(options: UseGingerLiveAnalyzerOptions = {}): UseGingerLiveAnalyzerResult {\n const {\n enabled = true,\n fftSize = 2048,\n smoothingTimeConstant = 0.8,\n minDecibels = -100,\n maxDecibels = -30,\n } = options;\n\n const { audioRef, state } = useGinger();\n const opts = useMemo<LiveAnalyserOptions>(\n () => ({\n fftSize,\n smoothingTimeConstant,\n minDecibels,\n maxDecibels,\n }),\n [fftSize, smoothingTimeConstant, minDecibels, maxDecibels],\n );\n\n const [frame, setFrame] = useState(0);\n const [error, setError] = useState<string | null>(null);\n const [isSuspended, setIsSuspended] = useState(false);\n const [meta, setMeta] = useState({ frequencyBinCount: 0, sampleRate: 0 });\n\n const freqRef = useRef<Uint8Array>(emptyFreq);\n const timeRef = useRef<Uint8Array>(emptyTime);\n\n const resume = useCallback(async () => {\n const ctx = contextHolderRef.current;\n if (ctx && ctx.state === \"suspended\") {\n await ctx.resume();\n }\n }, []);\n\n const contextHolderRef = useRef<AudioContext | null>(null);\n const analyserHolderRef = useRef<AnalyserNode | null>(null);\n\n useLayoutEffect(() => {\n if (!enabled || typeof window === \"undefined\") {\n return;\n }\n\n let cancelled = false;\n let consumerId: number | null = null;\n let element: HTMLAudioElement | null = null;\n let rafId = 0;\n\n const onStateChange = () => {\n const ctx = contextHolderRef.current;\n if (ctx) setIsSuspended(ctx.state === \"suspended\");\n };\n\n const runLoop = () => {\n if (cancelled) return;\n const a = analyserHolderRef.current;\n const fq = freqRef.current;\n const td = timeRef.current;\n if (a && fq.length > 0 && td.length > 0) {\n a.getByteFrequencyData(fq as Uint8Array<ArrayBuffer>);\n a.getByteTimeDomainData(td as Uint8Array<ArrayBuffer>);\n setFrame((n) => n + 1);\n }\n rafId = requestAnimationFrame(runLoop);\n };\n\n type AttachOutcome = \"ok\" | \"no-element\" | \"error\";\n\n const attach = (): AttachOutcome => {\n const el = audioRef.current;\n if (!el || cancelled) return \"no-element\";\n try {\n const { id, context, analyser } = attachLiveAnalyser(el, opts);\n consumerId = id;\n element = el;\n contextHolderRef.current = context;\n analyserHolderRef.current = analyser;\n setIsSuspended(context.state === \"suspended\");\n setError(null);\n\n context.addEventListener(\"statechange\", onStateChange);\n\n const n = analyser.frequencyBinCount;\n const fft = analyser.fftSize;\n freqRef.current = new Uint8Array(n);\n timeRef.current = new Uint8Array(fft);\n setMeta({ frequencyBinCount: n, sampleRate: context.sampleRate });\n\n rafId = requestAnimationFrame(runLoop);\n return \"ok\";\n } catch (e) {\n const msg = e instanceof Error ? e.message : \"Failed to attach live analyser\";\n setError(msg);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n setMeta({ frequencyBinCount: 0, sampleRate: 0 });\n return \"error\";\n }\n };\n\n const first = attach();\n if (first !== \"ok\") {\n let retryRaf = 0;\n const maxAttempts = 120;\n let attempts = 0;\n\n const retryLoop = () => {\n if (cancelled) return;\n const out = attach();\n if (out === \"ok\" || out === \"error\") return;\n attempts += 1;\n if (attempts >= maxAttempts) return;\n retryRaf = requestAnimationFrame(retryLoop);\n };\n\n if (first === \"no-element\") {\n retryRaf = requestAnimationFrame(retryLoop);\n }\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(retryRaf);\n cancelAnimationFrame(rafId);\n if (consumerId != null && element) {\n detachLiveAnalyser(element, consumerId);\n }\n contextHolderRef.current?.removeEventListener(\"statechange\", onStateChange);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n };\n }\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(rafId);\n if (consumerId != null && element) {\n detachLiveAnalyser(element, consumerId);\n }\n contextHolderRef.current?.removeEventListener(\"statechange\", onStateChange);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n setMeta({ frequencyBinCount: 0, sampleRate: 0 });\n };\n }, [enabled, audioRef, opts, state.currentIndex]);\n\n void frame;\n\n return {\n frequencyData: freqRef.current,\n timeDomainData: timeRef.current,\n frequencyBinCount: meta.frequencyBinCount,\n sampleRate: meta.sampleRate,\n isSuspended,\n error,\n resume,\n };\n}\n","import { useEffect } from \"react\";\nimport { useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerKeyboardShortcutBindings = {\n playPause?: string;\n next?: string;\n previous?: string;\n mute?: string;\n};\n\nexport function useGingerKeyboardShortcuts(\n enabled = true,\n bindings: GingerKeyboardShortcutBindings = {},\n): void {\n const { togglePlayPause, next, prev } = useGingerPlayback();\n const { toggleMute } = useGingerMedia();\n\n const muteBinding = bindings.mute;\n\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n const playPause = (bindings.playPause ?? \" \").toLowerCase();\n const nextKey = (bindings.next ?? \"ArrowRight\").toLowerCase();\n const prevKey = (bindings.previous ?? \"ArrowLeft\").toLowerCase();\n const muteKey = muteBinding?.toLowerCase();\n\n const onKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (target && ([\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName) || target.isContentEditable)) return;\n const key = event.key.toLowerCase();\n if (key === playPause) {\n event.preventDefault();\n togglePlayPause();\n } else if (key === nextKey) {\n event.preventDefault();\n next();\n } else if (key === prevKey) {\n event.preventDefault();\n prev();\n } else if (muteKey && key === muteKey) {\n event.preventDefault();\n toggleMute();\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [bindings.next, bindings.playPause, bindings.previous, enabled, muteBinding, next, prev, toggleMute, togglePlayPause]);\n}\n","import { useMemo } from \"react\";\nimport { useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerChapter = {\n title: string;\n startSeconds: number;\n};\n\nexport type GingerChapterState = {\n list: GingerChapter[];\n activeIndex: number;\n active: GingerChapter | null;\n seekTo: (index: number) => void;\n};\n\nexport function useGingerChapters(): GingerChapterState {\n const { tracks, currentIndex } = useGingerPlayback();\n const { currentTime, seek } = useGingerMedia();\n\n const list = useMemo(() => {\n const chapters = tracks[currentIndex]?.chapters ?? [];\n return [...chapters]\n .filter((item) => item && Number.isFinite(item.startSeconds) && item.startSeconds >= 0)\n .sort((a, b) => a.startSeconds - b.startSeconds);\n }, [currentIndex, tracks]);\n\n const activeIndex = useMemo(() => {\n if (list.length === 0) return -1;\n for (let i = list.length - 1; i >= 0; i -= 1) {\n if (currentTime >= list[i]!.startSeconds) return i;\n }\n return -1;\n }, [currentTime, list]);\n\n return {\n list,\n activeIndex,\n active: activeIndex >= 0 ? list[activeIndex] ?? null : null,\n seekTo: (index: number) => {\n const chapter = list[index];\n if (chapter) seek(chapter.startSeconds);\n },\n };\n}\n","export type TimedLyricLine = {\n time: number;\n text: string;\n};\n\nconst lrcTag = /\\[(\\d{1,2}):(\\d{2})(?:\\.(\\d{1,3}))?\\]/g;\n\nexport function parseLrc(lrc: string): TimedLyricLine[] {\n const lines: TimedLyricLine[] = [];\n for (const rawLine of lrc.split(/\\r?\\n/)) {\n const matches = [...rawLine.matchAll(lrcTag)];\n if (matches.length === 0) continue;\n const text = rawLine.replace(lrcTag, \"\").trim();\n for (const m of matches) {\n const minutes = Number(m[1] ?? 0);\n const seconds = Number(m[2] ?? 0);\n const millis = Number((m[3] ?? \"0\").padEnd(3, \"0\"));\n const time = minutes * 60 + seconds + millis / 1000;\n if (Number.isFinite(time) && time >= 0) {\n lines.push({ time, text });\n }\n }\n }\n return lines.sort((a, b) => a.time - b.time);\n}\n","import { useMemo } from \"react\";\nimport { useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\nimport { parseLrc, type TimedLyricLine } from \"../internal/lyrics\";\n\nexport type GingerLyricsSyncState = {\n lines: TimedLyricLine[];\n activeIndex: number;\n activeLine: TimedLyricLine | null;\n};\n\nexport function useGingerLyricsSync(): GingerLyricsSyncState {\n const { tracks, currentIndex } = useGingerPlayback();\n const { currentTime } = useGingerMedia();\n const currentTrack = tracks[currentIndex];\n\n const lines = useMemo(() => {\n if (!currentTrack) return [];\n if (Array.isArray(currentTrack.lyricsTimed) && currentTrack.lyricsTimed.length > 0) {\n return [...currentTrack.lyricsTimed]\n .filter((line) => Number.isFinite(line.time) && line.time >= 0)\n .sort((a, b) => a.time - b.time);\n }\n if (typeof currentTrack.lyrics === \"string\") {\n return parseLrc(currentTrack.lyrics);\n }\n return [];\n }, [currentTrack]);\n\n const activeIndex = useMemo(() => {\n for (let i = lines.length - 1; i >= 0; i -= 1) {\n if (currentTime >= lines[i]!.time) return i;\n }\n return -1;\n }, [currentTime, lines]);\n\n return {\n lines,\n activeIndex,\n activeLine: activeIndex >= 0 ? lines[activeIndex] ?? null : null,\n };\n}\n","import { useEffect, useRef } from \"react\";\nimport { useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerSleepTimerOptions = {\n durationMs?: number;\n stopAfterTracks?: number;\n respectPause?: boolean;\n enabled?: boolean;\n onFire?: () => void;\n};\n\nexport function useGingerSleepTimer(options: GingerSleepTimerOptions): void {\n const { durationMs, stopAfterTracks, respectPause = true, enabled = true, onFire } = options;\n const { currentIndex, pause, isPaused } = useGingerPlayback();\n const remainingTracksRef = useRef(stopAfterTracks ?? 0);\n const prevIndexRef = useRef(currentIndex);\n\n useEffect(() => {\n remainingTracksRef.current = stopAfterTracks ?? 0;\n }, [stopAfterTracks]);\n\n useEffect(() => {\n if (!enabled || !durationMs || durationMs <= 0) return;\n if (respectPause && isPaused) return;\n const id = setTimeout(() => {\n pause();\n onFire?.();\n }, durationMs);\n return () => clearTimeout(id);\n }, [durationMs, enabled, isPaused, onFire, pause, respectPause]);\n\n useEffect(() => {\n if (!enabled || !stopAfterTracks || stopAfterTracks <= 0) return;\n const prev = prevIndexRef.current;\n prevIndexRef.current = currentIndex;\n if (currentIndex === prev) return;\n remainingTracksRef.current -= 1;\n if (remainingTracksRef.current <= 0) {\n pause();\n onFire?.();\n }\n }, [currentIndex, enabled, onFire, pause, stopAfterTracks]);\n}\n","import { useEffect, useRef } from \"react\";\nimport { useGingerState } from \"../context/GingerSplitContexts\";\n\nexport function useGingerDebugLog(enabled = false): void {\n const state = useGingerState();\n const prevRef = useRef(state);\n\n useEffect(() => {\n if (!enabled || typeof console === \"undefined\") return;\n const prev = prevRef.current;\n if (prev !== state) {\n console.debug(\"[ginger]\", {\n from: {\n currentIndex: prev.currentIndex,\n isPaused: prev.isPaused,\n currentTime: prev.currentTime,\n repeatMode: prev.repeatMode,\n },\n to: {\n currentIndex: state.currentIndex,\n isPaused: state.isPaused,\n currentTime: state.currentTime,\n repeatMode: state.repeatMode,\n },\n });\n }\n prevRef.current = state;\n }, [enabled, state]);\n}\n","import { useCallback, useState } from \"react\";\nimport type { PointerEvent as ReactPointerEvent } from \"react\";\nimport { useGingerMedia, useGingerPlayback, gingerStateFromContextValues } from \"../context/GingerSplitContexts\";\nimport { progressFraction } from \"../internal/selectors\";\n\nexport type SeekDragState = {\n /** Raw drag fraction — only updated during an active drag gesture. */\n fraction: number;\n /** Blended fraction: follows live playback when idle, drag position when dragging. */\n displayFraction: number;\n isDragging: boolean;\n onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;\n};\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nexport function useSeekDrag(duration: number): SeekDragState {\n const media = useGingerMedia();\n const playback = useGingerPlayback();\n const { seek } = media;\n const [fraction, setFraction] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n\n const liveFraction = progressFraction(gingerStateFromContextValues(playback, media));\n const displayFraction = isDragging ? fraction : liveFraction;\n\n const onPointerDown = useCallback(\n (event: ReactPointerEvent<HTMLElement>) => {\n if (!(duration > 0)) return;\n const target = event.currentTarget;\n const rect = target.getBoundingClientRect();\n const update = (clientX: number) => {\n const ratio = clamp01((clientX - rect.left) / rect.width);\n setFraction(ratio);\n seek(ratio * duration);\n };\n setIsDragging(true);\n target.setPointerCapture(event.pointerId);\n update(event.clientX);\n const onMove = (moveEvent: PointerEvent) => update(moveEvent.clientX);\n const onUp = (upEvent: PointerEvent) => {\n update(upEvent.clientX);\n setIsDragging(false);\n target.releasePointerCapture(event.pointerId);\n target.removeEventListener(\"pointermove\", onMove);\n target.removeEventListener(\"pointerup\", onUp);\n target.removeEventListener(\"pointercancel\", onUp);\n };\n target.addEventListener(\"pointermove\", onMove);\n target.addEventListener(\"pointerup\", onUp);\n target.addEventListener(\"pointercancel\", onUp);\n },\n [duration, seek],\n );\n\n return { fraction, displayFraction, isDragging, onPointerDown };\n}\n"],"names":["useGinger","pb","useGingerPlayback","md","useGingerMedia","useMemo","state","gingerStateFromContextValues","getCurrentTrack","derivePlaybackUiState","effectiveDuration","effectiveRemaining","progressFraction","resolvedArtwork","resolvedAlbumLine","entries","clampFftSize","p","attachLiveAnalyser","element","options","entry","Context","context","source","analyser","isFirst","id","detachLiveAnalyser","consumer","isPlaybackSink","first","emptyFreq","emptyTime","useGingerLiveAnalyzer","enabled","fftSize","smoothingTimeConstant","minDecibels","maxDecibels","audioRef","opts","frame","setFrame","useState","error","setError","isSuspended","setIsSuspended","meta","setMeta","freqRef","useRef","timeRef","resume","useCallback","ctx","contextHolderRef","analyserHolderRef","useLayoutEffect","cancelled","consumerId","rafId","onStateChange","runLoop","a","fq","td","n","attach","el","fft","e","msg","retryRaf","maxAttempts","attempts","retryLoop","out","_a","useGingerKeyboardShortcuts","bindings","togglePlayPause","next","prev","toggleMute","muteBinding","useEffect","playPause","nextKey","prevKey","muteKey","onKeyDown","event","target","key","useGingerChapters","tracks","currentIndex","currentTime","seek","list","item","b","activeIndex","i","index","chapter","lrcTag","parseLrc","lrc","lines","rawLine","matches","text","m","minutes","seconds","millis","time","useGingerLyricsSync","currentTrack","line","useGingerSleepTimer","durationMs","stopAfterTracks","respectPause","onFire","pause","isPaused","remainingTracksRef","prevIndexRef","useGingerDebugLog","useGingerState","prevRef","clamp01","value","useSeekDrag","duration","media","playback","fraction","setFraction","isDragging","setIsDragging","liveFraction","displayFraction","onPointerDown","rect","update","clientX","ratio","onMove","moveEvent","onUp","upEvent"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export type AnalyzeAudioFileOptions = {
2
+ /** Number of time rows in the amplitude grid (and spectrogram if enabled). Default 128. */
3
+ timeSlices?: number;
4
+ /** Sub-buckets per time slice for the amplitude grid. Default 8. */
5
+ samplesPerSlice?: number;
6
+ /** When true, include `spectrogram` using windowed FFT per time slice. Default false. */
7
+ spectrogram?: boolean;
8
+ /** FFT length for spectrogram (power of 2). Default 1024. */
9
+ fftSize?: number;
10
+ /** Number of frequency bins to keep per row (first bins; capped by fftSize/2). Default 256. */
11
+ frequencyBins?: number;
12
+ /** Channel index, or `"mix"` for equal mix of all channels. Default 0. */
13
+ channel?: number | "mix";
14
+ };
15
+ export type AudioFileAnalysis = {
16
+ duration: number;
17
+ sampleRate: number;
18
+ /** Peak amplitudes in [0, 1]: `timeSlices` rows × `samplesPerSlice` columns. */
19
+ amplitudeGrid: number[][];
20
+ /** Optional magnitude spectrogram rows, each length `frequencyBins`, normalized to [0, 1] globally. */
21
+ spectrogram?: number[][];
22
+ };
23
+ /**
24
+ * Decodes an `AudioBuffer` into visualization-friendly grids (no network).
25
+ */
26
+ export declare function analyzeAudioBuffer(buffer: AudioBuffer, options?: AnalyzeAudioFileOptions): AudioFileAnalysis;
27
+ /**
28
+ * Fetches a URL, decodes audio to an `AudioBuffer`, runs {@link analyzeAudioBuffer}, then closes the temporary `AudioContext`.
29
+ */
30
+ export declare function analyzeAudioFile(fileUrl: string, options?: AnalyzeAudioFileOptions): Promise<AudioFileAnalysis>;
31
+ //# sourceMappingURL=analyzeAudioFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzeAudioFile.d.ts","sourceRoot":"","sources":["../../src/waveform/analyzeAudioFile.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,uBAAuB,GAAG;IACpC,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC;IAC1B,uGAAuG;IACvG,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CAC1B,CAAC;AAwGF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,uBAA4B,GAAG,iBAAiB,CAwBhH;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,CAAC,CAiB5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=analyzeAudioFile.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzeAudioFile.test.d.ts","sourceRoot":"","sources":["../../src/waveform/analyzeAudioFile.test.ts"],"names":[],"mappings":""}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react");function k(a,o=64){const[g,t]=h.useState({peaks:[],isLoading:!1,error:null});return h.useEffect(()=>{if(!a){t({peaks:[],isLoading:!1,error:null});return}let r=!1;return t(e=>({...e,isLoading:!0,error:null})),(async()=>{try{const e=await fetch(a);if(!e.ok)throw new Error(`Fetch failed: ${e.status} ${e.statusText}`);const p=await e.arrayBuffer(),c=new AudioContext,s=(await c.decodeAudioData(p)).getChannelData(0),l=Math.max(1,Math.floor(s.length/o)),f=[];for(let n=0;n<o;n+=1){let i=0;const d=n*l,w=Math.min(s.length,d+l);for(let u=d;u<w;u+=1)i=Math.max(i,Math.abs(s[u]??0));f.push(i)}await c.close(),r||t({peaks:f,isLoading:!1,error:null})}catch(e){r||t({peaks:[],isLoading:!1,error:e instanceof Error?e.message:"Failed to decode peaks"})}})(),()=>{r=!0}},[o,a]),g}exports.useAudioPeaks=k;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("react");function F(e,t=64){const[r,a]=y.useState({peaks:[],isLoading:!1,error:null});return y.useEffect(()=>{if(!e){a({peaks:[],isLoading:!1,error:null});return}let o=!1;return a(n=>({...n,isLoading:!0,error:null})),(async()=>{try{const n=await fetch(e);if(!n.ok)throw new Error(`Fetch failed: ${n.status} ${n.statusText}`);const l=await n.arrayBuffer(),s=new AudioContext,u=(await s.decodeAudioData(l)).getChannelData(0),w=Math.max(1,Math.floor(u.length/t)),f=[];for(let d=0;d<t;d+=1){let i=0;const h=d*w,M=Math.min(u.length,h+w);for(let c=h;c<M;c+=1)i=Math.max(i,Math.abs(u[c]??0));f.push(i)}await s.close(),o||a({peaks:f,isLoading:!1,error:null})}catch(n){o||a({peaks:[],isLoading:!1,error:n instanceof Error?n.message:"Failed to decode peaks"})}})(),()=>{o=!0}},[t,e]),r}function L(e,t){const r=e.length;if(r!==t.length||r<2||r&r-1)throw new Error("fftInPlace: length must be equal powers of 2 >= 2");let a=0;for(let o=0;o<r-1;o+=1){if(o<a){const l=e[o],s=t[o];e[o]=e[a],t[o]=t[a],e[a]=l,t[a]=s}let n=r>>1;for(;n<=a;)a-=n,n>>=1;a+=n}for(let o=2;o<=r;o<<=1){const n=-2*Math.PI/o,l=Math.cos(n),s=Math.sin(n);for(let g=0;g<r;g+=o){let u=1,w=0;const f=o>>1;for(let d=0;d<f;d+=1){const i=g+d,h=i+f,M=u*e[h]-w*t[h],c=u*t[h]+w*e[h];e[h]=e[i]-M,t[h]=t[i]-c,e[i]=e[i]+M,t[i]=t[i]+c;const m=u*l-w*s,p=u*s+w*l;u=m,w=p}}}}function C(e){const t=e.length;if(t<2||t&t-1)throw new Error("realFftMagnitudes: length must be a power of 2 >= 2");const r=new Float64Array(t),a=new Float64Array(t);for(let n=0;n<t;n+=1)r[n]=e[n];L(r,a);const o=new Float64Array(t>>1);for(let n=0;n<t>>1;n+=1)o[n]=Math.hypot(r[n],a[n]);return o}function k(e){const t=new Float64Array(e);if(e===1)return t[0]=1,t;const r=e-1;for(let a=0;a<e;a+=1)t[a]=.5*(1-Math.cos(2*Math.PI*a/r));return t}function S(e){const t=2**Math.round(Math.log2(e));return Math.min(8192,Math.max(32,t))}function b(e){const{numberOfChannels:t,length:r}=e;if(t===1)return e.getChannelData(0);const a=new Float32Array(r),o=1/t;for(let n=0;n<t;n+=1){const l=e.getChannelData(n);for(let s=0;s<r;s+=1)a[s]+=l[s]*o}return a}function B(e,t){if(t==="mix")return b(e);const r=Math.max(0,Math.min(e.numberOfChannels-1,t));return e.getChannelData(r)}function E(e,t,r){const a=[],o=e.length;if(o===0){for(let l=0;l<t;l+=1)a.push(Array.from({length:r},()=>0));return a}const n=o/t;for(let l=0;l<t;l+=1){const s=[],g=Math.floor(l*n),u=Math.floor((l+1)*n),f=Math.max(1,u-g)/r;for(let d=0;d<r;d+=1){const i=Math.floor(g+d*f),h=Math.min(u,Math.floor(g+(d+1)*f));let M=0;for(let c=i;c<h;c+=1)M=Math.max(M,Math.abs(e[c]??0));s.push(M)}a.push(s)}return a}function z(e,t,r,a){const o=[];let n=1e-12;const l=e.length,s=S(r),g=s>>1,u=Math.min(a,g),w=k(s);if(l<s){for(let f=0;f<t;f+=1)o.push(Array.from({length:u},()=>0));return{rows:o,maxMag:1}}for(let f=0;f<t;f+=1){const d=t<=1?0:Math.min(Math.floor(f*(l-s)/(t-1)),l-s),i=new Float64Array(s);for(let c=0;c<s;c+=1)i[c]=(e[d+c]??0)*(w[c]??0);const h=C(i),M=[];for(let c=0;c<u;c+=1){const m=h[c]??0;M.push(m),n=Math.max(n,m)}o.push(M)}return{rows:o,maxMag:n}}function A(e,t={}){const r=Math.max(1,t.timeSlices??128),a=Math.max(1,t.samplesPerSlice??8),o=!!t.spectrogram,n=t.fftSize??1024,l=Math.max(1,t.frequencyBins??256),s=t.channel??0,g=B(e,s),u=E(g,r,a),w={duration:e.duration,sampleRate:e.sampleRate,amplitudeGrid:u};if(o){const{rows:f,maxMag:d}=z(g,r,n,l),i=d>0?1/d:1;w.spectrogram=f.map(h=>h.map(M=>M*i))}return w}async function x(e,t={}){const r=await fetch(e);if(!r.ok)throw new Error(`Fetch failed: ${r.status} ${r.statusText}`);const a=await r.arrayBuffer(),o=window.AudioContext??window.webkitAudioContext;if(!o)throw new Error("Web Audio API is not available");const n=new o;try{const l=await n.decodeAudioData(a.slice(0));return A(l,t)}finally{await n.close()}}function P(e,t={}){const[r,a]=y.useState({data:null,isLoading:!1,error:null});return y.useEffect(()=>{if(!e){a({data:null,isLoading:!1,error:null});return}if(typeof window>"u"){a({data:null,isLoading:!1,error:null});return}let o=!1;return a(n=>({...n,isLoading:!0,error:null})),(async()=>{try{const n=await x(e,t);o||a({data:n,isLoading:!1,error:null})}catch(n){o||a({data:null,isLoading:!1,error:n instanceof Error?n.message:"Failed to analyze audio file"})}})(),()=>{o=!0}},[e,t.timeSlices,t.samplesPerSlice,t.spectrogram,t.fftSize,t.frequencyBins,t.channel]),r}exports.analyzeAudioBuffer=A;exports.analyzeAudioFile=x;exports.useAudioFileAnalysis=P;exports.useAudioPeaks=F;
2
2
  //# sourceMappingURL=index.cjs.map