@lucaismyname/ginger 0.0.32 → 0.0.35
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.
- package/README.md +105 -5
- package/dist/client.cjs +1 -1
- package/dist/client.js +2 -2
- package/dist/{ginger-L2ZFgzH4.js → ginger-DlCkxDXs.js} +38 -38
- package/dist/ginger-DlCkxDXs.js.map +1 -0
- package/dist/{ginger-NEcOSSJD.cjs → ginger-jToP7EpI.cjs} +2 -2
- package/dist/ginger-jToP7EpI.cjs.map +1 -0
- package/dist/hooks/useNextTrackPrefetch.d.ts +3 -0
- package/dist/hooks/useNextTrackPrefetch.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/remote/index.cjs +1 -1
- package/dist/remote/index.cjs.map +1 -1
- package/dist/remote/index.js +122 -103
- package/dist/remote/index.js.map +1 -1
- package/dist/remote/useGingerRemote.d.ts.map +1 -1
- package/dist/remote/useGingerRemote.test.d.ts +2 -0
- package/dist/remote/useGingerRemote.test.d.ts.map +1 -0
- package/dist/remote/validateGingerInitPayloadDev.d.ts +7 -0
- package/dist/remote/validateGingerInitPayloadDev.d.ts.map +1 -0
- package/dist/remote/validateGingerInitPayloadDev.test.d.ts +2 -0
- package/dist/remote/validateGingerInitPayloadDev.test.d.ts.map +1 -0
- package/dist/testing/index.cjs +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/{useGingerChapterProgress-BdaalJvX.cjs → useGingerChapterProgress-B2-J3dSP.cjs} +2 -2
- package/dist/useGingerChapterProgress-B2-J3dSP.cjs.map +1 -0
- package/dist/{useGingerChapterProgress-CZdv-HiI.js → useGingerChapterProgress-BW6v65wN.js} +2 -2
- package/dist/useGingerChapterProgress-BW6v65wN.js.map +1 -0
- package/dist/waveform/analyzeAudioFile.d.ts.map +1 -1
- package/dist/waveform/getAudioContextConstructor.d.ts +6 -0
- package/dist/waveform/getAudioContextConstructor.d.ts.map +1 -0
- package/dist/waveform/index.cjs +1 -1
- package/dist/waveform/index.cjs.map +1 -1
- package/dist/waveform/index.js +162 -153
- package/dist/waveform/index.js.map +1 -1
- package/dist/waveform/useAudioFileAnalysis.d.ts +1 -0
- package/dist/waveform/useAudioFileAnalysis.d.ts.map +1 -1
- package/dist/waveform/useAudioPeaks.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/ginger-L2ZFgzH4.js.map +0 -1
- package/dist/ginger-NEcOSSJD.cjs.map +0 -1
- package/dist/useGingerChapterProgress-BdaalJvX.cjs.map +0 -1
- package/dist/useGingerChapterProgress-CZdv-HiI.js.map +0 -1
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ Mount **`<Ginger.Player />`** once inside the same provider tree so the hidden a
|
|
|
56
56
|
- Streaming adapters: [`docs/guides/streaming-adapters.md`](./docs/guides/streaming-adapters.md)
|
|
57
57
|
- Components reference: [`docs/reference/components.md`](./docs/reference/components.md)
|
|
58
58
|
- Hooks reference: [`docs/reference/hooks.md`](./docs/reference/hooks.md)
|
|
59
|
-
- Subpath exports: [`docs/reference/subpaths.md`](./docs/reference/subpaths.md)
|
|
59
|
+
- Subpath exports (waveform, EQ, spatial, transcript, remote, …): [`docs/reference/subpaths.md`](./docs/reference/subpaths.md)
|
|
60
60
|
- Generated API docs: [`docs/api/index.html`](./docs/api/index.html)
|
|
61
61
|
|
|
62
62
|
## Subpath Exports
|
|
@@ -65,6 +65,9 @@ Mount **`<Ginger.Player />`** once inside the same provider tree so the hidden a
|
|
|
65
65
|
- `@lucaismyname/ginger/testing`
|
|
66
66
|
- `@lucaismyname/ginger/waveform`
|
|
67
67
|
- `@lucaismyname/ginger/equalizer`
|
|
68
|
+
- `@lucaismyname/ginger/spatial`
|
|
69
|
+
- `@lucaismyname/ginger/transcript`
|
|
70
|
+
- `@lucaismyname/ginger/remote`
|
|
68
71
|
- `@lucaismyname/ginger/experimental-gapless`
|
|
69
72
|
|
|
70
73
|
### Equalizer
|
|
@@ -105,6 +108,96 @@ function MyPlayer() {
|
|
|
105
108
|
|
|
106
109
|
The EQ and `useGingerLiveAnalyzer` share the same `AudioContext` and can be used together. EQ filters are inserted before the analyser in the Web Audio graph.
|
|
107
110
|
|
|
111
|
+
### Spatial audio (`@lucaismyname/ginger/spatial`)
|
|
112
|
+
|
|
113
|
+
Inserts an HRTF **`PannerNode`** into the same Web Audio graph as the EQ and live analyser (one `MediaElementAudioSourceNode` per `<audio>`).
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
import { useGingerSpatialAudio } from "@lucaismyname/ginger/spatial";
|
|
117
|
+
|
|
118
|
+
function Spatialized() {
|
|
119
|
+
const { setSourcePosition, error } = useGingerSpatialAudio({
|
|
120
|
+
panningModel: "HRTF",
|
|
121
|
+
position: [2, 0, 0],
|
|
122
|
+
listenerPosition: [0, 0, 0],
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<div>
|
|
127
|
+
<button type="button" onClick={() => setSourcePosition(0, 0, -2)}>
|
|
128
|
+
Move source
|
|
129
|
+
</button>
|
|
130
|
+
{error && <p>{error}</p>}
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Use **`setListenerPosition`** and **`setPanningModel`** for runtime updates without rebuilding the graph.
|
|
137
|
+
|
|
138
|
+
### Transcript (`@lucaismyname/ginger/transcript`)
|
|
139
|
+
|
|
140
|
+
Parse **SRT** and **WebVTT** captions and sync cues to playback time (podcasts, video-style transcripts). HTML tags in cue text are stripped.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import {
|
|
144
|
+
parseSrt,
|
|
145
|
+
parseVtt,
|
|
146
|
+
useGingerTranscriptSync,
|
|
147
|
+
} from "@lucaismyname/ginger/transcript";
|
|
148
|
+
|
|
149
|
+
const vtt = `WEBVTT
|
|
150
|
+
|
|
151
|
+
00:00:01.000 --> 00:00:04.000
|
|
152
|
+
Hello from VTT
|
|
153
|
+
`;
|
|
154
|
+
|
|
155
|
+
function TranscriptPanel() {
|
|
156
|
+
const { cues, activeCue, activeCues } = useGingerTranscriptSync({
|
|
157
|
+
transcript: vtt,
|
|
158
|
+
format: "auto",
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<div>
|
|
163
|
+
<p>Now: {activeCue?.text ?? "—"}</p>
|
|
164
|
+
<p>Overlapping: {activeCues.map((c) => c.text).join(" · ")}</p>
|
|
165
|
+
</div>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Or parse ahead of time:
|
|
170
|
+
const cuesFromSrt = parseSrt(srtString);
|
|
171
|
+
const cuesFromVtt = parseVtt(vttString);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**`useGingerTranscriptSync`** mirrors **`useGingerLyricsSync`** but uses cue **start/end** ranges and exposes **`activeCues`** for overlapping captions. **`parseTranscriptAuto`** chooses VTT when the string starts with `WEBVTT`, otherwise SRT.
|
|
175
|
+
|
|
176
|
+
### Multi-tab sync (`@lucaismyname/ginger/remote`)
|
|
177
|
+
|
|
178
|
+
Elects a **leader** tab via **`BroadcastChannel`** and pushes **`INIT`** snapshots to followers so queue and transport settings stay aligned. Mount **`Ginger.Player`** only on the leader so a single `<audio>` element plays.
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import { Ginger } from "@lucaismyname/ginger";
|
|
182
|
+
import { useGingerRemote } from "@lucaismyname/ginger/remote";
|
|
183
|
+
|
|
184
|
+
function RemoteAwarePlayer() {
|
|
185
|
+
const { isLeader, isPending, error } = useGingerRemote({
|
|
186
|
+
channelName: "my-app-ginger",
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<>
|
|
191
|
+
{error && <p role="alert">{error}</p>}
|
|
192
|
+
{isLeader && <Ginger.Player />}
|
|
193
|
+
{isPending && <p>Connecting to other tabs…</p>}
|
|
194
|
+
</>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Snapshots send the current queue order with **`isShuffled: false`** so followers do not re-randomize; the visible order matches the leader. **`claimLeadership()`** requests leadership (lexicographically smaller tab IDs win conflicts).
|
|
200
|
+
|
|
108
201
|
### Experimental Notice
|
|
109
202
|
|
|
110
203
|
`@lucaismyname/ginger/experimental-gapless` is intentionally non-production.
|
|
@@ -781,7 +874,11 @@ Example:
|
|
|
781
874
|
|
|
782
875
|
- **Buffered UI** — **`Ginger.Current.BufferRail`** shows load progress; **`Ginger.Current.TimeRail`** supports **`showBuffered`** to stack a buffered layer behind the played segment.
|
|
783
876
|
|
|
784
|
-
- **Audio analyzers** — Live Web Audio data for real-time visuals (**`useGingerLiveAnalyzer`**, main package), parametric EQ (**`useGingerEqualizer`**, `@lucaismyname/ginger/equalizer`), and whole-file grids for waveforms or spectrograms (**`useAudioFileAnalysis`** / **`analyzeAudioFile`**, `@lucaismyname/ginger/waveform`). See [Audio analyzers (visualizations)](#audio-analyzers-visualizations).
|
|
877
|
+
- **Audio analyzers** — Live Web Audio data for real-time visuals (**`useGingerLiveAnalyzer`**, main package), parametric EQ (**`useGingerEqualizer`**, `@lucaismyname/ginger/equalizer`), **spatial / HRTF panning** (**`useGingerSpatialAudio`**, `@lucaismyname/ginger/spatial`), and whole-file grids for waveforms or spectrograms (**`useAudioFileAnalysis`** / **`analyzeAudioFile`**, `@lucaismyname/ginger/waveform`). See [Audio analyzers (visualizations)](#audio-analyzers-visualizations).
|
|
878
|
+
|
|
879
|
+
- **Transcripts** — **SRT / WebVTT** parsing and sync (**`parseSrt`**, **`parseVtt`**, **`useGingerTranscriptSync`**, `@lucaismyname/ginger/transcript`); LRC / in-track lyrics remain **`useGingerLyricsSync`** and **`parseLrc()`** on the main package.
|
|
880
|
+
|
|
881
|
+
- **Multi-tab** — **`useGingerRemote`** (`@lucaismyname/ginger/remote`) coordinates playback state across browser tabs; see [Subpath exports](#subpath-exports).
|
|
785
882
|
|
|
786
883
|
Recipes below cover queue lifecycle and media edge cases.
|
|
787
884
|
|
|
@@ -1114,9 +1211,12 @@ Additional entrypoints:
|
|
|
1114
1211
|
- `@lucaismyname/ginger/client`
|
|
1115
1212
|
- `@lucaismyname/ginger/testing`
|
|
1116
1213
|
- `@lucaismyname/ginger/waveform`
|
|
1214
|
+
- `@lucaismyname/ginger/spatial`
|
|
1215
|
+
- `@lucaismyname/ginger/transcript`
|
|
1216
|
+
- `@lucaismyname/ginger/remote`
|
|
1117
1217
|
- `@lucaismyname/ginger/experimental-gapless`
|
|
1118
1218
|
|
|
1119
|
-
`experimental-gapless` is explicitly non-production and does not alter core playback.
|
|
1219
|
+
See [Subpath Exports](#subpath-exports) for **`spatial`**, **`transcript`**, and **`remote`** usage. `experimental-gapless` is explicitly non-production and does not alter core playback.
|
|
1120
1220
|
|
|
1121
1221
|
## Notes
|
|
1122
1222
|
|
|
@@ -1137,8 +1237,8 @@ See [Recipes — Updating the queue after mount](#updating-the-queue-after-mount
|
|
|
1137
1237
|
These priorities guide new work in the library; they are not a guarantee of shipping order.
|
|
1138
1238
|
|
|
1139
1239
|
1. **Music libraries and continuous listening** — Features that make track-to-track playback feel better come first: **next-track prefetch** (`useNextTrackPrefetch`), future gapless or crossfade (see `@lucaismyname/ginger/experimental-gapless`), and first-class **chapter** / **synced lyrics** UI (`Ginger.Current.Chapters`, `Ginger.Current.LyricsSynced`).
|
|
1140
|
-
2. **Podcasts and live-style streams** — **HLS / DASH** integration is emphasized when a concrete app needs it; the core package stays on native `<audio>` with optional adapters or documentation rather than hard dependencies.
|
|
1141
|
-
3. **Embedded or internal players** — **Accessibility**, persistence, and **testing** helpers are favored over heavier ecosystem integrations (Cast,
|
|
1240
|
+
2. **Podcasts and live-style streams** — **HLS / DASH** integration is emphasized when a concrete app needs it; the core package stays on native `<audio>` with optional adapters or documentation rather than hard dependencies. **SRT / WebVTT** transcripts are supported via `@lucaismyname/ginger/transcript`.
|
|
1241
|
+
3. **Embedded or internal players** — **Accessibility**, persistence, and **testing** helpers are favored over heavier ecosystem integrations (Cast, proprietary cast SDKs) unless there is a dedicated use case. **Multi-tab** web apps can use `@lucaismyname/ginger/remote` (BroadcastChannel) before reaching for OS-level remote playback.
|
|
1142
1242
|
|
|
1143
1243
|
## Monorepo Development
|
|
1144
1244
|
|
package/dist/client.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./ginger-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./ginger-jToP7EpI.cjs"),s=require("./useGinger-BXgia32v.cjs"),r=require("./useGingerChapterProgress-B2-J3dSP.cjs"),i=require("./liveAudioGraph-0cpHD_Ic.cjs"),n=require("./selectors-YXnP8Y8g.cjs"),a=require("./GingerSplitContexts-C7puo0M7.cjs");exports.Chapters=e.Chapters;exports.Ginger=e.Ginger;exports.LyricsSynced=e.LyricsSynced;exports.Pause=e.Pause;exports.Play=e.Play;exports.RepeatGlyph=e.RepeatGlyph;exports.ShuffleIcon=e.ShuffleIcon;exports.SkipBack=e.SkipBack;exports.SkipForward=e.SkipForward;exports.Volume2=e.Volume2;exports.VolumeX=e.VolumeX;exports.Wrapper=e.Wrapper;exports.clampPlaybackRate=e.clampPlaybackRate;exports.clampVolume=e.clampVolume;exports.defaultGingerLocale=e.defaultGingerLocale;exports.parseLrc=e.parseLrc;exports.useGingerChapters=e.useGingerChapters;exports.useGingerLocale=e.useGingerLocale;exports.useGingerLyricsSync=e.useGingerLyricsSync;exports.usePlayPauseBinding=e.usePlayPauseBinding;exports.useSeekBarBinding=e.useSeekBarBinding;exports.useVolumeSlider=e.useVolumeSlider;exports.useGinger=s.useGinger;exports.createGingerStore=r.createGingerStore;exports.useGingerChapterProgress=r.useGingerChapterProgress;exports.useGingerDebugLog=r.useGingerDebugLog;exports.useGingerKeyboardShortcuts=r.useGingerKeyboardShortcuts;exports.useGingerLiveAnalyzer=r.useGingerLiveAnalyzer;exports.useGingerPlaybackHistory=r.useGingerPlaybackHistory;exports.useGingerSleepTimer=r.useGingerSleepTimer;exports.useGingerVolumeFade=r.useGingerVolumeFade;exports.useNextTrackPrefetch=r.useNextTrackPrefetch;exports.useSeekDrag=r.useSeekDrag;exports.attachLiveAnalyser=i.attachLiveAnalyser;exports.detachLiveAnalyser=i.detachLiveAnalyser;exports.setProcessingChain=i.setProcessingChain;exports.derivePlaybackUiState=n.derivePlaybackUiState;exports.gingerStateFromContextValues=a.gingerStateFromContextValues;exports.gingerStateFromContexts=a.gingerStateFromContexts;exports.useGingerMedia=a.useGingerMedia;exports.useGingerPlayback=a.useGingerPlayback;exports.useGingerState=a.useGingerState;
|
|
2
2
|
//# sourceMappingURL=client.cjs.map
|
package/dist/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as s, G as r, L as i, P as t, a as u, R as n, S as o, b as g, c, V as l, d as p, W as G, e as m, f as y, g as S, p as d, u as f, h, i as P, j as k, k as L, l as b } from "./ginger-
|
|
1
|
+
import { C as s, G as r, L as i, P as t, a as u, R as n, S as o, b as g, c, V as l, d as p, W as G, e as m, f as y, g as S, p as d, u as f, h, i as P, j as k, k as L, l as b } from "./ginger-DlCkxDXs.js";
|
|
2
2
|
import { u as C } from "./useGinger-hpp2pAGY.js";
|
|
3
|
-
import { c as v, u as B, a as F, b as A, d as R, e as D, f as T, g as W, h as j, i as w } from "./useGingerChapterProgress-
|
|
3
|
+
import { c as v, u as B, a as F, b as A, d as R, e as D, f as T, g as W, h as j, i as w } from "./useGingerChapterProgress-BW6v65wN.js";
|
|
4
4
|
import { a as H, d as I, s as K } from "./liveAudioGraph-DvPaxBCP.js";
|
|
5
5
|
import { d as N } from "./selectors-BalBCc7X.js";
|
|
6
6
|
import { g as X, a as q, u as E, b as J, c as O } from "./GingerSplitContexts-BzBExb95.js";
|
|
@@ -31,14 +31,14 @@ function kn({
|
|
|
31
31
|
return I(), g.addEventListener("change", I), () => g.removeEventListener("change", I);
|
|
32
32
|
}, [n]);
|
|
33
33
|
const v = (g, I = !1) => {
|
|
34
|
-
const
|
|
34
|
+
const w = {
|
|
35
35
|
currentTime: g.currentTime,
|
|
36
36
|
duration: g.duration,
|
|
37
37
|
bufferedFraction: nr(g)
|
|
38
|
-
}, F = f.current, Z = T ? 0.5 : 0.25, ee = Math.abs(
|
|
39
|
-
!I && !ee || (f.current =
|
|
38
|
+
}, F = f.current, Z = T ? 0.5 : 0.25, ee = Math.abs(w.currentTime - F.currentTime) >= Z || Math.abs(w.duration - F.duration) >= 0.01 || Math.abs(w.bufferedFraction - F.bufferedFraction) >= 0.01;
|
|
39
|
+
!I && !ee || (f.current = w, o({
|
|
40
40
|
type: "MEDIA_TIME_UPDATE",
|
|
41
|
-
payload:
|
|
41
|
+
payload: w
|
|
42
42
|
}));
|
|
43
43
|
};
|
|
44
44
|
return E(() => {
|
|
@@ -522,10 +522,10 @@ function H(e, r) {
|
|
|
522
522
|
function j(e, r) {
|
|
523
523
|
return H(e, (t) => r(K(t)));
|
|
524
524
|
}
|
|
525
|
-
const An = j("Ginger.Current.Title", (e) => e == null ? void 0 : e.title), Sn = j("Ginger.Current.Artist", (e) => e == null ? void 0 : e.artist), Rn = H("Ginger.Current.Album", (e) => ln(e)),
|
|
525
|
+
const An = j("Ginger.Current.Title", (e) => e == null ? void 0 : e.title), Sn = j("Ginger.Current.Artist", (e) => e == null ? void 0 : e.artist), Rn = H("Ginger.Current.Album", (e) => ln(e)), wn = j(
|
|
526
526
|
"Ginger.Current.Description",
|
|
527
527
|
(e) => e == null ? void 0 : e.description
|
|
528
|
-
),
|
|
528
|
+
), Gn = H("Ginger.Current.Copyright", (e) => {
|
|
529
529
|
var t;
|
|
530
530
|
const r = K(e);
|
|
531
531
|
return (r == null ? void 0 : r.copyright) ?? ((t = e.playlistMeta) == null ? void 0 : t.copyright);
|
|
@@ -604,7 +604,7 @@ function Fn() {
|
|
|
604
604
|
activeLine: i >= 0 ? n[i] ?? null : null
|
|
605
605
|
};
|
|
606
606
|
}
|
|
607
|
-
function
|
|
607
|
+
function wr({
|
|
608
608
|
className: e,
|
|
609
609
|
style: r,
|
|
610
610
|
fallback: t,
|
|
@@ -661,7 +661,7 @@ function Gr({
|
|
|
661
661
|
}
|
|
662
662
|
);
|
|
663
663
|
}
|
|
664
|
-
|
|
664
|
+
wr.displayName = "Ginger.Current.LyricsSynced";
|
|
665
665
|
function Un() {
|
|
666
666
|
const { tracks: e, currentIndex: r } = N(), { currentTime: t, seek: a } = X(), n = A(() => {
|
|
667
667
|
var u;
|
|
@@ -682,7 +682,7 @@ function Un() {
|
|
|
682
682
|
}
|
|
683
683
|
};
|
|
684
684
|
}
|
|
685
|
-
function
|
|
685
|
+
function Gr({
|
|
686
686
|
className: e,
|
|
687
687
|
style: r,
|
|
688
688
|
fallback: t,
|
|
@@ -750,7 +750,7 @@ function wr({
|
|
|
750
750
|
}
|
|
751
751
|
);
|
|
752
752
|
}
|
|
753
|
-
|
|
753
|
+
Gr.displayName = "Ginger.Current.Chapters";
|
|
754
754
|
function Lr({
|
|
755
755
|
visible: e = !1,
|
|
756
756
|
className: r,
|
|
@@ -1314,7 +1314,7 @@ function zr({
|
|
|
1314
1314
|
const o = P(), u = (l = o.playlistMeta) == null ? void 0 : l.artworkUrl;
|
|
1315
1315
|
if (!u) {
|
|
1316
1316
|
const m = a ?? t ?? null;
|
|
1317
|
-
return m ? /* @__PURE__ */ c("span", { className: e, style: r, children: m }) : null;
|
|
1317
|
+
return m ? /* @__PURE__ */ c("span", { "data-ginger-component": "Artwork", className: e, style: r, children: m }) : null;
|
|
1318
1318
|
}
|
|
1319
1319
|
const d = ((f = o.playlistMeta) == null ? void 0 : f.title) ?? "Playlist artwork";
|
|
1320
1320
|
return /* @__PURE__ */ c(
|
|
@@ -1658,7 +1658,7 @@ function Xn({
|
|
|
1658
1658
|
onPlayBlocked: x,
|
|
1659
1659
|
persistence: g,
|
|
1660
1660
|
hydrateOnMount: I = !1,
|
|
1661
|
-
resumeOnTrackChange:
|
|
1661
|
+
resumeOnTrackChange: w = !1,
|
|
1662
1662
|
unstyled: F = !1,
|
|
1663
1663
|
asChild: Z = !1,
|
|
1664
1664
|
className: ee,
|
|
@@ -1831,7 +1831,7 @@ function Xn({
|
|
|
1831
1831
|
E(() => {
|
|
1832
1832
|
if (!(!g || !I))
|
|
1833
1833
|
try {
|
|
1834
|
-
const p = g.get("ginger:volume"), b = g.get("ginger:muted"), k = g.get("ginger:playbackRate"),
|
|
1834
|
+
const p = g.get("ginger:volume"), b = g.get("ginger:muted"), k = g.get("ginger:playbackRate"), G = g.get("ginger:repeatMode"), Ge = g.get("ginger:currentIndex"), D = De.current;
|
|
1835
1835
|
y({
|
|
1836
1836
|
type: "INIT",
|
|
1837
1837
|
payload: {
|
|
@@ -1840,8 +1840,8 @@ function Xn({
|
|
|
1840
1840
|
isPaused: D.isPaused,
|
|
1841
1841
|
isShuffled: D.isShuffled,
|
|
1842
1842
|
playbackMode: D.playbackMode,
|
|
1843
|
-
currentIndex: typeof
|
|
1844
|
-
repeatMode:
|
|
1843
|
+
currentIndex: typeof Ge == "number" ? Ge : D.currentIndex,
|
|
1844
|
+
repeatMode: G === "off" || G === "all" || G === "one" ? G : D.repeatMode,
|
|
1845
1845
|
volume: typeof p == "number" ? p : D.volume,
|
|
1846
1846
|
muted: typeof b == "boolean" ? b : D.muted,
|
|
1847
1847
|
playbackRate: typeof k == "number" ? k : D.playbackRate
|
|
@@ -1865,7 +1865,7 @@ function Xn({
|
|
|
1865
1865
|
s.repeatMode,
|
|
1866
1866
|
s.currentIndex
|
|
1867
1867
|
]), E(() => {
|
|
1868
|
-
if (!g || !
|
|
1868
|
+
if (!g || !w) return;
|
|
1869
1869
|
const p = s.tracks[s.currentIndex];
|
|
1870
1870
|
if (!p) return;
|
|
1871
1871
|
const b = `ginger:resume:${Ve(p)}`;
|
|
@@ -1875,19 +1875,19 @@ function Xn({
|
|
|
1875
1875
|
} catch (k) {
|
|
1876
1876
|
process.env.NODE_ENV !== "production" && console.warn("[@lucaismyname/ginger] persistence.get() threw during resume:", k);
|
|
1877
1877
|
}
|
|
1878
|
-
}, [g,
|
|
1879
|
-
if (!g || !
|
|
1878
|
+
}, [g, w, s.currentIndex, s.tracks, $]), E(() => {
|
|
1879
|
+
if (!g || !w) return;
|
|
1880
1880
|
const p = s.tracks[s.currentIndex];
|
|
1881
1881
|
if (!p || !(s.currentTime >= 0)) return;
|
|
1882
1882
|
const b = `ginger:resume:${Ve(p)}`, k = setTimeout(() => {
|
|
1883
1883
|
try {
|
|
1884
1884
|
g.set(b, s.currentTime);
|
|
1885
|
-
} catch (
|
|
1886
|
-
process.env.NODE_ENV !== "production" && console.warn("[@lucaismyname/ginger] persistence.set() threw during resume save:",
|
|
1885
|
+
} catch (G) {
|
|
1886
|
+
process.env.NODE_ENV !== "production" && console.warn("[@lucaismyname/ginger] persistence.set() threw during resume save:", G);
|
|
1887
1887
|
}
|
|
1888
1888
|
}, 250);
|
|
1889
1889
|
return () => clearTimeout(k);
|
|
1890
|
-
}, [g,
|
|
1890
|
+
}, [g, w, s.currentIndex, s.tracks, s.currentTime]);
|
|
1891
1891
|
const Kr = (Je = s.tracks[s.currentIndex]) == null ? void 0 : Je.fileUrl;
|
|
1892
1892
|
E(() => {
|
|
1893
1893
|
const p = V.current;
|
|
@@ -1902,9 +1902,9 @@ function Xn({
|
|
|
1902
1902
|
let k = !1;
|
|
1903
1903
|
try {
|
|
1904
1904
|
k = await v();
|
|
1905
|
-
} catch (
|
|
1906
|
-
const
|
|
1907
|
-
y({ type: "MEDIA_ERROR", payload: { message:
|
|
1905
|
+
} catch (G) {
|
|
1906
|
+
const Ge = G instanceof Error ? G.message : "beforePlay rejected";
|
|
1907
|
+
y({ type: "MEDIA_ERROR", payload: { message: Ge } });
|
|
1908
1908
|
return;
|
|
1909
1909
|
}
|
|
1910
1910
|
if (!k) {
|
|
@@ -1913,14 +1913,14 @@ function Xn({
|
|
|
1913
1913
|
}
|
|
1914
1914
|
}
|
|
1915
1915
|
b || p.play().catch((k) => {
|
|
1916
|
-
const
|
|
1917
|
-
y({ type: "MEDIA_ERROR", payload: { message:
|
|
1916
|
+
const G = k instanceof Error ? k.message : typeof k == "string" ? k : "Playback failed (e.g. autoplay blocked or unavailable source)";
|
|
1917
|
+
y({ type: "MEDIA_ERROR", payload: { message: G } });
|
|
1918
1918
|
});
|
|
1919
1919
|
})(), () => {
|
|
1920
1920
|
b = !0;
|
|
1921
1921
|
};
|
|
1922
1922
|
}, [v, Kr, x, s.isPaused]);
|
|
1923
|
-
const
|
|
1923
|
+
const we = M(() => {
|
|
1924
1924
|
const p = vn(ze.current);
|
|
1925
1925
|
if (p.kind === "replay_same") {
|
|
1926
1926
|
const k = V.current;
|
|
@@ -1943,7 +1943,7 @@ function Xn({
|
|
|
1943
1943
|
state: s,
|
|
1944
1944
|
dispatch: y,
|
|
1945
1945
|
audioRef: V,
|
|
1946
|
-
notifyEnded:
|
|
1946
|
+
notifyEnded: we,
|
|
1947
1947
|
init: Re,
|
|
1948
1948
|
play: B,
|
|
1949
1949
|
pause: O,
|
|
@@ -1973,7 +1973,7 @@ function Xn({
|
|
|
1973
1973
|
y,
|
|
1974
1974
|
Re,
|
|
1975
1975
|
z,
|
|
1976
|
-
|
|
1976
|
+
we,
|
|
1977
1977
|
O,
|
|
1978
1978
|
B,
|
|
1979
1979
|
Ee,
|
|
@@ -2071,7 +2071,7 @@ function Xn({
|
|
|
2071
2071
|
toggleMute: me,
|
|
2072
2072
|
setPlaybackRate: ye,
|
|
2073
2073
|
audioRef: V,
|
|
2074
|
-
notifyEnded:
|
|
2074
|
+
notifyEnded: we,
|
|
2075
2075
|
dispatch: y
|
|
2076
2076
|
}),
|
|
2077
2077
|
[
|
|
@@ -2089,7 +2089,7 @@ function Xn({
|
|
|
2089
2089
|
me,
|
|
2090
2090
|
ye,
|
|
2091
2091
|
V,
|
|
2092
|
-
|
|
2092
|
+
we,
|
|
2093
2093
|
y
|
|
2094
2094
|
]
|
|
2095
2095
|
), Ke = cr(s), qe = A(
|
|
@@ -2139,16 +2139,16 @@ const rt = {
|
|
|
2139
2139
|
Title: An,
|
|
2140
2140
|
Artist: Sn,
|
|
2141
2141
|
Album: Rn,
|
|
2142
|
-
Description:
|
|
2143
|
-
Copyright:
|
|
2142
|
+
Description: wn,
|
|
2143
|
+
Copyright: Gn,
|
|
2144
2144
|
Genre: Ln,
|
|
2145
2145
|
Label: Nn,
|
|
2146
2146
|
Isrc: _n,
|
|
2147
2147
|
TrackNumber: Dn,
|
|
2148
2148
|
Year: Sr,
|
|
2149
2149
|
Lyrics: Rr,
|
|
2150
|
-
LyricsSynced:
|
|
2151
|
-
Chapters:
|
|
2150
|
+
LyricsSynced: wr,
|
|
2151
|
+
Chapters: Gr,
|
|
2152
2152
|
FileUrl: Lr,
|
|
2153
2153
|
Artwork: Nr,
|
|
2154
2154
|
QueueIndex: _r,
|
|
@@ -2195,9 +2195,9 @@ const rt = {
|
|
|
2195
2195
|
Playlist: Bn
|
|
2196
2196
|
};
|
|
2197
2197
|
export {
|
|
2198
|
-
|
|
2198
|
+
Gr as C,
|
|
2199
2199
|
rt as G,
|
|
2200
|
-
|
|
2200
|
+
wr as L,
|
|
2201
2201
|
dr as P,
|
|
2202
2202
|
gr as R,
|
|
2203
2203
|
fr as S,
|
|
@@ -2220,4 +2220,4 @@ export {
|
|
|
2220
2220
|
Cn as p,
|
|
2221
2221
|
Un as u
|
|
2222
2222
|
};
|
|
2223
|
-
//# sourceMappingURL=ginger-
|
|
2223
|
+
//# sourceMappingURL=ginger-DlCkxDXs.js.map
|