@inner-dj/client 0.0.3
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/LICENSE +21 -0
- package/lib/src/config.d.ts +11 -0
- package/lib/src/config.js +34 -0
- package/lib/src/config.js.map +1 -0
- package/lib/src/index.d.ts +1 -0
- package/lib/src/index.js +11 -0
- package/lib/src/index.js.map +1 -0
- package/lib/src/main.d.ts +2 -0
- package/lib/src/main.js +5 -0
- package/lib/src/main.js.map +1 -0
- package/lib/src/player.d.ts +24 -0
- package/lib/src/player.js +211 -0
- package/lib/src/player.js.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Cory Sanin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ClientConfig {
|
|
2
|
+
server: string;
|
|
3
|
+
jwtSecret: string;
|
|
4
|
+
forceDownloadViaServer: boolean;
|
|
5
|
+
clientId: string;
|
|
6
|
+
standbyPool: string[];
|
|
7
|
+
downloadDir: string;
|
|
8
|
+
maxLength: number;
|
|
9
|
+
blocked: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function getConfig(cfgPath?: string): Promise<ClientConfig>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fsp from 'fs/promises';
|
|
3
|
+
import { parse } from 'yaml';
|
|
4
|
+
import { notStupidParseInt } from '@inner-dj/common';
|
|
5
|
+
function throwNewError(msg) {
|
|
6
|
+
throw new Error(msg);
|
|
7
|
+
}
|
|
8
|
+
function getBoolean(envname, cfg, key, fallback) {
|
|
9
|
+
return (process.env[envname] ?? `${cfg[key] ?? fallback}`) === 'true';
|
|
10
|
+
}
|
|
11
|
+
async function parseConfig(cfgPath) {
|
|
12
|
+
try {
|
|
13
|
+
return parse(await fsp.readFile(cfgPath, { encoding: 'utf-8' }));
|
|
14
|
+
}
|
|
15
|
+
catch (ex) {
|
|
16
|
+
console.warn(`failed to read ${cfgPath}:\n`, ex, '\nusing default config.');
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function getConfig(cfgPath) {
|
|
21
|
+
const p = process.env['CONFIG'] || cfgPath || path.join('config', 'config.yaml');
|
|
22
|
+
const cfg = await parseConfig(p);
|
|
23
|
+
return {
|
|
24
|
+
clientId: process.env['CLIENTID'] ?? cfg.clientId ?? throwNewError('clientId is required'),
|
|
25
|
+
server: process.env['SERVER'] ?? cfg.server ?? throwNewError('server is required'),
|
|
26
|
+
jwtSecret: process.env['JWTSECRET'] ?? cfg.jwtSecret ?? throwNewError('jwtSecret is required'),
|
|
27
|
+
forceDownloadViaServer: getBoolean('FORCESERVERDOWNLOAD', cfg, 'forceDownloadViaServer', false),
|
|
28
|
+
standbyPool: process.env['STANDBYPOOL']?.split(',') ?? cfg.standbyPool ?? [],
|
|
29
|
+
downloadDir: process.env['DOWNLOADDIR'] ?? cfg.downloadDir ?? path.join(path.dirname(p), 'downloads'),
|
|
30
|
+
maxLength: notStupidParseInt(process.env['MAXLENGTH'] ?? cfg.maxLength ?? 0),
|
|
31
|
+
blocked: process.env['BLOCKED']?.split(',') ?? cfg.blocked ?? [],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,GAAG,MAAM,aAAa,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAarD,SAAS,aAAa,CAAI,GAAW;IACjC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,GAA0B,EAAE,GAAuB,EAAE,QAAiB;IACvG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC,KAAK,MAAM,CAAC;AAC1E,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAe;IACtC,IAAI,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,EAAE,EAAE,CAAC;QACR,OAAO,CAAC,IAAI,CAAC,kBAAkB,OAAO,KAAK,EAAE,EAAE,EAAE,yBAAyB,CAAC,CAAC;QAC5E,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAgB;IAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAW,IAAI,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC3F,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC;IACjC,OAAO;QACH,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC,sBAAsB,CAAC;QAC1F,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,aAAa,CAAC,oBAAoB,CAAC;QAClF,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,SAAS,IAAI,aAAa,CAAC,uBAAuB,CAAC;QAC9F,sBAAsB,EAAE,UAAU,CAAC,qBAAqB,EAAE,GAAG,EAAE,wBAAwB,EAAE,KAAK,CAAC;QAC/F,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE;QAC5E,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC;QACrG,SAAS,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC;QAC5E,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE;KACnE,CAAA;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function main(cfgPath?: string): Promise<void>;
|
package/lib/src/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getConfig } from './config.js';
|
|
2
|
+
import { Player } from './player.js';
|
|
3
|
+
export async function main(cfgPath) {
|
|
4
|
+
const cfg = await getConfig(cfgPath);
|
|
5
|
+
const player = new Player(cfg);
|
|
6
|
+
player.start();
|
|
7
|
+
process.on('SIGTERM', () => {
|
|
8
|
+
player.close();
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAgB;IACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,MAAM,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/lib/src/main.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;AAChE,MAAM,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type YouTubeVideoID } from '@inner-dj/common';
|
|
2
|
+
import type { ClientConfig } from './config.js';
|
|
3
|
+
export declare class Player {
|
|
4
|
+
private downloader;
|
|
5
|
+
private filesCache;
|
|
6
|
+
private proc;
|
|
7
|
+
private config;
|
|
8
|
+
private sock;
|
|
9
|
+
private blockedVids;
|
|
10
|
+
private queue;
|
|
11
|
+
private standbyQueue;
|
|
12
|
+
private standbyPool;
|
|
13
|
+
constructor(config: ClientConfig);
|
|
14
|
+
start: () => Promise<void>;
|
|
15
|
+
connect: (retryOnFailure?: boolean) => void;
|
|
16
|
+
play: () => Promise<void>;
|
|
17
|
+
enqueue: (vidurl: string, destination: string[], insertFilename?: boolean) => Promise<string | false>;
|
|
18
|
+
skip: () => void;
|
|
19
|
+
fileExists: (vid: YouTubeVideoID) => Promise<string | false>;
|
|
20
|
+
download: (vid: YouTubeVideoID) => Promise<void>;
|
|
21
|
+
downloadFromServer: (vidurl: YouTubeVideoID) => Promise<void>;
|
|
22
|
+
isBlocked: (vid: YouTubeVideoID) => boolean;
|
|
23
|
+
close: () => void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fsp from 'fs/promises';
|
|
3
|
+
import jwt from 'jsonwebtoken';
|
|
4
|
+
import { LRUCache } from 'lru-cache';
|
|
5
|
+
import { shuffle } from 'fast-shuffle';
|
|
6
|
+
import { spawn } from 'spawn-but-with-promises';
|
|
7
|
+
import { ytdlp, ytdlpDefaults, encodePayload } from '@inner-dj/common';
|
|
8
|
+
import getYouTubeID from 'get-youtube-id-ng';
|
|
9
|
+
async function getFilesNoError(downloadDir) {
|
|
10
|
+
try {
|
|
11
|
+
return await fsp.readdir(downloadDir);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function emptyArray(arr) {
|
|
18
|
+
while (arr.length) {
|
|
19
|
+
arr.pop();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class Player {
|
|
23
|
+
downloader;
|
|
24
|
+
filesCache;
|
|
25
|
+
proc = false;
|
|
26
|
+
config;
|
|
27
|
+
sock = null;
|
|
28
|
+
blockedVids;
|
|
29
|
+
// All track arrays are composed of filenames.
|
|
30
|
+
queue = [];
|
|
31
|
+
standbyQueue = [];
|
|
32
|
+
standbyPool = [];
|
|
33
|
+
constructor(config) {
|
|
34
|
+
this.downloader = new ytdlp({
|
|
35
|
+
...ytdlpDefaults,
|
|
36
|
+
optput: path.join(config.downloadDir, ytdlpDefaults.optput)
|
|
37
|
+
});
|
|
38
|
+
this.filesCache = new LRUCache({
|
|
39
|
+
max: config.standbyPool.length + 100,
|
|
40
|
+
ttl: 1000 * 60 * 60 * 12
|
|
41
|
+
});
|
|
42
|
+
this.config = config;
|
|
43
|
+
this.blockedVids = config.blocked.map(b => getYouTubeID(b)).filter(vid => vid != null);
|
|
44
|
+
}
|
|
45
|
+
start = async () => {
|
|
46
|
+
for (const vidurl of this.config.standbyPool) {
|
|
47
|
+
if (await this.enqueue(vidurl, this.standbyPool, true)) {
|
|
48
|
+
this.play();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.standbyQueue = shuffle(this.standbyPool);
|
|
52
|
+
this.connect();
|
|
53
|
+
};
|
|
54
|
+
connect = (retryOnFailure = false) => {
|
|
55
|
+
const config = this.config;
|
|
56
|
+
const ws = this.sock = new WebSocket(`${config.server}/sock`);
|
|
57
|
+
ws.onerror = err => {
|
|
58
|
+
console.error(err);
|
|
59
|
+
ws.close();
|
|
60
|
+
this.sock = null;
|
|
61
|
+
if (retryOnFailure) {
|
|
62
|
+
console.log('Failed to connect. Attempting to reconnect...');
|
|
63
|
+
setTimeout(() => this.connect(true), 5000);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log('Failed to connect to server. Check your configuration and try again.\nStarting without server connectivity.');
|
|
67
|
+
};
|
|
68
|
+
ws.onopen = () => {
|
|
69
|
+
ws.onerror = null;
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
ws.send(encodePayload({
|
|
72
|
+
type: 'reg',
|
|
73
|
+
body: config.clientId
|
|
74
|
+
}, config.jwtSecret));
|
|
75
|
+
}, 500);
|
|
76
|
+
};
|
|
77
|
+
ws.onmessage = (msg) => {
|
|
78
|
+
const payload = jwt.verify(msg.data, config.jwtSecret);
|
|
79
|
+
if (typeof payload === 'string') {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (payload.type === 'ack') {
|
|
83
|
+
this.proc && typeof this.proc === 'object' && 'kill' in this.proc && ws.send(encodePayload({
|
|
84
|
+
type: 'nowPlaying',
|
|
85
|
+
body: path.basename(this.proc.spawnargs[this.proc.spawnargs.length - 1] || 'track not found')
|
|
86
|
+
}, config.jwtSecret));
|
|
87
|
+
(!ws.onclose) && (ws.onclose = () => {
|
|
88
|
+
console.log('Connection closed. Attempting to reconnect...');
|
|
89
|
+
this.sock = null;
|
|
90
|
+
ws.close();
|
|
91
|
+
setTimeout(() => this.connect(true), 2500);
|
|
92
|
+
}) && console.log(`Connected to ${config.server}`);
|
|
93
|
+
}
|
|
94
|
+
else if (payload.type === 'queue') {
|
|
95
|
+
console.log(`adding ${payload.body} to the queue`);
|
|
96
|
+
this.enqueue(payload.body, this.queue).then(this.play);
|
|
97
|
+
}
|
|
98
|
+
else if (payload.type === 'skip') {
|
|
99
|
+
this.skip();
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
play = async () => {
|
|
104
|
+
if (this.proc) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const queue = this.queue;
|
|
108
|
+
const maxLength = this.config.maxLength;
|
|
109
|
+
while (queue.length > 0 || this.standbyQueue.length > 0 || this.standbyPool.length > 0) {
|
|
110
|
+
this.proc = true;
|
|
111
|
+
if (this.standbyQueue.length === 0) {
|
|
112
|
+
this.standbyQueue = shuffle(this.standbyPool);
|
|
113
|
+
}
|
|
114
|
+
if (queue.length === 0) {
|
|
115
|
+
queue.push(this.standbyQueue.pop());
|
|
116
|
+
}
|
|
117
|
+
const track = queue.shift();
|
|
118
|
+
if (!track) {
|
|
119
|
+
throw new Error('assertion failed: queue length was 0');
|
|
120
|
+
}
|
|
121
|
+
console.info(`playing ${track}`);
|
|
122
|
+
this.proc = spawn('ffplay', ['-nodisp', '-autoexit', '-loglevel', 'quiet', track]);
|
|
123
|
+
this.sock?.send(encodePayload({
|
|
124
|
+
type: 'nowPlaying',
|
|
125
|
+
body: path.basename(track)
|
|
126
|
+
}, this.config.jwtSecret));
|
|
127
|
+
const timeout = maxLength > 0 && setTimeout(() => {
|
|
128
|
+
this.skip();
|
|
129
|
+
console.info(`played the first ${maxLength}ms of ${track}. That's all, folks!`);
|
|
130
|
+
}, maxLength);
|
|
131
|
+
await this.proc;
|
|
132
|
+
timeout === false || clearTimeout(timeout);
|
|
133
|
+
}
|
|
134
|
+
this.proc = null;
|
|
135
|
+
};
|
|
136
|
+
enqueue = async (vidurl, destination, insertFilename = true) => {
|
|
137
|
+
const vid = getYouTubeID(vidurl);
|
|
138
|
+
if (!vid) {
|
|
139
|
+
console.warn(`could not parse url ${vidurl}`);
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
if (this.isBlocked(vid)) {
|
|
143
|
+
console.log(`skipping blocked video ${vidurl}`);
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
if (!await this.fileExists(vid)) {
|
|
147
|
+
try {
|
|
148
|
+
await this.download(vid);
|
|
149
|
+
}
|
|
150
|
+
catch (ex) {
|
|
151
|
+
console.error(`failed to download ${vidurl}\n`, ex);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const filename = await this.fileExists(vid);
|
|
155
|
+
if (!filename) {
|
|
156
|
+
console.warn(`no file for video ${vid} found.`);
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
destination.push(insertFilename ? filename : vidurl);
|
|
160
|
+
return filename;
|
|
161
|
+
};
|
|
162
|
+
skip = () => {
|
|
163
|
+
this.proc && typeof this.proc === 'object' && 'kill' in this.proc && this.proc.kill();
|
|
164
|
+
};
|
|
165
|
+
fileExists = async (vid) => {
|
|
166
|
+
const cache = this.filesCache;
|
|
167
|
+
const cacheResult = cache.get(vid);
|
|
168
|
+
const downloadDir = this.config.downloadDir;
|
|
169
|
+
if (cacheResult) {
|
|
170
|
+
return cacheResult;
|
|
171
|
+
}
|
|
172
|
+
const files = await getFilesNoError(downloadDir);
|
|
173
|
+
const file = files.find(f => f.split('.')[0] === vid);
|
|
174
|
+
if (!file) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
const result = path.join(downloadDir, file);
|
|
178
|
+
cache.set(vid, result);
|
|
179
|
+
return result;
|
|
180
|
+
};
|
|
181
|
+
download = async (vid) => {
|
|
182
|
+
const vidurl = `https://www.youtube.com/watch?v=${vid}`;
|
|
183
|
+
console.info(`downloading ${vidurl}`);
|
|
184
|
+
await fsp.mkdir(this.config.downloadDir, { recursive: true });
|
|
185
|
+
if (this.config.forceDownloadViaServer) {
|
|
186
|
+
await this.downloadFromServer(vidurl);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
await this.downloader.exec(vidurl);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
catch (ex) {
|
|
194
|
+
console.warn(`failed to download ${vidurl}, falling back to server\n`, ex);
|
|
195
|
+
await this.downloadFromServer(vidurl);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
downloadFromServer = async (vidurl) => {
|
|
199
|
+
console.log(`todo: download video ${vidurl} from server`);
|
|
200
|
+
};
|
|
201
|
+
isBlocked = (vid) => {
|
|
202
|
+
return this.blockedVids.indexOf(vid) >= 0;
|
|
203
|
+
};
|
|
204
|
+
close = () => {
|
|
205
|
+
this.sock?.close();
|
|
206
|
+
this.sock = null;
|
|
207
|
+
[this.standbyPool, this.standbyQueue, this.queue].forEach(q => emptyArray(q));
|
|
208
|
+
this.skip();
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=player.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player.js","sourceRoot":"","sources":["../../src/player.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@inner-dj/client",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "player component of inner-dj",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://codeberg.org/sanin/inner-dj.git"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "Cory Sanin",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./lib/src/index.d.ts",
|
|
15
|
+
"import": "./lib/src/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"main": "./lib/src/index.js",
|
|
19
|
+
"types": "./lib/src/index.d.ts",
|
|
20
|
+
"bin": {
|
|
21
|
+
"inner-dj-client": "./lib/src/main.js"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"lib/src",
|
|
25
|
+
"!lib/**/*.js.map"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"fast-shuffle": "^6.1.1",
|
|
29
|
+
"get-youtube-id-ng": "1.0.1",
|
|
30
|
+
"jsonwebtoken": "9.0.3",
|
|
31
|
+
"lru-cache": "^11.4.0",
|
|
32
|
+
"spawn-but-with-promises": "^1.0.4",
|
|
33
|
+
"yaml": "^2.9.0",
|
|
34
|
+
"@inner-dj/common": "0.0.3"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@sindresorhus/tsconfig": "8.1.0",
|
|
38
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
39
|
+
"@types/node": "^24.12.4",
|
|
40
|
+
"typescript": "^6.0.3"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc && chmod +x ./lib/src/main.js",
|
|
44
|
+
"start": "./lib/src/main.js"
|
|
45
|
+
}
|
|
46
|
+
}
|