@groovenet/player 0.1.3 → 0.1.5
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 +17 -0
- package/SERVER_PLAYERS.md +348 -0
- package/build/daemon.d.ts.map +1 -1
- package/build/daemon.js +3 -0
- package/build/daemon.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -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.map +1 -1
- package/build/mpvBackend.js +2 -1
- 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/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 +61 -0
- package/build/server/manager.d.ts.map +1 -0
- package/build/server/manager.js +555 -0
- package/build/server/manager.js.map +1 -0
- package/build/server/observer.d.ts +10 -0
- package/build/server/observer.d.ts.map +1 -0
- package/build/server/observer.js +47 -0
- package/build/server/observer.js.map +1 -0
- package/build/server/runtime.d.ts +18 -0
- package/build/server/runtime.d.ts.map +1 -0
- package/build/server/runtime.js +101 -0
- package/build/server/runtime.js.map +1 -0
- package/build/server/store.d.ts +47 -0
- package/build/server/store.d.ts.map +1 -0
- package/build/server/store.js +120 -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,5 @@
|
|
|
1
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
2
|
+
import { ServerPlayerManager } from "./manager.js";
|
|
3
|
+
/** The worker API is private to Compose. Public clients go through the app. */
|
|
4
|
+
export declare function playerHttpServer(manager: ServerPlayerManager, key: string): import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
5
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/server/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAMpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAyBnD,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,EAAE,MAAM,6EAwDzE"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { timingSafeEqual } from "node:crypto";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { ZodError } from "zod";
|
|
5
|
+
import { createServerPlayerSchema, playerIdSchema, serverPlayerCommandSchema } from "@groovenet/contracts";
|
|
6
|
+
import { PlayerError } from "../types.js";
|
|
7
|
+
import { ServerPlayerError } from "./store.js";
|
|
8
|
+
function authorized(header, key) {
|
|
9
|
+
const actual = Buffer.from(header ?? "");
|
|
10
|
+
const expected = Buffer.from(`Bearer ${key}`);
|
|
11
|
+
return actual.length === expected.length && timingSafeEqual(actual, expected);
|
|
12
|
+
}
|
|
13
|
+
async function body(request) {
|
|
14
|
+
const chunks = [];
|
|
15
|
+
let bytes = 0;
|
|
16
|
+
for await (const chunk of request.iterator({ destroyOnReturn: false })) {
|
|
17
|
+
const buffer = Buffer.from(chunk);
|
|
18
|
+
bytes += buffer.length;
|
|
19
|
+
if (bytes > 2 * 1024 * 1024) {
|
|
20
|
+
request.resume();
|
|
21
|
+
throw new ServerPlayerError("BODY_TOO_LARGE", "Player command exceeds 2 MB", 413);
|
|
22
|
+
}
|
|
23
|
+
chunks.push(buffer);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(Buffer.concat(chunks).toString());
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
throw new ServerPlayerError("INVALID_JSON", "Invalid JSON request", 400);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function json(response, status, value) {
|
|
33
|
+
response.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
34
|
+
response.end(JSON.stringify(value));
|
|
35
|
+
}
|
|
36
|
+
/** The worker API is private to Compose. Public clients go through the app. */
|
|
37
|
+
export function playerHttpServer(manager, key) {
|
|
38
|
+
if (key.length < 32)
|
|
39
|
+
throw new Error("PLAYER_API_KEY must contain at least 32 characters");
|
|
40
|
+
const instance = randomUUID();
|
|
41
|
+
let sequence = 0;
|
|
42
|
+
const server = createServer((request, response) => {
|
|
43
|
+
void (async () => {
|
|
44
|
+
if (!authorized(request.headers.authorization, key)) {
|
|
45
|
+
json(response, 401, { error: "Unauthorized", code: "UNAUTHORIZED" });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const path = new URL(request.url ?? "/", "http://worker").pathname;
|
|
49
|
+
if (request.method === "GET" && path === "/health") {
|
|
50
|
+
json(response, 200, { status: "ok", instance });
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (request.method === "GET" && path === "/engines") {
|
|
54
|
+
json(response, 200, { engines: manager.engineIds() });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (path === "/players") {
|
|
58
|
+
if (request.method === "GET") {
|
|
59
|
+
json(response, 200, { players: manager.list() });
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (request.method === "POST") {
|
|
63
|
+
json(response, 201, await manager.create(createServerPlayerSchema.parse(await body(request))));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const match = /^\/players\/([^/]+)(?:\/(commands|devices|events))?$/.exec(path);
|
|
68
|
+
if (!match) {
|
|
69
|
+
json(response, 404, { error: "Not found" });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const id = playerIdSchema.parse(match[1]);
|
|
73
|
+
const player = manager.get(id);
|
|
74
|
+
if (!match[2] && request.method === "GET") {
|
|
75
|
+
json(response, 200, player);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (match[2] === "devices" && request.method === "GET") {
|
|
79
|
+
json(response, 200, { devices: await manager.devices(id) });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (match[2] === "commands" && request.method === "POST") {
|
|
83
|
+
json(response, 200, await manager.command(id, serverPlayerCommandSchema.parse(await body(request))));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (match[2] === "events" && request.method === "GET") {
|
|
87
|
+
response.writeHead(200, { "Content-Type": "text/event-stream", "Cache-Control": "no-cache, no-transform", "Connection": "keep-alive", "X-Accel-Buffering": "no" });
|
|
88
|
+
const send = (value) => {
|
|
89
|
+
if (value.id !== id || response.destroyed)
|
|
90
|
+
return;
|
|
91
|
+
const event = JSON.stringify({ type: "snapshot", player: value, worker_instance: instance, sequence: ++sequence });
|
|
92
|
+
// A slow/disconnected client is dropped; it never blocks the player.
|
|
93
|
+
response.write(`event: snapshot\ndata: ${event}\n\n`);
|
|
94
|
+
if (response.writableLength > 64 * 1024 * 1024)
|
|
95
|
+
response.destroy();
|
|
96
|
+
};
|
|
97
|
+
const position = (value) => {
|
|
98
|
+
if (value.player_id === id && !response.destroyed) {
|
|
99
|
+
response.write(`event: position\ndata: ${JSON.stringify({ ...value, type: "position", worker_instance: instance, sequence: ++sequence })}\n\n`);
|
|
100
|
+
if (response.writableLength > 64 * 1024 * 1024)
|
|
101
|
+
response.destroy();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const heartbeat = setInterval(() => { if (!response.destroyed && !response.write(": heartbeat\n\n"))
|
|
105
|
+
response.destroy(); }, 15000);
|
|
106
|
+
heartbeat.unref();
|
|
107
|
+
const cleanup = () => { clearInterval(heartbeat); manager.off("snapshot", send); manager.off("position", position); };
|
|
108
|
+
response.once("close", cleanup);
|
|
109
|
+
manager.on("snapshot", send);
|
|
110
|
+
manager.on("position", position);
|
|
111
|
+
send(player);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
json(response, 405, { error: "Method not allowed" });
|
|
115
|
+
})().catch((error) => {
|
|
116
|
+
if (response.headersSent) {
|
|
117
|
+
response.destroy();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const status = error instanceof ServerPlayerError ? error.status : error instanceof ZodError ? 400 : error instanceof PlayerError ? 422 : 502;
|
|
121
|
+
const code = error instanceof ServerPlayerError ? error.code : error instanceof ZodError ? "INVALID_ARGUMENT" : error instanceof PlayerError ? error.code : "PLAYER_OPERATION_FAILED";
|
|
122
|
+
json(response, status, { error: error instanceof ServerPlayerError ? error.message : "Player operation failed", code });
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
server.requestTimeout = 15000;
|
|
126
|
+
server.headersTimeout = 10000;
|
|
127
|
+
return server;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/server/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import { type CreateServerPlayer, type ServerPlayer, type ServerPlayerCommand, type ServerPlayerCommandResult, type ServerPlayerDevice, type SpeakerObservation } from "@groovenet/contracts";
|
|
3
|
+
import { type PlaybackBackend } from "../types.js";
|
|
4
|
+
import { type PlayerStore, type ServerPlay } from "./store.js";
|
|
5
|
+
export interface PlayerEngine {
|
|
6
|
+
libraryRoot: string;
|
|
7
|
+
create(outputId?: string): PlaybackBackend;
|
|
8
|
+
}
|
|
9
|
+
export type SpeakerObserver = (outputId: string, context?: {
|
|
10
|
+
outputName?: string;
|
|
11
|
+
resolveOutputName?: () => Promise<string | undefined>;
|
|
12
|
+
fresh?: boolean;
|
|
13
|
+
}) => Promise<SpeakerObservation>;
|
|
14
|
+
export declare const unknownSpeaker: () => SpeakerObservation;
|
|
15
|
+
export interface ServerPlayLogging {
|
|
16
|
+
ownerFriendId: number;
|
|
17
|
+
logPlay: (play: ServerPlay) => Promise<void>;
|
|
18
|
+
now?: () => Date;
|
|
19
|
+
}
|
|
20
|
+
/** Owns all player lifecycles; no HTTP connection owns a backend. */
|
|
21
|
+
export declare class ServerPlayerManager extends EventEmitter {
|
|
22
|
+
private readonly store;
|
|
23
|
+
private readonly engines;
|
|
24
|
+
private readonly observe;
|
|
25
|
+
private readonly playLogging?;
|
|
26
|
+
private players;
|
|
27
|
+
private runtimes;
|
|
28
|
+
private generation;
|
|
29
|
+
private tail;
|
|
30
|
+
private stopping;
|
|
31
|
+
private checkpointAt;
|
|
32
|
+
private progress;
|
|
33
|
+
private queuedPlays;
|
|
34
|
+
private retrying;
|
|
35
|
+
constructor(store: PlayerStore, engines: Record<string, PlayerEngine>, observe?: SpeakerObserver, playLogging?: ServerPlayLogging | undefined);
|
|
36
|
+
/** Retry durable deliveries independently of queue changes and playback. */
|
|
37
|
+
retryPlays(): Promise<void>;
|
|
38
|
+
private serial;
|
|
39
|
+
initialize(): Promise<void>;
|
|
40
|
+
engineIds(): string[];
|
|
41
|
+
list(): ServerPlayer[];
|
|
42
|
+
get(id: string): ServerPlayer;
|
|
43
|
+
create(input: CreateServerPlayer): Promise<ServerPlayer>;
|
|
44
|
+
devices(id: string): Promise<ServerPlayerDevice[]>;
|
|
45
|
+
command(id: string, input: ServerPlayerCommand): Promise<ServerPlayerCommandResult>;
|
|
46
|
+
private replaceQueue;
|
|
47
|
+
private play;
|
|
48
|
+
private enqueueEvent;
|
|
49
|
+
private detach;
|
|
50
|
+
private stop;
|
|
51
|
+
private transfer;
|
|
52
|
+
shutdown(): Promise<void>;
|
|
53
|
+
private requireAvailable;
|
|
54
|
+
private engine;
|
|
55
|
+
private active;
|
|
56
|
+
private revision;
|
|
57
|
+
private available;
|
|
58
|
+
private save;
|
|
59
|
+
private publish;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/server/manager.ts"],"names":[],"mappings":"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"}
|