@groovenet/player 0.1.2 → 0.1.4
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/MPRIS.md +97 -0
- package/OWNTONE.md +145 -0
- package/README.md +29 -0
- package/SERVER_PLAYERS.md +215 -0
- package/build/daemon.d.ts.map +1 -1
- package/build/daemon.js +42 -16
- package/build/daemon.js.map +1 -1
- package/build/index.d.ts +4 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -0
- package/build/index.js.map +1 -1
- package/build/mpris.d.ts +11 -0
- package/build/mpris.d.ts.map +1 -0
- package/build/mpris.js +145 -0
- package/build/mpris.js.map +1 -0
- package/build/mprisBin.d.ts +3 -0
- package/build/mprisBin.d.ts.map +1 -0
- package/build/mprisBin.js +26 -0
- package/build/mprisBin.js.map +1 -0
- package/build/mprisMapping.d.ts +12 -0
- package/build/mprisMapping.d.ts.map +1 -0
- package/build/mprisMapping.js +35 -0
- package/build/mprisMapping.js.map +1 -0
- package/build/mpvBackend.d.ts +3 -0
- package/build/mpvBackend.d.ts.map +1 -1
- package/build/mpvBackend.js +6 -0
- package/build/mpvBackend.js.map +1 -1
- package/build/ownToneBackend.d.ts +62 -0
- package/build/ownToneBackend.d.ts.map +1 -0
- package/build/ownToneBackend.js +349 -0
- package/build/ownToneBackend.js.map +1 -0
- package/build/paths.d.ts +4 -0
- package/build/paths.d.ts.map +1 -0
- package/build/paths.js +8 -0
- package/build/paths.js.map +1 -0
- package/build/playLogger.d.ts +39 -0
- package/build/playLogger.d.ts.map +1 -0
- package/build/playLogger.js +59 -0
- package/build/playLogger.js.map +1 -0
- package/build/playThreshold.d.ts +31 -0
- package/build/playThreshold.d.ts.map +1 -0
- package/build/playThreshold.js +40 -0
- package/build/playThreshold.js.map +1 -0
- package/build/player.d.ts +1 -0
- package/build/player.d.ts.map +1 -1
- package/build/player.js +11 -0
- package/build/player.js.map +1 -1
- package/build/protocol.d.ts.map +1 -1
- package/build/protocol.js +1 -0
- package/build/protocol.js.map +1 -1
- package/build/resolver.d.ts +3 -1
- package/build/resolver.d.ts.map +1 -1
- package/build/resolver.js +30 -1
- package/build/resolver.js.map +1 -1
- package/build/server/bin.d.ts +3 -0
- package/build/server/bin.d.ts.map +1 -0
- package/build/server/bin.js +7 -0
- package/build/server/bin.js.map +1 -0
- package/build/server/http.d.ts +5 -0
- package/build/server/http.d.ts.map +1 -0
- package/build/server/http.js +129 -0
- package/build/server/http.js.map +1 -0
- package/build/server/manager.d.ts +45 -0
- package/build/server/manager.d.ts.map +1 -0
- package/build/server/manager.js +423 -0
- package/build/server/manager.js.map +1 -0
- package/build/server/observer.d.ts +9 -0
- package/build/server/observer.d.ts.map +1 -0
- package/build/server/observer.js +29 -0
- package/build/server/observer.js.map +1 -0
- package/build/server/runtime.d.ts +16 -0
- package/build/server/runtime.d.ts.map +1 -0
- package/build/server/runtime.js +78 -0
- package/build/server/runtime.js.map +1 -0
- package/build/server/store.d.ts +33 -0
- package/build/server/store.d.ts.map +1 -0
- package/build/server/store.js +108 -0
- package/build/server/store.js.map +1 -0
- package/build/types.d.ts +3 -1
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/owntone/Dockerfile +27 -0
- package/owntone/smoke.mjs +135 -0
- package/owntone/terminal-v1.patch +96 -0
- package/package.json +24 -4
- package/scripts/mpris-smoke.mjs +54 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { posix } from "node:path";
|
|
4
|
+
import { PlayerError } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Single-output adapter for a dedicated OwnTone engine with terminal-v1.patch.
|
|
7
|
+
* Unpatched engines are refused; a stopped state alone never means EOF.
|
|
8
|
+
*/
|
|
9
|
+
export class OwnToneBackend extends EventEmitter {
|
|
10
|
+
apiUrl;
|
|
11
|
+
transport;
|
|
12
|
+
timeoutMs;
|
|
13
|
+
pollIntervalMs;
|
|
14
|
+
authorization;
|
|
15
|
+
outputId;
|
|
16
|
+
session = null;
|
|
17
|
+
finishedSession = null;
|
|
18
|
+
failedSession = null;
|
|
19
|
+
selected = false;
|
|
20
|
+
uncertain = false;
|
|
21
|
+
closed = false;
|
|
22
|
+
timer;
|
|
23
|
+
closing;
|
|
24
|
+
tail = Promise.resolve();
|
|
25
|
+
constructor(options) {
|
|
26
|
+
super();
|
|
27
|
+
try {
|
|
28
|
+
this.apiUrl = new URL(options.apiUrl.endsWith("/") ? options.apiUrl : `${options.apiUrl}/`);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
throw new PlayerError("INVALID_ARGUMENT", "OwnTone API URL must be an absolute HTTP(S) URL");
|
|
32
|
+
}
|
|
33
|
+
if (!["http:", "https:"].includes(this.apiUrl.protocol) || this.apiUrl.username || this.apiUrl.password || this.apiUrl.search || this.apiUrl.hash) {
|
|
34
|
+
throw new PlayerError("INVALID_ARGUMENT", "OwnTone API URL must use HTTP(S), without credentials, query or fragment");
|
|
35
|
+
}
|
|
36
|
+
this.transport = options.fetch ?? globalThis.fetch;
|
|
37
|
+
this.timeoutMs = options.timeoutMs ?? 5000;
|
|
38
|
+
this.pollIntervalMs = options.pollIntervalMs ?? 500;
|
|
39
|
+
if (![this.timeoutMs, this.pollIntervalMs].every((value) => Number.isFinite(value) && value > 0)) {
|
|
40
|
+
throw new PlayerError("INVALID_ARGUMENT", "OwnTone timeouts and polling interval must be positive");
|
|
41
|
+
}
|
|
42
|
+
this.authorization = options.password === undefined ? undefined : `Basic ${Buffer.from(`admin:${options.password}`).toString("base64")}`;
|
|
43
|
+
this.outputId = options.outputId;
|
|
44
|
+
}
|
|
45
|
+
// All commands and polls share a serial lane: no delayed response from an old
|
|
46
|
+
// load can emit an event for the next track, or race cleanup.
|
|
47
|
+
serial(operation) {
|
|
48
|
+
const result = this.tail.then(() => {
|
|
49
|
+
if (this.closed)
|
|
50
|
+
throw new PlayerError("ENGINE_UNAVAILABLE", "OwnTone backend is closed");
|
|
51
|
+
return operation();
|
|
52
|
+
});
|
|
53
|
+
this.tail = result.catch(() => { });
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
load(source) {
|
|
57
|
+
return this.serial(async () => {
|
|
58
|
+
// Only indexed files have verified finite-track semantics. In particular,
|
|
59
|
+
// never strip Authorization from an app HTTP URL and enqueue it as a stream.
|
|
60
|
+
let path;
|
|
61
|
+
try {
|
|
62
|
+
path = fileURLToPath(source.url);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
throw new PlayerError("STREAM_FAILED", "OwnTone requires a file URL in its indexed shared library; authenticated HTTP sources are not supported");
|
|
66
|
+
}
|
|
67
|
+
if (source.headers && Object.keys(source.headers).length) {
|
|
68
|
+
throw new PlayerError("STREAM_FAILED", "OwnTone indexed sources cannot include HTTP headers");
|
|
69
|
+
}
|
|
70
|
+
const params = new URLSearchParams({ directory: posix.dirname(path) });
|
|
71
|
+
const search = await this.request(`library/files?${params}`);
|
|
72
|
+
const tracks = search?.tracks?.items;
|
|
73
|
+
if (!Array.isArray(tracks) || tracks.some((track) => !track || typeof track.path !== "string"))
|
|
74
|
+
throw this.invalidResponse();
|
|
75
|
+
const matches = tracks.filter((track) => track.path === path && track.data_kind === "file" && Number.isSafeInteger(track.id) && track.id > 0 && track.length_ms > 0);
|
|
76
|
+
if (matches.length !== 1)
|
|
77
|
+
throw new PlayerError("NO_AUDIO", "Audio file is missing, ambiguous, or not yet indexed in OwnTone");
|
|
78
|
+
const status = await this.status();
|
|
79
|
+
if (status.state !== "stop" && (!this.session || !this.owns(status, await this.queue()))) {
|
|
80
|
+
throw new PlayerError("DEVICE_BUSY", "OwnTone has an unowned active or paused session; explicitly stop that engine before loading Groovenet audio");
|
|
81
|
+
}
|
|
82
|
+
if (!this.outputId)
|
|
83
|
+
throw new PlayerError("DEVICE_UNAVAILABLE", "Select one OwnTone output before playback");
|
|
84
|
+
// Device selection is an explicit load-time action, never a reconnect action.
|
|
85
|
+
await this.select(this.outputId);
|
|
86
|
+
this.session = null;
|
|
87
|
+
this.finishedSession = null;
|
|
88
|
+
this.failedSession = null;
|
|
89
|
+
this.cancelPoll();
|
|
90
|
+
await this.request("player/stop", "PUT");
|
|
91
|
+
await this.request("player/repeat?state=off", "PUT");
|
|
92
|
+
await this.request("player/consume?state=false", "PUT");
|
|
93
|
+
await this.request("player/shuffle?state=false", "PUT");
|
|
94
|
+
const queue = await this.request(`queue/items/add?${new URLSearchParams({ uris: `library:track:${matches[0].id}`, clear: "true" })}`, "POST");
|
|
95
|
+
this.validateQueue(queue);
|
|
96
|
+
if (queue.items.length !== 1)
|
|
97
|
+
throw new PlayerError("STREAM_FAILED", "OwnTone did not queue exactly one audio file");
|
|
98
|
+
this.session = { itemId: queue.items[0].id, queueVersion: queue.version, instance: status.groovenet_terminal.instance, sequence: status.groovenet_terminal.sequence };
|
|
99
|
+
try {
|
|
100
|
+
await this.request("player/play", "PUT");
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
// A lost reply can mean playback started. Keep the item identity for
|
|
104
|
+
// explicit close/reconciliation, without retrying the play command.
|
|
105
|
+
this.uncertain = true;
|
|
106
|
+
this.schedulePoll();
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
this.uncertain = false;
|
|
110
|
+
this.schedulePoll();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
pause(paused) {
|
|
114
|
+
return this.serial(async () => {
|
|
115
|
+
await this.assertOwned();
|
|
116
|
+
await this.request(`player/${paused ? "pause" : "play"}`, "PUT");
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
seek(seconds) {
|
|
120
|
+
return this.serial(async () => {
|
|
121
|
+
if (!Number.isFinite(seconds) || seconds < 0)
|
|
122
|
+
throw new PlayerError("INVALID_ARGUMENT", "Seek position must be non-negative seconds");
|
|
123
|
+
await this.assertOwned();
|
|
124
|
+
await this.request(`player/seek?position_ms=${Math.round(seconds * 1000)}`, "PUT");
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
setVolume(volume) {
|
|
128
|
+
return this.serial(async () => {
|
|
129
|
+
if (!Number.isFinite(volume) || volume < 0 || volume > 100)
|
|
130
|
+
throw new PlayerError("INVALID_ARGUMENT", "Volume must be between 0 and 100");
|
|
131
|
+
if (!this.outputId || !this.selected)
|
|
132
|
+
throw new PlayerError("DEVICE_UNAVAILABLE", "Select an OwnTone output before setting volume");
|
|
133
|
+
if (this.session)
|
|
134
|
+
await this.assertOwned();
|
|
135
|
+
if (!(await this.output(this.outputId)).selected)
|
|
136
|
+
throw new PlayerError("DEVICE_UNAVAILABLE", "OwnTone output was deselected");
|
|
137
|
+
await this.request(`outputs/${encodeURIComponent(this.outputId)}`, "PUT", { volume });
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
listDevices() {
|
|
141
|
+
return this.serial(async () => (await this.outputs()).map(({ id, name, type }) => ({ id, name, description: type })));
|
|
142
|
+
}
|
|
143
|
+
outputConnection() {
|
|
144
|
+
return this.serial(async () => {
|
|
145
|
+
if (!this.outputId)
|
|
146
|
+
return "unknown";
|
|
147
|
+
const output = (await this.outputs()).find((candidate) => candidate.id === this.outputId);
|
|
148
|
+
if (!output?.selected)
|
|
149
|
+
return "disconnected";
|
|
150
|
+
if (output.connected === undefined)
|
|
151
|
+
return "unknown";
|
|
152
|
+
return output.connected ? "connected" : "disconnected";
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
setOutputDevice(id) {
|
|
156
|
+
return this.serial(async () => {
|
|
157
|
+
const status = await this.status();
|
|
158
|
+
if (status.state !== "stop")
|
|
159
|
+
await this.assertOwned();
|
|
160
|
+
await this.select(id);
|
|
161
|
+
this.outputId = id;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
close() {
|
|
165
|
+
if (this.closing)
|
|
166
|
+
return this.closing;
|
|
167
|
+
this.closing = this.serial(async () => {
|
|
168
|
+
this.cancelPoll();
|
|
169
|
+
try {
|
|
170
|
+
if (this.session || this.finishedSession || this.failedSession || this.selected) {
|
|
171
|
+
const status = await this.status();
|
|
172
|
+
const queue = await this.queue();
|
|
173
|
+
const finished = this.finishedSession;
|
|
174
|
+
const completed = finished && status.state === "stop" && status.groovenet_terminal.instance === finished.instance && status.groovenet_terminal.item_id === finished.itemId && status.groovenet_terminal.reason === "eof" && (queue.items.length === 0 || (queue.version === finished.queueVersion && queue.items.length === 1 && queue.items[0].id === finished.itemId));
|
|
175
|
+
const stoppedOwned = this.session && status.state === "stop" && status.groovenet_terminal.instance === this.session.instance && queue.version === this.session.queueVersion && queue.items.length === 1 && queue.items[0].id === this.session.itemId;
|
|
176
|
+
const outputs = await this.outputs();
|
|
177
|
+
const foreignOutput = outputs.some((output) => output.selected && output.id !== this.outputId);
|
|
178
|
+
const failed = status.state !== "play" && this.matchesFailedSession(status, queue);
|
|
179
|
+
if (!foreignOutput && (this.owns(status, queue) || completed || stoppedOwned || failed || (!this.session && !finished && this.selected && status.state === "stop" && queue.items.length === 0))) {
|
|
180
|
+
await this.request("player/stop", "PUT");
|
|
181
|
+
await this.request("queue/clear", "PUT");
|
|
182
|
+
await this.request("outputs/set", "PUT", { outputs: [] });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
this.session = null;
|
|
188
|
+
this.failedSession = null;
|
|
189
|
+
this.selected = false;
|
|
190
|
+
this.closed = true;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
return this.closing;
|
|
194
|
+
}
|
|
195
|
+
async request(path, method = "GET", body) {
|
|
196
|
+
const signal = AbortSignal.timeout(this.timeoutMs);
|
|
197
|
+
try {
|
|
198
|
+
const response = await this.transport(new URL(path, this.apiUrl), {
|
|
199
|
+
method, signal, redirect: "error",
|
|
200
|
+
headers: { ...(this.authorization ? { Authorization: this.authorization } : {}), ...(body === undefined ? {} : { "Content-Type": "application/json" }) },
|
|
201
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
202
|
+
});
|
|
203
|
+
if (!response.ok) {
|
|
204
|
+
const code = response.status === 401 || response.status === 403 ? "ENGINE_AUTH" : response.status === 409 ? "DEVICE_BUSY" : "ENGINE_API";
|
|
205
|
+
// Do not include engine body, URL, password or source path in errors.
|
|
206
|
+
throw new PlayerError(code, `OwnTone API returned HTTP ${response.status}`);
|
|
207
|
+
}
|
|
208
|
+
if (response.status === 204)
|
|
209
|
+
return undefined;
|
|
210
|
+
return await response.json();
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
if (error instanceof PlayerError)
|
|
214
|
+
throw error;
|
|
215
|
+
throw new PlayerError(signal.aborted ? "ENGINE_TIMEOUT" : "ENGINE_UNAVAILABLE", signal.aborted ? "OwnTone API request timed out" : "OwnTone API is unreachable or returned invalid JSON");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
invalidResponse() { return new PlayerError("ENGINE_API", "OwnTone returned an invalid API response"); }
|
|
219
|
+
async status() {
|
|
220
|
+
const status = await this.request("player");
|
|
221
|
+
if (!status || !["play", "pause", "stop"].includes(status.state) || !Number.isSafeInteger(status.item_id) || !Number.isFinite(status.item_progress_ms) || !Number.isFinite(status.item_length_ms))
|
|
222
|
+
throw this.invalidResponse();
|
|
223
|
+
const terminal = status.groovenet_terminal;
|
|
224
|
+
if (!terminal || terminal.version !== 1 || !/^[a-f0-9]{32}$/.test(terminal.instance) || !Number.isSafeInteger(terminal.sequence) || terminal.sequence < 0 || !Number.isSafeInteger(terminal.item_id) || !["none", "eof", "input_error", "failed", "output_lost", "interrupted"].includes(terminal.reason)) {
|
|
225
|
+
throw new PlayerError("ENGINE_INCOMPATIBLE", "OwnTone requires the Groovenet terminal-v1 extension for reliable completion events");
|
|
226
|
+
}
|
|
227
|
+
return status;
|
|
228
|
+
}
|
|
229
|
+
validateQueue(queue) {
|
|
230
|
+
if (!queue || !Number.isSafeInteger(queue.version) || !Array.isArray(queue.items) || queue.items.some((item) => !item || !Number.isSafeInteger(item.id)))
|
|
231
|
+
throw this.invalidResponse();
|
|
232
|
+
}
|
|
233
|
+
async queue() {
|
|
234
|
+
const queue = await this.request("queue");
|
|
235
|
+
this.validateQueue(queue);
|
|
236
|
+
return queue;
|
|
237
|
+
}
|
|
238
|
+
async outputs() {
|
|
239
|
+
const result = await this.request("outputs");
|
|
240
|
+
if (!Array.isArray(result?.outputs) || result.outputs.some((output) => !output || typeof output.id !== "string" || typeof output.name !== "string" || typeof output.selected !== "boolean" || typeof output.type !== "string"))
|
|
241
|
+
throw this.invalidResponse();
|
|
242
|
+
return result.outputs;
|
|
243
|
+
}
|
|
244
|
+
async output(id) {
|
|
245
|
+
const output = (await this.outputs()).find((output) => output.id === id);
|
|
246
|
+
if (!output)
|
|
247
|
+
throw new PlayerError("DEVICE_UNAVAILABLE", "OwnTone output is unavailable");
|
|
248
|
+
if (output.busy || output.prevent_playback)
|
|
249
|
+
throw new PlayerError("DEVICE_BUSY", "OwnTone output is busy");
|
|
250
|
+
if (output.requires_auth || output.needs_auth_key)
|
|
251
|
+
throw new PlayerError("DEVICE_AUTH", "Authorize this output in OwnTone before using it");
|
|
252
|
+
return output;
|
|
253
|
+
}
|
|
254
|
+
async select(id) {
|
|
255
|
+
if (!id)
|
|
256
|
+
throw new PlayerError("INVALID_ARGUMENT", "OwnTone output ID must not be empty");
|
|
257
|
+
await this.output(id);
|
|
258
|
+
this.selected = false;
|
|
259
|
+
await this.request("outputs/set", "PUT", { outputs: [id] });
|
|
260
|
+
const outputs = await this.outputs();
|
|
261
|
+
if (outputs.filter((output) => output.selected).length !== 1 || !outputs.some((output) => output.id === id && output.selected)) {
|
|
262
|
+
throw new PlayerError("DEVICE_UNAVAILABLE", "OwnTone could not select the requested single output");
|
|
263
|
+
}
|
|
264
|
+
this.selected = true;
|
|
265
|
+
}
|
|
266
|
+
owns(status, queue) {
|
|
267
|
+
return this.session !== null && status.groovenet_terminal.instance === this.session.instance && !this.terminalForSession(status) && status.state !== "stop" && status.item_id === this.session.itemId && queue.version === this.session.queueVersion && queue.items.length === 1 && queue.items[0].id === this.session.itemId;
|
|
268
|
+
}
|
|
269
|
+
terminalForSession(status) {
|
|
270
|
+
return this.session !== null && status.groovenet_terminal.instance === this.session.instance && status.groovenet_terminal.sequence > this.session.sequence && status.groovenet_terminal.item_id === this.session.itemId;
|
|
271
|
+
}
|
|
272
|
+
/** Retain cleanup identity only for a terminal failure of our unchanged item.
|
|
273
|
+
* Polls never reconnect or replay. close() rechecks this identity before writes.
|
|
274
|
+
*/
|
|
275
|
+
rememberFailure(status, queue) {
|
|
276
|
+
if (this.session && this.terminalForSession(status) && ["output_lost", "input_error", "failed"].includes(status.groovenet_terminal.reason)) {
|
|
277
|
+
this.failedSession = { ...this.session, terminalSequence: status.groovenet_terminal.sequence, terminalReason: status.groovenet_terminal.reason };
|
|
278
|
+
if (!this.matchesFailedSession(status, queue))
|
|
279
|
+
this.failedSession = null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
matchesFailedSession(status, queue) {
|
|
283
|
+
const failed = this.failedSession;
|
|
284
|
+
return failed !== null && status.groovenet_terminal.instance === failed.instance
|
|
285
|
+
&& status.item_id === failed.itemId && status.groovenet_terminal.item_id === failed.itemId
|
|
286
|
+
&& status.groovenet_terminal.sequence === failed.terminalSequence && status.groovenet_terminal.reason === failed.terminalReason
|
|
287
|
+
&& queue.version === failed.queueVersion && queue.items.length === 1 && queue.items[0].id === failed.itemId;
|
|
288
|
+
}
|
|
289
|
+
async assertOwned() {
|
|
290
|
+
const status = await this.status();
|
|
291
|
+
const queue = await this.queue();
|
|
292
|
+
if (!this.owns(status, queue)) {
|
|
293
|
+
this.rememberFailure(status, queue);
|
|
294
|
+
this.session = null;
|
|
295
|
+
throw new PlayerError("PLAYBACK_INTERRUPTED", "OwnTone playback stopped or was replaced; explicitly play again to start a session");
|
|
296
|
+
}
|
|
297
|
+
return status;
|
|
298
|
+
}
|
|
299
|
+
schedulePoll() {
|
|
300
|
+
this.timer = setTimeout(() => {
|
|
301
|
+
void this.serial(async () => {
|
|
302
|
+
if (!this.session)
|
|
303
|
+
return;
|
|
304
|
+
try {
|
|
305
|
+
const status = await this.status();
|
|
306
|
+
const queue = await this.queue();
|
|
307
|
+
if (!this.uncertain && this.terminalForSession(status) && status.groovenet_terminal.reason === "eof" && status.state === "stop" && (queue.items.length === 0 || (queue.version === this.session.queueVersion && queue.items.length === 1 && queue.items[0].id === this.session.itemId))) {
|
|
308
|
+
this.finishedSession = this.session;
|
|
309
|
+
this.session = null;
|
|
310
|
+
this.emit("ended");
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (!this.owns(status, queue)) {
|
|
314
|
+
this.rememberFailure(status, queue);
|
|
315
|
+
const reason = status.groovenet_terminal.instance !== this.session.instance ? "engine restarted" : this.terminalForSession(status) ? status.groovenet_terminal.reason : status.state === "stop" ? "stopped" : queue.version !== this.session.queueVersion ? "queue changed" : "item replaced";
|
|
316
|
+
throw new PlayerError("PLAYBACK_INTERRUPTED", `OwnTone playback interrupted (${reason}); the queue has not advanced. Check the engine/receiver, then explicitly play again when ready.`);
|
|
317
|
+
}
|
|
318
|
+
const outputs = await this.outputs();
|
|
319
|
+
const output = outputs.find((output) => output.id === this.outputId);
|
|
320
|
+
if (outputs.filter((output) => output.selected).length !== 1 || !output?.selected)
|
|
321
|
+
throw new PlayerError("DEVICE_UNAVAILABLE", "OwnTone output was disconnected or deselected");
|
|
322
|
+
this.uncertain = false;
|
|
323
|
+
this.emit("position", Math.max(0, status.item_progress_ms) / 1000, status.item_length_ms > 0 ? status.item_length_ms / 1000 : null);
|
|
324
|
+
this.schedulePoll();
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
if (error instanceof PlayerError && (error.code === "ENGINE_UNAVAILABLE" || error.code === "ENGINE_TIMEOUT")) {
|
|
328
|
+
// Reconcile using reads only. Never infer EOF across a connection gap.
|
|
329
|
+
if (!this.uncertain)
|
|
330
|
+
this.emit("error", error);
|
|
331
|
+
this.uncertain = true;
|
|
332
|
+
this.schedulePoll();
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
this.session = null;
|
|
336
|
+
this.selected = false;
|
|
337
|
+
this.emit("error", error);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}).catch(() => { });
|
|
341
|
+
}, this.pollIntervalMs);
|
|
342
|
+
this.timer.unref();
|
|
343
|
+
}
|
|
344
|
+
cancelPoll() {
|
|
345
|
+
clearTimeout(this.timer);
|
|
346
|
+
this.timer = undefined;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
//# sourceMappingURL=ownToneBackend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownToneBackend.js","sourceRoot":"","sources":["../src/ownToneBackend.ts"],"names":[],"mappings":"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"}
|
package/build/paths.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,MAAkB,GAAG,iBAAiB,CAG9E"}
|
package/build/paths.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/** Where the daemon's control socket and pidfile live: `~/.groovenet/player/`. */
|
|
4
|
+
export function defaultPlayerPaths(home = homedir()) {
|
|
5
|
+
const dir = join(home, ".groovenet", "player");
|
|
6
|
+
return { socketPath: join(dir, "player.sock"), pidPath: join(dir, "player.pid") };
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,kFAAkF;AAClF,MAAM,UAAU,kBAAkB,CAAC,IAAI,GAAW,OAAO,EAAE;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC/C,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Track } from "@groovenet/client";
|
|
2
|
+
import type { PlaybackSnapshot, QueueEntry } from "./types.js";
|
|
3
|
+
/** The slice of PlayerCore the logger listens to, so tests need no player. */
|
|
4
|
+
export interface PlayEventSource {
|
|
5
|
+
on(event: "change", listener: (snapshot: PlaybackSnapshot) => void): unknown;
|
|
6
|
+
on(event: "track-started" | "track-ended", listener: (entry: QueueEntry) => void): unknown;
|
|
7
|
+
off(event: "change", listener: (snapshot: PlaybackSnapshot) => void): unknown;
|
|
8
|
+
off(event: "track-started" | "track-ended", listener: (entry: QueueEntry) => void): unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface LoggedPlay {
|
|
11
|
+
track: Track;
|
|
12
|
+
startedAt: Date;
|
|
13
|
+
listened: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PlayLoggerOptions {
|
|
16
|
+
source: PlayEventSource;
|
|
17
|
+
/** Records one play. Resolve for "logged" or "already logged"; reject to retry later. */
|
|
18
|
+
logPlay: (play: LoggedPlay) => Promise<void>;
|
|
19
|
+
/** Only this library's tracks are logged; the API rejects another owner's. */
|
|
20
|
+
friendId: number;
|
|
21
|
+
now?: () => Date;
|
|
22
|
+
onError?: (error: unknown, play: LoggedPlay) => void;
|
|
23
|
+
retryDelayMs?: number;
|
|
24
|
+
}
|
|
25
|
+
/** Logs a play when a track has been listened to long enough (see playThreshold). */
|
|
26
|
+
export declare class PlayLogger {
|
|
27
|
+
private readonly options;
|
|
28
|
+
private tracked;
|
|
29
|
+
private readonly now;
|
|
30
|
+
private readonly retryDelayMs;
|
|
31
|
+
private readonly onStart;
|
|
32
|
+
private readonly onChange;
|
|
33
|
+
private readonly onEnd;
|
|
34
|
+
constructor(options: PlayLoggerOptions);
|
|
35
|
+
start(): void;
|
|
36
|
+
stop(): void;
|
|
37
|
+
private maybeLog;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=playLogger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playLogger.d.ts","sourceRoot":"","sources":["../src/playLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE/D,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC;IAC7E,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC;IAC3F,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC;IAC9E,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC;CAC7F;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,yFAAyF;IACzF,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAYD,qFAAqF;AACrF,qBAAa,UAAU;IAwBT,OAAO,CAAC,QAAQ,CAAC,OAAO;IAvBpC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;IAEF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAMvB;IAEF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAKpB;IAEF,YAA6B,OAAO,EAAE,iBAAiB,EAGtD;IAED,KAAK,IAAI,IAAI,CAIZ;IAED,IAAI,IAAI,IAAI,CAKX;IAED,OAAO,CAAC,QAAQ;CAiBjB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { advanceProgress, initialProgress, isPlay } from "./playThreshold.js";
|
|
2
|
+
/** Logs a play when a track has been listened to long enough (see playThreshold). */
|
|
3
|
+
export class PlayLogger {
|
|
4
|
+
options;
|
|
5
|
+
tracked = null;
|
|
6
|
+
now;
|
|
7
|
+
retryDelayMs;
|
|
8
|
+
onStart = (entry) => {
|
|
9
|
+
this.tracked = { entry, startedAt: this.now(), progress: initialProgress, duration: null, claimed: false, retryAt: 0 };
|
|
10
|
+
};
|
|
11
|
+
onChange = (snapshot) => {
|
|
12
|
+
const tracked = this.tracked;
|
|
13
|
+
if (!tracked || snapshot.current?.id !== tracked.entry.id)
|
|
14
|
+
return;
|
|
15
|
+
tracked.duration = snapshot.duration;
|
|
16
|
+
tracked.progress = advanceProgress(tracked.progress, snapshot.position, snapshot.status === "playing");
|
|
17
|
+
this.maybeLog(tracked);
|
|
18
|
+
};
|
|
19
|
+
onEnd = (entry) => {
|
|
20
|
+
if (this.tracked?.entry.id === entry.id) {
|
|
21
|
+
this.maybeLog(this.tracked);
|
|
22
|
+
this.tracked = null;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.options = options;
|
|
27
|
+
this.now = options.now ?? (() => new Date());
|
|
28
|
+
this.retryDelayMs = options.retryDelayMs ?? 30_000;
|
|
29
|
+
}
|
|
30
|
+
start() {
|
|
31
|
+
this.options.source.on("track-started", this.onStart);
|
|
32
|
+
this.options.source.on("change", this.onChange);
|
|
33
|
+
this.options.source.on("track-ended", this.onEnd);
|
|
34
|
+
}
|
|
35
|
+
stop() {
|
|
36
|
+
this.options.source.off("track-started", this.onStart);
|
|
37
|
+
this.options.source.off("change", this.onChange);
|
|
38
|
+
this.options.source.off("track-ended", this.onEnd);
|
|
39
|
+
this.tracked = null;
|
|
40
|
+
}
|
|
41
|
+
maybeLog(tracked) {
|
|
42
|
+
const { track } = tracked.entry;
|
|
43
|
+
if (tracked.claimed || !isPlay(tracked.progress.listened, tracked.duration))
|
|
44
|
+
return;
|
|
45
|
+
if (!track.release_id || track.friend_id !== this.options.friendId)
|
|
46
|
+
return;
|
|
47
|
+
if (this.now().getTime() < tracked.retryAt)
|
|
48
|
+
return;
|
|
49
|
+
// `claimed` makes repeated events harmless; the API's unique index covers a restart.
|
|
50
|
+
tracked.claimed = true;
|
|
51
|
+
const play = { track, startedAt: tracked.startedAt, listened: tracked.progress.listened };
|
|
52
|
+
void this.options.logPlay(play).then(() => undefined, (error) => {
|
|
53
|
+
tracked.claimed = false;
|
|
54
|
+
tracked.retryAt = this.now().getTime() + this.retryDelayMs;
|
|
55
|
+
this.options.onError?.(error, play);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=playLogger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playLogger.js","sourceRoot":"","sources":["../src/playLogger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** A track shorter than this is never a play. */
|
|
2
|
+
export declare const MIN_TRACK_SECONDS = 30;
|
|
3
|
+
/** Half of the track, or this many seconds, whichever comes first. */
|
|
4
|
+
export declare const MAX_THRESHOLD_SECONDS = 240;
|
|
5
|
+
export declare const THRESHOLD_FRACTION = 0.5;
|
|
6
|
+
/**
|
|
7
|
+
* The largest forward jump between two position updates that still counts as
|
|
8
|
+
* listening. mpv reports about once a second, so anything bigger is a seek.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MAX_STEP_SECONDS = 5;
|
|
11
|
+
export interface ListenProgress {
|
|
12
|
+
/** Seconds actually played, excluding pauses and seeks. */
|
|
13
|
+
listened: number;
|
|
14
|
+
/** The last position seen, or null before the first update. */
|
|
15
|
+
lastPosition: number | null;
|
|
16
|
+
}
|
|
17
|
+
export declare const initialProgress: ListenProgress;
|
|
18
|
+
/**
|
|
19
|
+
* Seconds of play time that make a play, or null when the track can never be
|
|
20
|
+
* one. An unknown duration is judged by the absolute limit alone.
|
|
21
|
+
*/
|
|
22
|
+
export declare function playThreshold(duration: number | null): number | null;
|
|
23
|
+
/**
|
|
24
|
+
* Fold one position update into the running total. Only forward progress while
|
|
25
|
+
* playing counts: a pause adds nothing, and a backward or oversized jump is a
|
|
26
|
+
* seek, which moves the reference point without adding listening time.
|
|
27
|
+
*/
|
|
28
|
+
export declare function advanceProgress(progress: ListenProgress, position: number, playing: boolean, maxStep?: number): ListenProgress;
|
|
29
|
+
/** Whether `listened` seconds of a track of this duration is a play. */
|
|
30
|
+
export declare function isPlay(listened: number, duration: number | null): boolean;
|
|
31
|
+
//# sourceMappingURL=playThreshold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playThreshold.d.ts","sourceRoot":"","sources":["../src/playThreshold.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC;;;GAGG;AACH,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,eAAO,MAAM,eAAe,EAAE,cAAiD,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAIpE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,MAAyB,GACjC,cAAc,CAKhB;AAED,wEAAwE;AACxE,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAGzE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** A track shorter than this is never a play. */
|
|
2
|
+
export const MIN_TRACK_SECONDS = 30;
|
|
3
|
+
/** Half of the track, or this many seconds, whichever comes first. */
|
|
4
|
+
export const MAX_THRESHOLD_SECONDS = 240;
|
|
5
|
+
export const THRESHOLD_FRACTION = 0.5;
|
|
6
|
+
/**
|
|
7
|
+
* The largest forward jump between two position updates that still counts as
|
|
8
|
+
* listening. mpv reports about once a second, so anything bigger is a seek.
|
|
9
|
+
*/
|
|
10
|
+
export const MAX_STEP_SECONDS = 5;
|
|
11
|
+
export const initialProgress = { listened: 0, lastPosition: 0 };
|
|
12
|
+
/**
|
|
13
|
+
* Seconds of play time that make a play, or null when the track can never be
|
|
14
|
+
* one. An unknown duration is judged by the absolute limit alone.
|
|
15
|
+
*/
|
|
16
|
+
export function playThreshold(duration) {
|
|
17
|
+
if (duration === null)
|
|
18
|
+
return MAX_THRESHOLD_SECONDS;
|
|
19
|
+
if (!Number.isFinite(duration) || duration < MIN_TRACK_SECONDS)
|
|
20
|
+
return null;
|
|
21
|
+
return Math.min(duration * THRESHOLD_FRACTION, MAX_THRESHOLD_SECONDS);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Fold one position update into the running total. Only forward progress while
|
|
25
|
+
* playing counts: a pause adds nothing, and a backward or oversized jump is a
|
|
26
|
+
* seek, which moves the reference point without adding listening time.
|
|
27
|
+
*/
|
|
28
|
+
export function advanceProgress(progress, position, playing, maxStep = MAX_STEP_SECONDS) {
|
|
29
|
+
if (!Number.isFinite(position))
|
|
30
|
+
return progress;
|
|
31
|
+
const delta = progress.lastPosition === null ? 0 : position - progress.lastPosition;
|
|
32
|
+
const counted = playing && delta > 0 && delta <= maxStep ? delta : 0;
|
|
33
|
+
return { listened: progress.listened + counted, lastPosition: position };
|
|
34
|
+
}
|
|
35
|
+
/** Whether `listened` seconds of a track of this duration is a play. */
|
|
36
|
+
export function isPlay(listened, duration) {
|
|
37
|
+
const threshold = playThreshold(duration);
|
|
38
|
+
return threshold !== null && listened >= threshold;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=playThreshold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playThreshold.js","sourceRoot":"","sources":["../src/playThreshold.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,sEAAsE;AACtE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AACzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AASlC,MAAM,CAAC,MAAM,eAAe,GAAmB,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;AAEhF;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,QAAuB;IACnD,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,qBAAqB,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,iBAAiB;QAAE,OAAO,IAAI,CAAC;IAC5E,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAwB,EACxB,QAAgB,EAChB,OAAgB,EAChB,OAAO,GAAW,gBAAgB;IAElC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChD,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC;IACpF,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AAC3E,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,MAAM,CAAC,QAAgB,EAAE,QAAuB;IAC9D,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,SAAS,KAAK,IAAI,IAAI,QAAQ,IAAI,SAAS,CAAC;AACrD,CAAC"}
|
package/build/player.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export declare class PlayerCore extends EventEmitter {
|
|
|
33
33
|
move(from: number, to: number): void;
|
|
34
34
|
play(index?: number): Promise<void>;
|
|
35
35
|
pause(): Promise<void>;
|
|
36
|
+
stop(): Promise<void>;
|
|
36
37
|
resume(): Promise<void>;
|
|
37
38
|
next(): Promise<void>;
|
|
38
39
|
previous(): Promise<void>;
|
package/build/player.d.ts.map
CHANGED
|
@@ -1 +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;IAE1B,YACmB,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,aAAa,EAiBzC;IAID,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACrE,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAKpF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACtE,GAAG,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAIrF,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,CAIvE;IAEK,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAEpE;IAEK,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAExE;IAED,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAIzD;IAED,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAGnC;IAEK,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"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"}
|