@groovenet/player 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1,309 @@
1
+ import { spawn } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import { EventEmitter } from "node:events";
4
+ import { createConnection } from "node:net";
5
+ import { unlink } from "node:fs/promises";
6
+ import { tmpdir } from "node:os";
7
+ import { join } from "node:path";
8
+ import { PlayerError } from "./types.js";
9
+ /** mpv child process controlled through its line-delimited JSON IPC socket. */
10
+ export class MpvBackend extends EventEmitter {
11
+ process = null;
12
+ socket = null;
13
+ socketPath = join(tmpdir(), `gn-mpv-${process.pid}-${randomUUID().slice(0, 12)}.sock`);
14
+ buffer = "";
15
+ nextId = 1;
16
+ pending = new Map();
17
+ startup = null;
18
+ closing = false;
19
+ spawnError = null;
20
+ executable;
21
+ startupTimeoutMs;
22
+ commandTimeoutMs;
23
+ spawnProcess;
24
+ connectSocket;
25
+ duration = null;
26
+ constructor(options = {}) {
27
+ super();
28
+ this.executable = options.executable ?? "mpv";
29
+ this.startupTimeoutMs = options.startupTimeoutMs ?? 5000;
30
+ this.commandTimeoutMs = options.commandTimeoutMs ?? 5000;
31
+ this.spawnProcess = options.spawnProcess ?? ((executable, args) => spawn(executable, args, { stdio: "ignore" }));
32
+ this.connectSocket = options.connectSocket ?? createConnection;
33
+ this.insecureTls = options.insecureTls ?? false;
34
+ }
35
+ insecureTls;
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ on(event, listener) { return super.on(event, listener); }
38
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
+ off(event, listener) { return super.off(event, listener); }
40
+ async load(source) {
41
+ await this.ensureStarted();
42
+ if (source.headers && Object.keys(source.headers).length) {
43
+ const fields = Object.entries(source.headers).map(([name, value]) => `${name}: ${value}`);
44
+ await this.command("set_property", "http-header-fields", fields);
45
+ }
46
+ else {
47
+ await this.command("set_property", "http-header-fields", []);
48
+ }
49
+ await this.command("loadfile", source.url, "replace");
50
+ }
51
+ async pause(paused) {
52
+ await this.command("set_property", "pause", paused);
53
+ }
54
+ async seek(seconds) {
55
+ await this.command("seek", seconds, "absolute+exact");
56
+ }
57
+ async setVolume(volume) {
58
+ await this.command("set_property", "volume", volume);
59
+ }
60
+ async listDevices() {
61
+ await this.ensureStarted();
62
+ const result = await this.command("get_property", "audio-device-list");
63
+ if (!Array.isArray(result))
64
+ return [];
65
+ return result.flatMap((item) => {
66
+ if (!item || typeof item !== "object")
67
+ return [];
68
+ const device = item;
69
+ if (typeof device.name !== "string")
70
+ return [];
71
+ return [{
72
+ id: device.name,
73
+ name: typeof device.description === "string" ? device.description : device.name,
74
+ ...(typeof device.description === "string" ? { description: device.description } : {}),
75
+ }];
76
+ });
77
+ }
78
+ async setOutputDevice(deviceId) {
79
+ try {
80
+ await this.ensureStarted();
81
+ await this.command("set_property", "audio-device", deviceId);
82
+ }
83
+ catch (error) {
84
+ throw new PlayerError("DEVICE_UNAVAILABLE", `Could not select audio output “${deviceId}”. Check that the device is connected and visible to mpv.`, { cause: error });
85
+ }
86
+ }
87
+ async close() {
88
+ this.closing = true;
89
+ if (!this.process)
90
+ return;
91
+ try {
92
+ if (this.socket?.writable)
93
+ await this.command("quit");
94
+ }
95
+ catch {
96
+ // The process may already have exited; continue with forced cleanup below.
97
+ }
98
+ const child = this.process;
99
+ if (child.exitCode === null && child.signalCode === null) {
100
+ await Promise.race([
101
+ new Promise((resolve) => child.once("exit", () => resolve())),
102
+ new Promise((resolve) => setTimeout(resolve, 1000)),
103
+ ]);
104
+ if (child.exitCode === null && child.signalCode === null) {
105
+ child.kill("SIGTERM");
106
+ await Promise.race([
107
+ new Promise((resolve) => child.once("exit", () => resolve())),
108
+ new Promise((resolve) => setTimeout(resolve, 1000)),
109
+ ]);
110
+ if (child.exitCode === null && child.signalCode === null)
111
+ child.kill("SIGKILL");
112
+ }
113
+ }
114
+ this.socket?.destroy();
115
+ this.socket = null;
116
+ this.process = null;
117
+ try {
118
+ await unlink(this.socketPath);
119
+ }
120
+ catch { /* socket is already gone */ }
121
+ }
122
+ ensureStarted() {
123
+ if (this.startup)
124
+ return this.startup;
125
+ this.closing = false;
126
+ this.startup = this.startMpv().catch(async (error) => {
127
+ await this.cleanupAfterStartupFailure();
128
+ this.startup = null;
129
+ throw error;
130
+ });
131
+ return this.startup;
132
+ }
133
+ async startMpv() {
134
+ this.spawnError = null;
135
+ const args = ["--idle=yes", "--no-terminal", `--input-ipc-server=${this.socketPath}`];
136
+ if (this.insecureTls)
137
+ args.push("--tls-verify=no");
138
+ try {
139
+ this.process = this.spawnProcess(this.executable, args);
140
+ }
141
+ catch (error) {
142
+ throw new PlayerError("MPV_NOT_FOUND", "Could not start mpv. Install mpv and ensure it is on PATH.", { cause: error });
143
+ }
144
+ const child = this.process;
145
+ child.once("error", (error) => {
146
+ const wrapped = new PlayerError("MPV_NOT_FOUND", "Could not start mpv. Install mpv and ensure it is on PATH.", { cause: error });
147
+ this.spawnError = wrapped;
148
+ this.rejectPending(wrapped);
149
+ this.reportError(wrapped);
150
+ });
151
+ child.once("exit", (code, signal) => {
152
+ this.socket?.destroy();
153
+ this.socket = null;
154
+ this.rejectPending(new PlayerError("MPV_EXITED", `mpv exited unexpectedly (${signal ?? code ?? "unknown status"}).`));
155
+ if (!this.closing) {
156
+ this.startup = null;
157
+ this.reportError(new PlayerError("MPV_EXITED", `mpv exited unexpectedly (${signal ?? code ?? "unknown status"}).`));
158
+ }
159
+ });
160
+ const deadline = Date.now() + this.startupTimeoutMs;
161
+ while (Date.now() < deadline) {
162
+ if (this.spawnError)
163
+ throw this.spawnError;
164
+ if (child.exitCode !== null || child.signalCode !== null) {
165
+ throw new PlayerError("MPV_EXITED", "mpv exited while starting. Check the mpv installation and audio output configuration.");
166
+ }
167
+ try {
168
+ await this.connect();
169
+ if (this.spawnError)
170
+ throw this.spawnError;
171
+ await this.command("observe_property", 1, "time-pos");
172
+ if (this.spawnError)
173
+ throw this.spawnError;
174
+ await this.command("observe_property", 2, "duration");
175
+ if (this.spawnError)
176
+ throw this.spawnError;
177
+ return;
178
+ }
179
+ catch {
180
+ this.socket?.destroy();
181
+ this.socket = null;
182
+ await new Promise((resolve) => setTimeout(resolve, 40));
183
+ }
184
+ }
185
+ throw new PlayerError("MPV_IPC", "mpv started but its IPC socket did not become ready.");
186
+ }
187
+ connect() {
188
+ return new Promise((resolve, reject) => {
189
+ const socket = this.connectSocket(this.socketPath);
190
+ const failed = (error) => { socket.destroy(); reject(error); };
191
+ socket.once("error", failed);
192
+ socket.once("connect", () => {
193
+ socket.off("error", failed);
194
+ this.socket = socket;
195
+ socket.on("data", (chunk) => this.onData(chunk));
196
+ socket.on("error", (error) => this.rejectPending(new PlayerError("MPV_IPC", `mpv IPC connection failed: ${error.message}`, { cause: error })));
197
+ socket.on("close", () => this.rejectPending(new PlayerError("MPV_IPC", "mpv IPC connection closed.")));
198
+ resolve();
199
+ });
200
+ });
201
+ }
202
+ command(name, ...args) {
203
+ const socket = this.socket;
204
+ if (!socket?.writable)
205
+ return Promise.reject(new PlayerError("MPV_IPC", "mpv is not connected."));
206
+ const request_id = this.nextId++;
207
+ return new Promise((resolve, reject) => {
208
+ const timer = setTimeout(() => {
209
+ this.pending.delete(request_id);
210
+ reject(new PlayerError("MPV_IPC", `mpv did not answer the “${name}” command within ${this.commandTimeoutMs} ms.`));
211
+ }, this.commandTimeoutMs);
212
+ this.pending.set(request_id, { resolve, reject, timer });
213
+ socket.write(`${JSON.stringify({ command: [name, ...args], request_id })}\n`, (error) => {
214
+ if (error) {
215
+ const pending = this.pending.get(request_id);
216
+ this.pending.delete(request_id);
217
+ if (pending)
218
+ clearTimeout(pending.timer);
219
+ reject(new PlayerError("MPV_IPC", `Could not send command to mpv: ${error.message}`, { cause: error }));
220
+ }
221
+ });
222
+ });
223
+ }
224
+ onData(chunk) {
225
+ this.buffer += chunk.toString("utf8");
226
+ let newline;
227
+ while ((newline = this.buffer.indexOf("\n")) >= 0) {
228
+ const line = this.buffer.slice(0, newline);
229
+ this.buffer = this.buffer.slice(newline + 1);
230
+ let message;
231
+ try {
232
+ message = JSON.parse(line);
233
+ }
234
+ catch {
235
+ continue;
236
+ }
237
+ if (message.request_id !== undefined) {
238
+ const pending = this.pending.get(message.request_id);
239
+ if (!pending)
240
+ continue;
241
+ this.pending.delete(message.request_id);
242
+ clearTimeout(pending.timer);
243
+ if (message.error && message.error !== "success")
244
+ pending.reject(this.mapMpvError(message.error));
245
+ else
246
+ pending.resolve(message.data);
247
+ }
248
+ else {
249
+ this.onEvent(message);
250
+ }
251
+ }
252
+ }
253
+ onEvent(message) {
254
+ if (message.event === "property-change") {
255
+ const position = message.name === "time-pos" ? message.data : undefined;
256
+ if (message.name === "duration")
257
+ this.duration = typeof message.data === "number" ? message.data : null;
258
+ if (typeof position === "number") {
259
+ this.emit("position", position, this.duration);
260
+ }
261
+ }
262
+ else if (message.event === "end-file") {
263
+ const reason = message.reason;
264
+ if (reason === "eof")
265
+ this.emit("ended");
266
+ else if (reason === "error")
267
+ this.reportError(new PlayerError("STREAM_FAILED", "mpv could not read the audio stream. Check the server URL, API key, and downloaded audio."));
268
+ }
269
+ }
270
+ mapMpvError(error) {
271
+ if (error.includes("audio-device"))
272
+ return new PlayerError("DEVICE_UNAVAILABLE", `mpv could not select the audio device: ${error}. Check that it is connected.`);
273
+ return new PlayerError("MPV_IPC", `mpv command failed: ${error}`);
274
+ }
275
+ rejectPending(error) {
276
+ for (const pending of this.pending.values()) {
277
+ clearTimeout(pending.timer);
278
+ pending.reject(error);
279
+ }
280
+ this.pending.clear();
281
+ }
282
+ async cleanupAfterStartupFailure() {
283
+ this.closing = true;
284
+ this.socket?.destroy();
285
+ this.socket = null;
286
+ const child = this.process;
287
+ if (child && child.exitCode === null && child.signalCode === null) {
288
+ child.kill("SIGTERM");
289
+ await Promise.race([
290
+ new Promise((resolve) => child.once("exit", () => resolve())),
291
+ new Promise((resolve) => setTimeout(resolve, 1000)),
292
+ ]);
293
+ if (child.exitCode === null && child.signalCode === null)
294
+ child.kill("SIGKILL");
295
+ }
296
+ this.process = null;
297
+ try {
298
+ await unlink(this.socketPath);
299
+ }
300
+ catch { /* socket was never created or already removed */ }
301
+ }
302
+ reportError(error) {
303
+ // EventEmitter treats an unhandled `error` event as an exception. A backend
304
+ // can be used directly before a client subscribes, so report only to listeners.
305
+ if (this.listenerCount("error") > 0)
306
+ this.emit("error", error);
307
+ }
308
+ }
309
+ //# sourceMappingURL=mpvBackend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mpvBackend.js","sourceRoot":"","sources":["../src/mpvBackend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { TrackQueue } from "./queue.js";
3
+ import { TrackResolver } from "./resolver.js";
4
+ import type { PlaybackBackend, PlaybackSnapshot, QueueEntry } from "./types.js";
5
+ import { PlayerError, type AudioDevice } from "./types.js";
6
+ export interface PlayerCoreEvents {
7
+ change: (snapshot: PlaybackSnapshot) => void;
8
+ "track-started": (entry: QueueEntry) => void;
9
+ "track-ended": (entry: QueueEntry) => void;
10
+ "track-skipped": (entry: QueueEntry, error: PlayerError) => void;
11
+ }
12
+ export declare class PlayerCore extends EventEmitter {
13
+ private readonly backend;
14
+ private readonly resolver;
15
+ readonly queue: TrackQueue;
16
+ private current;
17
+ private status;
18
+ private position;
19
+ private duration;
20
+ private volume;
21
+ private error;
22
+ private currentIndex;
23
+ constructor(backend: PlaybackBackend, resolver: TrackResolver);
24
+ on(event: string | symbol, listener: (...args: any[]) => void): this;
25
+ on<E extends keyof PlayerCoreEvents>(event: E, listener: PlayerCoreEvents[E]): this;
26
+ off(event: string | symbol, listener: (...args: any[]) => void): this;
27
+ off<E extends keyof PlayerCoreEvents>(event: E, listener: PlayerCoreEvents[E]): this;
28
+ get snapshot(): PlaybackSnapshot;
29
+ add(tracks: Parameters<TrackQueue["add"]>[0], at?: number): QueueEntry[];
30
+ enqueueSearch(query: string, limit?: number): Promise<QueueEntry[]>;
31
+ enqueuePlaylist(playlistId: number | string): Promise<QueueEntry[]>;
32
+ remove(idOrIndex: string | number): QueueEntry | undefined;
33
+ move(from: number, to: number): void;
34
+ play(index?: number): Promise<void>;
35
+ pause(): Promise<void>;
36
+ resume(): Promise<void>;
37
+ next(): Promise<void>;
38
+ previous(): Promise<void>;
39
+ seek(seconds: number): Promise<void>;
40
+ setVolume(volume: number): Promise<void>;
41
+ listDevices(): Promise<AudioDevice[]>;
42
+ setOutputDevice(deviceId: string): Promise<void>;
43
+ close(): Promise<void>;
44
+ private playNextPlayable;
45
+ }
46
+ //# sourceMappingURL=player.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7C,eAAe,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,aAAa,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,eAAe,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAClE;AAED,qBAAa,UAAW,SAAQ,YAAY;IAWxC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,QAAQ,CAAC,KAAK,aAAoB;IAClC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,MAAM,CAAO;IACrB,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,YAAY,CAAM;gBAGP,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,aAAa;IAqB1C,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IACpE,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;IAKnF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IACrE,GAAG,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;IAIpF,IAAI,QAAQ,IAAI,gBAAgB,CAU/B;IAED,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAMlE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAI/D,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAIzE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS;IAM1D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAK9B,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAMvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAYzB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9C,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAI/B,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAUd,gBAAgB;CAe/B"}
@@ -0,0 +1,176 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { TrackQueue } from "./queue.js";
3
+ import { PlayerError } from "./types.js";
4
+ export class PlayerCore extends EventEmitter {
5
+ backend;
6
+ resolver;
7
+ queue = new TrackQueue();
8
+ current = null;
9
+ status = "stopped";
10
+ position = 0;
11
+ duration = null;
12
+ volume = 100;
13
+ error = null;
14
+ currentIndex = -1;
15
+ constructor(backend, resolver) {
16
+ super();
17
+ this.backend = backend;
18
+ this.resolver = resolver;
19
+ backend.on("position", (position, duration) => {
20
+ this.position = position;
21
+ this.duration = duration;
22
+ this.emit("change", this.snapshot);
23
+ });
24
+ backend.on("ended", () => {
25
+ if (this.current)
26
+ this.emit("track-ended", this.current);
27
+ void this.next().catch(() => { });
28
+ });
29
+ backend.on("error", (error) => {
30
+ this.status = "error";
31
+ this.error = error;
32
+ this.emit("change", this.snapshot);
33
+ });
34
+ }
35
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
+ on(event, listener) { return super.on(event, listener); }
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ off(event, listener) { return super.off(event, listener); }
39
+ get snapshot() {
40
+ return {
41
+ status: this.status,
42
+ current: this.current,
43
+ queue: this.queue.items,
44
+ position: this.position,
45
+ duration: this.duration,
46
+ volume: this.volume,
47
+ error: this.error,
48
+ };
49
+ }
50
+ add(tracks, at) {
51
+ const added = this.queue.add(tracks, at);
52
+ this.emit("change", this.snapshot);
53
+ return added;
54
+ }
55
+ async enqueueSearch(query, limit = 50) {
56
+ return this.add(await this.resolver.search(query, limit));
57
+ }
58
+ async enqueuePlaylist(playlistId) {
59
+ return this.add(await this.resolver.playlist(playlistId));
60
+ }
61
+ remove(idOrIndex) {
62
+ const removed = this.queue.remove(idOrIndex);
63
+ if (removed)
64
+ this.emit("change", this.snapshot);
65
+ return removed;
66
+ }
67
+ move(from, to) {
68
+ this.queue.move(from, to);
69
+ this.emit("change", this.snapshot);
70
+ }
71
+ async play(index) {
72
+ const currentIndex = this.current ? this.queue.items.findIndex((entry) => entry.id === this.current.id) : this.currentIndex;
73
+ const targetIndex = index ?? (currentIndex < 0 ? 0 : currentIndex);
74
+ const entry = this.queue.items[targetIndex];
75
+ if (!entry)
76
+ throw new PlayerError("INVALID_ARGUMENT", "The playback queue is empty or the index is out of range");
77
+ const source = this.resolver.source(entry.track);
78
+ if (!source) {
79
+ this.status = "error";
80
+ this.error = new PlayerError("NO_AUDIO", `No downloaded audio is available for “${entry.track.title}”. Skipping it.`);
81
+ this.emit("track-skipped", entry, this.error);
82
+ this.emit("change", this.snapshot);
83
+ await this.playNextPlayable(targetIndex + 1);
84
+ return;
85
+ }
86
+ this.status = "loading";
87
+ this.error = null;
88
+ this.current = entry;
89
+ this.currentIndex = targetIndex;
90
+ this.position = 0;
91
+ this.duration = null;
92
+ this.emit("change", this.snapshot);
93
+ try {
94
+ await this.backend.load(source);
95
+ this.status = "playing";
96
+ }
97
+ catch (error) {
98
+ this.status = "error";
99
+ this.error = error instanceof PlayerError ? error : new PlayerError("STREAM_FAILED", `Could not play “${entry.track.title}”: ${String(error)}`, { cause: error });
100
+ this.emit("change", this.snapshot);
101
+ throw this.error;
102
+ }
103
+ this.emit("track-started", entry);
104
+ this.emit("change", this.snapshot);
105
+ }
106
+ async pause() {
107
+ await this.backend.pause(true);
108
+ this.status = "paused";
109
+ this.emit("change", this.snapshot);
110
+ }
111
+ async resume() {
112
+ await this.backend.pause(false);
113
+ this.status = "playing";
114
+ this.emit("change", this.snapshot);
115
+ }
116
+ async next() {
117
+ const index = this.current ? this.queue.items.findIndex((entry) => entry.id === this.current.id) : this.currentIndex;
118
+ await this.playNextPlayable(index + 1);
119
+ }
120
+ async previous() {
121
+ if (!this.queue.length)
122
+ throw new PlayerError("INVALID_ARGUMENT", "The playback queue is empty");
123
+ const index = this.current ? this.queue.items.findIndex((entry) => entry.id === this.current.id) : this.currentIndex;
124
+ let target = Math.max(0, index - 1);
125
+ while (target >= 0 && !this.resolver.source(this.queue.items[target].track)) {
126
+ const skipped = this.queue.items[target];
127
+ this.emit("track-skipped", skipped, new PlayerError("NO_AUDIO", `No downloaded audio is available for “${skipped.track.title}”.`));
128
+ target--;
129
+ }
130
+ if (target >= 0)
131
+ await this.play(target);
132
+ }
133
+ async seek(seconds) {
134
+ if (!Number.isFinite(seconds) || seconds < 0)
135
+ throw new PlayerError("INVALID_ARGUMENT", "Seek position must be a non-negative number of seconds");
136
+ await this.backend.seek(seconds);
137
+ }
138
+ async setVolume(volume) {
139
+ if (!Number.isFinite(volume) || volume < 0 || volume > 100)
140
+ throw new PlayerError("INVALID_ARGUMENT", "Volume must be between 0 and 100");
141
+ await this.backend.setVolume(volume);
142
+ this.volume = volume;
143
+ this.emit("change", this.snapshot);
144
+ }
145
+ listDevices() {
146
+ return this.backend.listDevices();
147
+ }
148
+ async setOutputDevice(deviceId) {
149
+ await this.backend.setOutputDevice(deviceId);
150
+ }
151
+ async close() {
152
+ await this.backend.close();
153
+ this.status = "stopped";
154
+ this.current = null;
155
+ this.currentIndex = -1;
156
+ this.position = 0;
157
+ this.duration = null;
158
+ this.emit("change", this.snapshot);
159
+ }
160
+ async playNextPlayable(index) {
161
+ while (index < this.queue.length && !this.resolver.source(this.queue.items[index].track)) {
162
+ const skipped = this.queue.items[index];
163
+ this.emit("track-skipped", skipped, new PlayerError("NO_AUDIO", `No downloaded audio is available for “${skipped.track.title}”.`));
164
+ index++;
165
+ }
166
+ if (index >= this.queue.length) {
167
+ this.current = null;
168
+ this.currentIndex = -1;
169
+ this.status = "ended";
170
+ this.emit("change", this.snapshot);
171
+ return;
172
+ }
173
+ await this.play(index);
174
+ }
175
+ }
176
+ //# sourceMappingURL=player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.js","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { type Socket } from "node:net";
3
+ export declare const PLAYER_PROTOCOL_VERSION = 1;
4
+ export interface PlayerRpcRequest {
5
+ jsonrpc: "2.0";
6
+ version: number;
7
+ id: number;
8
+ method: string;
9
+ params?: Record<string, unknown>;
10
+ }
11
+ export interface PlayerRpcError {
12
+ code: string;
13
+ message: string;
14
+ }
15
+ export interface PlayerRpcResponse {
16
+ jsonrpc: "2.0";
17
+ version: number;
18
+ id: number;
19
+ result?: unknown;
20
+ error?: PlayerRpcError;
21
+ }
22
+ export interface PlayerRpcEvent {
23
+ jsonrpc: "2.0";
24
+ version: number;
25
+ event: string;
26
+ data: unknown;
27
+ }
28
+ export declare class PlayerProtocolError extends Error {
29
+ readonly code: string;
30
+ constructor(code: string, message: string);
31
+ }
32
+ export type PlayerSocketConnector = (path: string) => Socket;
33
+ export declare function encodeRpcRequest(id: number, method: string, params?: Record<string, unknown>): string;
34
+ export declare function encodeRpcResponse(response: Omit<PlayerRpcResponse, "jsonrpc">): string;
35
+ export declare function encodeRpcEvent(event: string, data: unknown): string;
36
+ export declare class PlayerControlClient extends EventEmitter {
37
+ private readonly socketPath;
38
+ private readonly timeoutMs;
39
+ private readonly connectSocket;
40
+ private socket;
41
+ private buffer;
42
+ private nextId;
43
+ private pending;
44
+ constructor(socketPath: string, timeoutMs?: number, connectSocket?: PlayerSocketConnector);
45
+ connect(): Promise<void>;
46
+ request<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
47
+ close(): Promise<void>;
48
+ private onData;
49
+ private rejectPending;
50
+ }
51
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAoB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAEzD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAInD;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAE7D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAQrG;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,GAAG,MAAM,CAEtF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAEnE;AAED,qBAAa,mBAAoB,SAAQ,YAAY;IAOjD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa;IARhC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAoH;gBAGhH,UAAU,EAAE,MAAM,EAClB,SAAS,SAAO,EAChB,aAAa,GAAE,qBAAwC;IAKpE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBxB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBlF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,OAAO,CAAC,MAAM;IAyBd,OAAO,CAAC,aAAa;CAOtB"}