distube 5.0.2 → 5.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/dist/index.d.mts +1489 -0
- package/dist/index.d.ts +22 -4
- package/dist/index.js +711 -828
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2463 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +39 -23
package/dist/index.js
CHANGED
|
@@ -3,14 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __typeError = (msg) => {
|
|
7
|
-
throw TypeError(msg);
|
|
8
|
-
};
|
|
9
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
6
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
11
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
12
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
13
|
-
};
|
|
14
7
|
var __export = (target, all) => {
|
|
15
8
|
for (var name in all)
|
|
16
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -24,115 +17,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
24
17
|
return to;
|
|
25
18
|
};
|
|
26
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
28
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
29
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
30
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
31
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
32
|
-
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
33
|
-
|
|
34
|
-
// package.json
|
|
35
|
-
var require_package = __commonJS({
|
|
36
|
-
"package.json"(exports2, module2) {
|
|
37
|
-
module2.exports = {
|
|
38
|
-
name: "distube",
|
|
39
|
-
version: "5.0.2",
|
|
40
|
-
description: "A powerful Discord.js module for simplifying music commands and effortless playback of various sources with integrated audio filters.",
|
|
41
|
-
main: "./dist/index.js",
|
|
42
|
-
types: "./dist/index.d.ts",
|
|
43
|
-
exports: "./dist/index.js",
|
|
44
|
-
directories: {
|
|
45
|
-
lib: "src",
|
|
46
|
-
test: "tests"
|
|
47
|
-
},
|
|
48
|
-
files: [
|
|
49
|
-
"dist"
|
|
50
|
-
],
|
|
51
|
-
scripts: {
|
|
52
|
-
test: "VITE_CJS_IGNORE_WARNING=true vitest run",
|
|
53
|
-
docs: "typedoc",
|
|
54
|
-
lint: "prettier --check . && eslint .",
|
|
55
|
-
"lint:fix": "eslint . --fix",
|
|
56
|
-
prettier: 'prettier --write "**/*.{ts,json,yml,yaml,md}"',
|
|
57
|
-
build: "tsup",
|
|
58
|
-
type: "tsc --noEmit",
|
|
59
|
-
update: 'pnpm up -L "!eslint"',
|
|
60
|
-
prepare: "husky",
|
|
61
|
-
prepublishOnly: "pnpm run lint && pnpm run test",
|
|
62
|
-
prepack: "pnpm run build"
|
|
63
|
-
},
|
|
64
|
-
repository: {
|
|
65
|
-
type: "git",
|
|
66
|
-
url: "git+https://github.com/skick1234/DisTube.git"
|
|
67
|
-
},
|
|
68
|
-
keywords: [
|
|
69
|
-
"youtube",
|
|
70
|
-
"music",
|
|
71
|
-
"discord",
|
|
72
|
-
"discordjs",
|
|
73
|
-
"bot",
|
|
74
|
-
"distube",
|
|
75
|
-
"queue",
|
|
76
|
-
"musicbot",
|
|
77
|
-
"discord-music-bot",
|
|
78
|
-
"music-bot",
|
|
79
|
-
"discord-js"
|
|
80
|
-
],
|
|
81
|
-
author: "Skick (https://github.com/skick1234)",
|
|
82
|
-
license: "MIT",
|
|
83
|
-
bugs: {
|
|
84
|
-
url: "https://github.com/skick1234/DisTube/issues"
|
|
85
|
-
},
|
|
86
|
-
funding: "https://github.com/skick1234/DisTube?sponsor",
|
|
87
|
-
homepage: "https://distube.js.org/",
|
|
88
|
-
dependencies: {
|
|
89
|
-
"tiny-typed-emitter": "^2.1.0",
|
|
90
|
-
undici: "^6.18.2"
|
|
91
|
-
},
|
|
92
|
-
devDependencies: {
|
|
93
|
-
"@commitlint/cli": "^19.3.0",
|
|
94
|
-
"@commitlint/config-conventional": "^19.2.2",
|
|
95
|
-
"@discordjs/voice": "^0.17.0",
|
|
96
|
-
"@types/node": "^20.14.2",
|
|
97
|
-
"@types/tough-cookie": "^4.0.5",
|
|
98
|
-
"@typescript-eslint/eslint-plugin": "^7.13.0",
|
|
99
|
-
"@typescript-eslint/parser": "^7.13.0",
|
|
100
|
-
"@vitest/coverage-v8": "^1.6.0",
|
|
101
|
-
"discord.js": "^14.15.3",
|
|
102
|
-
eslint: "^8.57.0",
|
|
103
|
-
"eslint-config-distube": "^1.7.0",
|
|
104
|
-
husky: "^9.0.11",
|
|
105
|
-
"nano-staged": "^0.8.0",
|
|
106
|
-
prettier: "^3.3.2",
|
|
107
|
-
"sodium-native": "^4.1.1",
|
|
108
|
-
"ts-node": "^10.9.2",
|
|
109
|
-
tsup: "^8.1.0",
|
|
110
|
-
typedoc: "^0.25.13",
|
|
111
|
-
"typedoc-material-theme": "^1.0.2",
|
|
112
|
-
"typedoc-plugin-extras": "^3.0.0",
|
|
113
|
-
typescript: "^5.4.5",
|
|
114
|
-
"vite-tsconfig-paths": "^4.3.2",
|
|
115
|
-
vitest: "^1.6.0"
|
|
116
|
-
},
|
|
117
|
-
peerDependencies: {
|
|
118
|
-
"@discordjs/voice": "*",
|
|
119
|
-
"discord.js": "14"
|
|
120
|
-
},
|
|
121
|
-
"nano-staged": {
|
|
122
|
-
"*.ts": [
|
|
123
|
-
"prettier --write",
|
|
124
|
-
"eslint"
|
|
125
|
-
],
|
|
126
|
-
"*.{json,yml,yaml,md}": [
|
|
127
|
-
"prettier --write"
|
|
128
|
-
]
|
|
129
|
-
},
|
|
130
|
-
engines: {
|
|
131
|
-
node: ">=18.17"
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
20
|
|
|
137
21
|
// src/index.ts
|
|
138
22
|
var src_exports = {};
|
|
@@ -160,6 +44,7 @@ __export(src_exports, {
|
|
|
160
44
|
RepeatMode: () => RepeatMode,
|
|
161
45
|
Song: () => Song,
|
|
162
46
|
TaskQueue: () => TaskQueue,
|
|
47
|
+
checkEncryptionLibraries: () => checkEncryptionLibraries,
|
|
163
48
|
checkFFmpeg: () => checkFFmpeg,
|
|
164
49
|
checkIntents: () => checkIntents,
|
|
165
50
|
checkInvalidKey: () => checkInvalidKey,
|
|
@@ -267,6 +152,7 @@ var ERROR_MESSAGES = {
|
|
|
267
152
|
VOICE_DIFFERENT_CLIENT: "Cannot join a voice channel created by a different client",
|
|
268
153
|
FFMPEG_EXITED: /* @__PURE__ */ __name((code) => `ffmpeg exited with code ${code}`, "FFMPEG_EXITED"),
|
|
269
154
|
FFMPEG_NOT_INSTALLED: /* @__PURE__ */ __name((path) => `ffmpeg is not installed at '${path}' path`, "FFMPEG_NOT_INSTALLED"),
|
|
155
|
+
ENCRYPTION_LIBRARIES_MISSING: "Cannot play audio as no valid encryption package is installed.\nPlease install sodium-native, sodium, libsodium-wrappers, or tweetnacl.",
|
|
270
156
|
NO_QUEUE: "There is no playing queue in this guild",
|
|
271
157
|
QUEUE_EXIST: "This guild has a Queue already",
|
|
272
158
|
QUEUE_STOPPED: "The queue has been stopped already",
|
|
@@ -276,6 +162,7 @@ var ERROR_MESSAGES = {
|
|
|
276
162
|
NO_UP_NEXT: "There is no up next song",
|
|
277
163
|
NO_SONG_POSITION: "Does not have any song at this position",
|
|
278
164
|
NO_PLAYING_SONG: "There is no playing song in the queue",
|
|
165
|
+
NO_EXTRACTOR_PLUGIN: "There is no extractor plugin in the DisTubeOptions.plugins, please add one for searching songs",
|
|
279
166
|
NO_RELATED: "Cannot find any related songs",
|
|
280
167
|
CANNOT_PLAY_RELATED: "Cannot play the related song",
|
|
281
168
|
UNAVAILABLE_VIDEO: "This video is unavailable",
|
|
@@ -285,9 +172,9 @@ var ERROR_MESSAGES = {
|
|
|
285
172
|
NOT_SUPPORTED_SONG: /* @__PURE__ */ __name((song) => `There is no plugin supporting this song (${song})`, "NOT_SUPPORTED_SONG"),
|
|
286
173
|
NO_VALID_SONG: "'songs' array does not have any valid Song or url",
|
|
287
174
|
CANNOT_RESOLVE_SONG: /* @__PURE__ */ __name((t) => `Cannot resolve ${(0, import_node_util.inspect)(t)} to a Song`, "CANNOT_RESOLVE_SONG"),
|
|
288
|
-
CANNOT_GET_STREAM_URL: /* @__PURE__ */ __name((song) => `Cannot get stream url
|
|
289
|
-
CANNOT_GET_SEARCH_QUERY: /* @__PURE__ */ __name((song) => `Cannot get search query
|
|
290
|
-
NO_RESULT: /* @__PURE__ */ __name((query) => `Cannot
|
|
175
|
+
CANNOT_GET_STREAM_URL: /* @__PURE__ */ __name((song) => `Cannot get stream url with this song (${song})`, "CANNOT_GET_STREAM_URL"),
|
|
176
|
+
CANNOT_GET_SEARCH_QUERY: /* @__PURE__ */ __name((song) => `Cannot get search query with this song (${song})`, "CANNOT_GET_SEARCH_QUERY"),
|
|
177
|
+
NO_RESULT: /* @__PURE__ */ __name((query) => `Cannot find any song with this query (${query})`, "NO_RESULT"),
|
|
291
178
|
NO_STREAM_URL: /* @__PURE__ */ __name((song) => `No stream url attached (${song})`, "NO_STREAM_URL"),
|
|
292
179
|
EMPTY_FILTERED_PLAYLIST: "There is no valid video in the playlist\nMaybe age-restricted contents is filtered because you are in non-NSFW channel",
|
|
293
180
|
EMPTY_PLAYLIST: "There is no valid video in the playlist"
|
|
@@ -295,10 +182,13 @@ var ERROR_MESSAGES = {
|
|
|
295
182
|
var haveCode = /* @__PURE__ */ __name((code) => Object.keys(ERROR_MESSAGES).includes(code), "haveCode");
|
|
296
183
|
var parseMessage = /* @__PURE__ */ __name((m, ...args) => typeof m === "string" ? m : m(...args), "parseMessage");
|
|
297
184
|
var getErrorMessage = /* @__PURE__ */ __name((code, ...args) => haveCode(code) ? parseMessage(ERROR_MESSAGES[code], ...args) : args[0], "getErrorMessage");
|
|
298
|
-
var
|
|
185
|
+
var DisTubeError = class _DisTubeError extends Error {
|
|
186
|
+
static {
|
|
187
|
+
__name(this, "DisTubeError");
|
|
188
|
+
}
|
|
189
|
+
errorCode;
|
|
299
190
|
constructor(code, ...args) {
|
|
300
191
|
super(getErrorMessage(code, ...args));
|
|
301
|
-
__publicField(this, "errorCode");
|
|
302
192
|
this.errorCode = code;
|
|
303
193
|
if (Error.captureStackTrace) Error.captureStackTrace(this, _DisTubeError);
|
|
304
194
|
}
|
|
@@ -309,89 +199,87 @@ var _DisTubeError = class _DisTubeError extends Error {
|
|
|
309
199
|
return this.errorCode;
|
|
310
200
|
}
|
|
311
201
|
};
|
|
312
|
-
__name(_DisTubeError, "DisTubeError");
|
|
313
|
-
var DisTubeError = _DisTubeError;
|
|
314
202
|
|
|
315
203
|
// src/struct/TaskQueue.ts
|
|
316
|
-
var
|
|
204
|
+
var Task = class {
|
|
205
|
+
static {
|
|
206
|
+
__name(this, "Task");
|
|
207
|
+
}
|
|
208
|
+
resolve;
|
|
209
|
+
promise;
|
|
317
210
|
constructor() {
|
|
318
|
-
__publicField(this, "resolve");
|
|
319
|
-
__publicField(this, "promise");
|
|
320
211
|
this.promise = new Promise((res) => {
|
|
321
212
|
this.resolve = res;
|
|
322
213
|
});
|
|
323
214
|
}
|
|
324
215
|
};
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
var _TaskQueue = class _TaskQueue {
|
|
329
|
-
constructor() {
|
|
330
|
-
/**
|
|
331
|
-
* The task array
|
|
332
|
-
*/
|
|
333
|
-
__privateAdd(this, _tasks, []);
|
|
216
|
+
var TaskQueue = class {
|
|
217
|
+
static {
|
|
218
|
+
__name(this, "TaskQueue");
|
|
334
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* The task array
|
|
222
|
+
*/
|
|
223
|
+
#tasks = [];
|
|
335
224
|
/**
|
|
336
225
|
* Waits for last task finished and queues a new task
|
|
337
226
|
*/
|
|
338
227
|
queuing() {
|
|
339
|
-
const next = this.remaining ?
|
|
340
|
-
|
|
228
|
+
const next = this.remaining ? this.#tasks[this.#tasks.length - 1].promise : Promise.resolve();
|
|
229
|
+
this.#tasks.push(new Task());
|
|
341
230
|
return next;
|
|
342
231
|
}
|
|
343
232
|
/**
|
|
344
233
|
* Removes the finished task and processes the next task
|
|
345
234
|
*/
|
|
346
235
|
resolve() {
|
|
347
|
-
|
|
236
|
+
this.#tasks.shift()?.resolve();
|
|
348
237
|
}
|
|
349
238
|
/**
|
|
350
239
|
* The remaining number of tasks
|
|
351
240
|
*/
|
|
352
241
|
get remaining() {
|
|
353
|
-
return
|
|
242
|
+
return this.#tasks.length;
|
|
354
243
|
}
|
|
355
244
|
};
|
|
356
|
-
_tasks = new WeakMap();
|
|
357
|
-
__name(_TaskQueue, "TaskQueue");
|
|
358
|
-
var TaskQueue = _TaskQueue;
|
|
359
245
|
|
|
360
246
|
// src/struct/Playlist.ts
|
|
361
|
-
var
|
|
362
|
-
|
|
247
|
+
var Playlist = class {
|
|
248
|
+
static {
|
|
249
|
+
__name(this, "Playlist");
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Playlist source.
|
|
253
|
+
*/
|
|
254
|
+
source;
|
|
255
|
+
/**
|
|
256
|
+
* Songs in the playlist.
|
|
257
|
+
*/
|
|
258
|
+
songs;
|
|
259
|
+
/**
|
|
260
|
+
* Playlist ID.
|
|
261
|
+
*/
|
|
262
|
+
id;
|
|
263
|
+
/**
|
|
264
|
+
* Playlist name.
|
|
265
|
+
*/
|
|
266
|
+
name;
|
|
267
|
+
/**
|
|
268
|
+
* Playlist URL.
|
|
269
|
+
*/
|
|
270
|
+
url;
|
|
271
|
+
/**
|
|
272
|
+
* Playlist thumbnail.
|
|
273
|
+
*/
|
|
274
|
+
thumbnail;
|
|
275
|
+
#metadata;
|
|
276
|
+
#member;
|
|
363
277
|
/**
|
|
364
278
|
* Create a Playlist
|
|
365
279
|
* @param playlist - Raw playlist info
|
|
366
280
|
* @param options - Optional data
|
|
367
281
|
*/
|
|
368
282
|
constructor(playlist, { member, metadata } = {}) {
|
|
369
|
-
/**
|
|
370
|
-
* Playlist source.
|
|
371
|
-
*/
|
|
372
|
-
__publicField(this, "source");
|
|
373
|
-
/**
|
|
374
|
-
* Songs in the playlist.
|
|
375
|
-
*/
|
|
376
|
-
__publicField(this, "songs");
|
|
377
|
-
/**
|
|
378
|
-
* Playlist ID.
|
|
379
|
-
*/
|
|
380
|
-
__publicField(this, "id");
|
|
381
|
-
/**
|
|
382
|
-
* Playlist name.
|
|
383
|
-
*/
|
|
384
|
-
__publicField(this, "name");
|
|
385
|
-
/**
|
|
386
|
-
* Playlist URL.
|
|
387
|
-
*/
|
|
388
|
-
__publicField(this, "url");
|
|
389
|
-
/**
|
|
390
|
-
* Playlist thumbnail.
|
|
391
|
-
*/
|
|
392
|
-
__publicField(this, "thumbnail");
|
|
393
|
-
__privateAdd(this, _metadata);
|
|
394
|
-
__privateAdd(this, _member);
|
|
395
283
|
if (!Array.isArray(playlist.songs) || !playlist.songs.length) throw new DisTubeError("EMPTY_PLAYLIST");
|
|
396
284
|
this.source = playlist.source.toLowerCase();
|
|
397
285
|
this.songs = playlist.songs;
|
|
@@ -419,11 +307,11 @@ var _Playlist = class _Playlist {
|
|
|
419
307
|
* User requested.
|
|
420
308
|
*/
|
|
421
309
|
get member() {
|
|
422
|
-
return
|
|
310
|
+
return this.#member;
|
|
423
311
|
}
|
|
424
312
|
set member(member) {
|
|
425
313
|
if (!isMemberInstance(member)) return;
|
|
426
|
-
|
|
314
|
+
this.#member = member;
|
|
427
315
|
this.songs.forEach((s) => s.member = this.member);
|
|
428
316
|
}
|
|
429
317
|
/**
|
|
@@ -436,24 +324,89 @@ var _Playlist = class _Playlist {
|
|
|
436
324
|
* Optional metadata that can be used to identify the playlist.
|
|
437
325
|
*/
|
|
438
326
|
get metadata() {
|
|
439
|
-
return
|
|
327
|
+
return this.#metadata;
|
|
440
328
|
}
|
|
441
329
|
set metadata(metadata) {
|
|
442
|
-
|
|
330
|
+
this.#metadata = metadata;
|
|
443
331
|
this.songs.forEach((s) => s.metadata = metadata);
|
|
444
332
|
}
|
|
445
333
|
toString() {
|
|
446
334
|
return `${this.name} (${this.songs.length} songs)`;
|
|
447
335
|
}
|
|
448
336
|
};
|
|
449
|
-
_metadata = new WeakMap();
|
|
450
|
-
_member = new WeakMap();
|
|
451
|
-
__name(_Playlist, "Playlist");
|
|
452
|
-
var Playlist = _Playlist;
|
|
453
337
|
|
|
454
338
|
// src/struct/Song.ts
|
|
455
|
-
var
|
|
456
|
-
|
|
339
|
+
var Song = class {
|
|
340
|
+
static {
|
|
341
|
+
__name(this, "Song");
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* The source of this song info
|
|
345
|
+
*/
|
|
346
|
+
source;
|
|
347
|
+
/**
|
|
348
|
+
* Song ID.
|
|
349
|
+
*/
|
|
350
|
+
id;
|
|
351
|
+
/**
|
|
352
|
+
* Song name.
|
|
353
|
+
*/
|
|
354
|
+
name;
|
|
355
|
+
/**
|
|
356
|
+
* Indicates if the song is an active live.
|
|
357
|
+
*/
|
|
358
|
+
isLive;
|
|
359
|
+
/**
|
|
360
|
+
* Song duration.
|
|
361
|
+
*/
|
|
362
|
+
duration;
|
|
363
|
+
/**
|
|
364
|
+
* Formatted duration string (`hh:mm:ss`, `mm:ss` or `Live`).
|
|
365
|
+
*/
|
|
366
|
+
formattedDuration;
|
|
367
|
+
/**
|
|
368
|
+
* Song URL.
|
|
369
|
+
*/
|
|
370
|
+
url;
|
|
371
|
+
/**
|
|
372
|
+
* Song thumbnail.
|
|
373
|
+
*/
|
|
374
|
+
thumbnail;
|
|
375
|
+
/**
|
|
376
|
+
* Song view count
|
|
377
|
+
*/
|
|
378
|
+
views;
|
|
379
|
+
/**
|
|
380
|
+
* Song like count
|
|
381
|
+
*/
|
|
382
|
+
likes;
|
|
383
|
+
/**
|
|
384
|
+
* Song dislike count
|
|
385
|
+
*/
|
|
386
|
+
dislikes;
|
|
387
|
+
/**
|
|
388
|
+
* Song repost (share) count
|
|
389
|
+
*/
|
|
390
|
+
reposts;
|
|
391
|
+
/**
|
|
392
|
+
* Song uploader
|
|
393
|
+
*/
|
|
394
|
+
uploader;
|
|
395
|
+
/**
|
|
396
|
+
* Whether or not an age-restricted content
|
|
397
|
+
*/
|
|
398
|
+
ageRestricted;
|
|
399
|
+
/**
|
|
400
|
+
* Stream info
|
|
401
|
+
*/
|
|
402
|
+
stream;
|
|
403
|
+
/**
|
|
404
|
+
* The plugin that created this song
|
|
405
|
+
*/
|
|
406
|
+
plugin;
|
|
407
|
+
#metadata;
|
|
408
|
+
#member;
|
|
409
|
+
#playlist;
|
|
457
410
|
/**
|
|
458
411
|
* Create a Song
|
|
459
412
|
*
|
|
@@ -461,73 +414,6 @@ var _Song = class _Song {
|
|
|
461
414
|
* @param options - Optional data
|
|
462
415
|
*/
|
|
463
416
|
constructor(info, { member, metadata } = {}) {
|
|
464
|
-
/**
|
|
465
|
-
* The source of this song info
|
|
466
|
-
*/
|
|
467
|
-
__publicField(this, "source");
|
|
468
|
-
/**
|
|
469
|
-
* Song ID.
|
|
470
|
-
*/
|
|
471
|
-
__publicField(this, "id");
|
|
472
|
-
/**
|
|
473
|
-
* Song name.
|
|
474
|
-
*/
|
|
475
|
-
__publicField(this, "name");
|
|
476
|
-
/**
|
|
477
|
-
* Indicates if the song is an active live.
|
|
478
|
-
*/
|
|
479
|
-
__publicField(this, "isLive");
|
|
480
|
-
/**
|
|
481
|
-
* Song duration.
|
|
482
|
-
*/
|
|
483
|
-
__publicField(this, "duration");
|
|
484
|
-
/**
|
|
485
|
-
* Formatted duration string (`hh:mm:ss`, `mm:ss` or `Live`).
|
|
486
|
-
*/
|
|
487
|
-
__publicField(this, "formattedDuration");
|
|
488
|
-
/**
|
|
489
|
-
* Song URL.
|
|
490
|
-
*/
|
|
491
|
-
__publicField(this, "url");
|
|
492
|
-
/**
|
|
493
|
-
* Song thumbnail.
|
|
494
|
-
*/
|
|
495
|
-
__publicField(this, "thumbnail");
|
|
496
|
-
/**
|
|
497
|
-
* Song view count
|
|
498
|
-
*/
|
|
499
|
-
__publicField(this, "views");
|
|
500
|
-
/**
|
|
501
|
-
* Song like count
|
|
502
|
-
*/
|
|
503
|
-
__publicField(this, "likes");
|
|
504
|
-
/**
|
|
505
|
-
* Song dislike count
|
|
506
|
-
*/
|
|
507
|
-
__publicField(this, "dislikes");
|
|
508
|
-
/**
|
|
509
|
-
* Song repost (share) count
|
|
510
|
-
*/
|
|
511
|
-
__publicField(this, "reposts");
|
|
512
|
-
/**
|
|
513
|
-
* Song uploader
|
|
514
|
-
*/
|
|
515
|
-
__publicField(this, "uploader");
|
|
516
|
-
/**
|
|
517
|
-
* Whether or not an age-restricted content
|
|
518
|
-
*/
|
|
519
|
-
__publicField(this, "ageRestricted");
|
|
520
|
-
/**
|
|
521
|
-
* Stream info
|
|
522
|
-
*/
|
|
523
|
-
__publicField(this, "stream");
|
|
524
|
-
/**
|
|
525
|
-
* The plugin that created this song
|
|
526
|
-
*/
|
|
527
|
-
__publicField(this, "plugin");
|
|
528
|
-
__privateAdd(this, _metadata2);
|
|
529
|
-
__privateAdd(this, _member2);
|
|
530
|
-
__privateAdd(this, _playlist);
|
|
531
417
|
this.source = info.source.toLowerCase();
|
|
532
418
|
this.metadata = metadata;
|
|
533
419
|
this.member = member;
|
|
@@ -554,21 +440,21 @@ var _Song = class _Song {
|
|
|
554
440
|
* The playlist this song belongs to
|
|
555
441
|
*/
|
|
556
442
|
get playlist() {
|
|
557
|
-
return
|
|
443
|
+
return this.#playlist;
|
|
558
444
|
}
|
|
559
445
|
set playlist(playlist) {
|
|
560
446
|
if (!(playlist instanceof Playlist)) throw new DisTubeError("INVALID_TYPE", "Playlist", playlist, "Song#playlist");
|
|
561
|
-
|
|
447
|
+
this.#playlist = playlist;
|
|
562
448
|
this.member = playlist.member;
|
|
563
449
|
}
|
|
564
450
|
/**
|
|
565
451
|
* User requested to play this song.
|
|
566
452
|
*/
|
|
567
453
|
get member() {
|
|
568
|
-
return
|
|
454
|
+
return this.#member;
|
|
569
455
|
}
|
|
570
456
|
set member(member) {
|
|
571
|
-
if (isMemberInstance(member))
|
|
457
|
+
if (isMemberInstance(member)) this.#member = member;
|
|
572
458
|
}
|
|
573
459
|
/**
|
|
574
460
|
* User requested to play this song.
|
|
@@ -581,25 +467,23 @@ var _Song = class _Song {
|
|
|
581
467
|
* {@link DisTube#play} method.
|
|
582
468
|
*/
|
|
583
469
|
get metadata() {
|
|
584
|
-
return
|
|
470
|
+
return this.#metadata;
|
|
585
471
|
}
|
|
586
472
|
set metadata(metadata) {
|
|
587
|
-
|
|
473
|
+
this.#metadata = metadata;
|
|
588
474
|
}
|
|
589
475
|
toString() {
|
|
590
476
|
return this.name || this.url || this.id || "Unknown";
|
|
591
477
|
}
|
|
592
478
|
};
|
|
593
|
-
_metadata2 = new WeakMap();
|
|
594
|
-
_member2 = new WeakMap();
|
|
595
|
-
_playlist = new WeakMap();
|
|
596
|
-
__name(_Song, "Song");
|
|
597
|
-
var Song = _Song;
|
|
598
479
|
|
|
599
480
|
// src/core/DisTubeBase.ts
|
|
600
|
-
var
|
|
481
|
+
var DisTubeBase = class {
|
|
482
|
+
static {
|
|
483
|
+
__name(this, "DisTubeBase");
|
|
484
|
+
}
|
|
485
|
+
distube;
|
|
601
486
|
constructor(distube) {
|
|
602
|
-
__publicField(this, "distube");
|
|
603
487
|
this.distube = distube;
|
|
604
488
|
}
|
|
605
489
|
/**
|
|
@@ -663,27 +547,26 @@ var _DisTubeBase = class _DisTubeBase {
|
|
|
663
547
|
return this.distube.plugins;
|
|
664
548
|
}
|
|
665
549
|
};
|
|
666
|
-
__name(_DisTubeBase, "DisTubeBase");
|
|
667
|
-
var DisTubeBase = _DisTubeBase;
|
|
668
550
|
|
|
669
551
|
// src/core/DisTubeVoice.ts
|
|
670
552
|
var import_discord = require("discord.js");
|
|
671
553
|
var import_tiny_typed_emitter = require("tiny-typed-emitter");
|
|
672
554
|
var import_voice = require("@discordjs/voice");
|
|
673
|
-
var
|
|
674
|
-
|
|
555
|
+
var DisTubeVoice = class extends import_tiny_typed_emitter.TypedEmitter {
|
|
556
|
+
static {
|
|
557
|
+
__name(this, "DisTubeVoice");
|
|
558
|
+
}
|
|
559
|
+
id;
|
|
560
|
+
voices;
|
|
561
|
+
audioPlayer;
|
|
562
|
+
connection;
|
|
563
|
+
emittedError;
|
|
564
|
+
isDisconnected = false;
|
|
565
|
+
stream;
|
|
566
|
+
#channel;
|
|
567
|
+
#volume = 100;
|
|
675
568
|
constructor(voiceManager, channel) {
|
|
676
569
|
super();
|
|
677
|
-
__privateAdd(this, _DisTubeVoice_instances);
|
|
678
|
-
__publicField(this, "id");
|
|
679
|
-
__publicField(this, "voices");
|
|
680
|
-
__publicField(this, "audioPlayer");
|
|
681
|
-
__publicField(this, "connection");
|
|
682
|
-
__publicField(this, "emittedError");
|
|
683
|
-
__publicField(this, "isDisconnected", false);
|
|
684
|
-
__publicField(this, "stream");
|
|
685
|
-
__privateAdd(this, _channel);
|
|
686
|
-
__privateAdd(this, _volume, 100);
|
|
687
570
|
this.voices = voiceManager;
|
|
688
571
|
this.id = channel.guildId;
|
|
689
572
|
this.channel = channel;
|
|
@@ -726,17 +609,17 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
726
609
|
return this.connection?.joinConfig?.channelId ?? void 0;
|
|
727
610
|
}
|
|
728
611
|
get channel() {
|
|
729
|
-
if (!this.channelId) return
|
|
730
|
-
if (
|
|
612
|
+
if (!this.channelId) return this.#channel;
|
|
613
|
+
if (this.#channel?.id === this.channelId) return this.#channel;
|
|
731
614
|
const channel = this.voices.client.channels.cache.get(this.channelId);
|
|
732
|
-
if (!channel) return
|
|
615
|
+
if (!channel) return this.#channel;
|
|
733
616
|
for (const type of import_discord.Constants.VoiceBasedChannelTypes) {
|
|
734
617
|
if (channel.type === type) {
|
|
735
|
-
|
|
618
|
+
this.#channel = channel;
|
|
736
619
|
return channel;
|
|
737
620
|
}
|
|
738
621
|
}
|
|
739
|
-
return
|
|
622
|
+
return this.#channel;
|
|
740
623
|
}
|
|
741
624
|
set channel(channel) {
|
|
742
625
|
if (!isSupportedVoiceChannel(channel)) {
|
|
@@ -749,8 +632,16 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
749
632
|
if (channel.full) throw new DisTubeError("VOICE_FULL");
|
|
750
633
|
else throw new DisTubeError("VOICE_MISSING_PERMS");
|
|
751
634
|
}
|
|
752
|
-
this.connection =
|
|
753
|
-
|
|
635
|
+
this.connection = this.#join(channel);
|
|
636
|
+
this.#channel = channel;
|
|
637
|
+
}
|
|
638
|
+
#join(channel) {
|
|
639
|
+
return (0, import_voice.joinVoiceChannel)({
|
|
640
|
+
channelId: channel.id,
|
|
641
|
+
guildId: this.id,
|
|
642
|
+
adapterCreator: channel.guild.voiceAdapterCreator,
|
|
643
|
+
group: channel.client.user?.id
|
|
644
|
+
});
|
|
754
645
|
}
|
|
755
646
|
/**
|
|
756
647
|
* Join a voice channel with this connection
|
|
@@ -795,6 +686,10 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
795
686
|
* @param dtStream - DisTubeStream
|
|
796
687
|
*/
|
|
797
688
|
play(dtStream) {
|
|
689
|
+
if (!checkEncryptionLibraries()) {
|
|
690
|
+
dtStream.kill();
|
|
691
|
+
throw new DisTubeError("ENCRYPTION_LIBRARIES_MISSING");
|
|
692
|
+
}
|
|
798
693
|
this.emittedError = false;
|
|
799
694
|
dtStream.on("error", (error) => {
|
|
800
695
|
if (this.emittedError || error.code === "ERR_STREAM_PREMATURE_CLOSE") return;
|
|
@@ -804,7 +699,7 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
804
699
|
if (this.audioPlayer.state.status !== import_voice.AudioPlayerStatus.Paused) this.audioPlayer.play(dtStream.audioResource);
|
|
805
700
|
this.stream?.kill();
|
|
806
701
|
this.stream = dtStream;
|
|
807
|
-
this.volume =
|
|
702
|
+
this.volume = this.#volume;
|
|
808
703
|
dtStream.spawn();
|
|
809
704
|
}
|
|
810
705
|
set volume(volume) {
|
|
@@ -814,14 +709,14 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
814
709
|
if (volume < 0) {
|
|
815
710
|
throw new DisTubeError("NUMBER_COMPARE", "Volume", "bigger or equal to", 0);
|
|
816
711
|
}
|
|
817
|
-
|
|
818
|
-
this.stream?.setVolume(Math.pow(
|
|
712
|
+
this.#volume = volume;
|
|
713
|
+
this.stream?.setVolume(Math.pow(this.#volume / 100, 0.5 / Math.log10(2)));
|
|
819
714
|
}
|
|
820
715
|
/**
|
|
821
716
|
* Get or set the volume percentage
|
|
822
717
|
*/
|
|
823
718
|
get volume() {
|
|
824
|
-
return
|
|
719
|
+
return this.#volume;
|
|
825
720
|
}
|
|
826
721
|
/**
|
|
827
722
|
* Playback duration of the audio resource in seconds
|
|
@@ -888,19 +783,6 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
888
783
|
return this.channel?.guild?.members?.me?.voice;
|
|
889
784
|
}
|
|
890
785
|
};
|
|
891
|
-
_channel = new WeakMap();
|
|
892
|
-
_volume = new WeakMap();
|
|
893
|
-
_DisTubeVoice_instances = new WeakSet();
|
|
894
|
-
join_fn = /* @__PURE__ */ __name(function(channel) {
|
|
895
|
-
return (0, import_voice.joinVoiceChannel)({
|
|
896
|
-
channelId: channel.id,
|
|
897
|
-
guildId: this.id,
|
|
898
|
-
adapterCreator: channel.guild.voiceAdapterCreator,
|
|
899
|
-
group: channel.client.user?.id
|
|
900
|
-
});
|
|
901
|
-
}, "#join");
|
|
902
|
-
__name(_DisTubeVoice, "DisTubeVoice");
|
|
903
|
-
var DisTubeVoice = _DisTubeVoice;
|
|
904
786
|
|
|
905
787
|
// src/core/DisTubeStream.ts
|
|
906
788
|
var import_stream = require("stream");
|
|
@@ -927,8 +809,15 @@ var checkFFmpeg = /* @__PURE__ */ __name((distube) => {
|
|
|
927
809
|
}
|
|
928
810
|
checked = true;
|
|
929
811
|
}, "checkFFmpeg");
|
|
930
|
-
var
|
|
931
|
-
|
|
812
|
+
var DisTubeStream = class extends import_tiny_typed_emitter2.TypedEmitter {
|
|
813
|
+
static {
|
|
814
|
+
__name(this, "DisTubeStream");
|
|
815
|
+
}
|
|
816
|
+
#ffmpegPath;
|
|
817
|
+
#opts;
|
|
818
|
+
process;
|
|
819
|
+
stream;
|
|
820
|
+
audioResource;
|
|
932
821
|
/**
|
|
933
822
|
* Create a DisTubeStream to play with {@link DisTubeVoice}
|
|
934
823
|
* @param url - Stream URL
|
|
@@ -936,11 +825,6 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
936
825
|
*/
|
|
937
826
|
constructor(url, options) {
|
|
938
827
|
super();
|
|
939
|
-
__privateAdd(this, _ffmpegPath);
|
|
940
|
-
__privateAdd(this, _opts);
|
|
941
|
-
__publicField(this, "process");
|
|
942
|
-
__publicField(this, "stream");
|
|
943
|
-
__publicField(this, "audioResource");
|
|
944
828
|
const { ffmpeg, seek } = options;
|
|
945
829
|
const opts = {
|
|
946
830
|
reconnect: 1,
|
|
@@ -964,13 +848,13 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
964
848
|
opts.reconnect_delay_max = null;
|
|
965
849
|
opts.i = fileUrl.hostname + fileUrl.pathname;
|
|
966
850
|
}
|
|
967
|
-
|
|
968
|
-
|
|
851
|
+
this.#ffmpegPath = ffmpeg.path;
|
|
852
|
+
this.#opts = [
|
|
969
853
|
...Object.entries(opts).flatMap(
|
|
970
854
|
([key, value]) => Array.isArray(value) ? value.filter(Boolean).map((v) => [`-${key}`, String(v)]) : value == null || value === false ? [] : [value === true ? `-${key}` : [`-${key}`, String(value)]]
|
|
971
855
|
).flat(),
|
|
972
856
|
"pipe:1"
|
|
973
|
-
]
|
|
857
|
+
];
|
|
974
858
|
this.stream = new VolumeTransformer();
|
|
975
859
|
this.stream.on("close", () => this.kill()).on("error", (err) => {
|
|
976
860
|
this.debug(`[stream] error: ${err.message}`);
|
|
@@ -979,8 +863,8 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
979
863
|
this.audioResource = (0, import_voice2.createAudioResource)(this.stream, { inputType: import_voice2.StreamType.Raw, inlineVolume: false });
|
|
980
864
|
}
|
|
981
865
|
spawn() {
|
|
982
|
-
this.debug(`[process] spawn: ${
|
|
983
|
-
this.process = (0, import_child_process.spawn)(
|
|
866
|
+
this.debug(`[process] spawn: ${this.#ffmpegPath} ${this.#opts.join(" ")}`);
|
|
867
|
+
this.process = (0, import_child_process.spawn)(this.#ffmpegPath, this.#opts, {
|
|
984
868
|
stdio: ["ignore", "pipe", "pipe"],
|
|
985
869
|
shell: false,
|
|
986
870
|
windowsHide: true
|
|
@@ -1017,17 +901,13 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
1017
901
|
if (this.process && !this.process.killed) this.process.kill("SIGKILL");
|
|
1018
902
|
}
|
|
1019
903
|
};
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
__name(
|
|
1023
|
-
var DisTubeStream = _DisTubeStream;
|
|
1024
|
-
var _VolumeTransformer = class _VolumeTransformer extends import_stream.Transform {
|
|
1025
|
-
constructor() {
|
|
1026
|
-
super(...arguments);
|
|
1027
|
-
__publicField(this, "buffer", Buffer.allocUnsafe(0));
|
|
1028
|
-
__publicField(this, "extrema", [-Math.pow(2, 16 - 1), Math.pow(2, 16 - 1) - 1]);
|
|
1029
|
-
__publicField(this, "vol", 1);
|
|
904
|
+
var VolumeTransformer = class extends import_stream.Transform {
|
|
905
|
+
static {
|
|
906
|
+
__name(this, "VolumeTransformer");
|
|
1030
907
|
}
|
|
908
|
+
buffer = Buffer.allocUnsafe(0);
|
|
909
|
+
extrema = [-Math.pow(2, 16 - 1), Math.pow(2, 16 - 1) - 1];
|
|
910
|
+
vol = 1;
|
|
1031
911
|
_transform(newChunk, _encoding, done) {
|
|
1032
912
|
const { vol } = this;
|
|
1033
913
|
if (vol === 1) {
|
|
@@ -1048,17 +928,13 @@ var _VolumeTransformer = class _VolumeTransformer extends import_stream.Transfor
|
|
|
1048
928
|
done();
|
|
1049
929
|
}
|
|
1050
930
|
};
|
|
1051
|
-
__name(_VolumeTransformer, "VolumeTransformer");
|
|
1052
|
-
var VolumeTransformer = _VolumeTransformer;
|
|
1053
931
|
|
|
1054
932
|
// src/core/DisTubeHandler.ts
|
|
1055
933
|
var import_undici = require("undici");
|
|
1056
934
|
var REDIRECT_CODES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
1057
|
-
var
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
super(...arguments);
|
|
1061
|
-
__privateAdd(this, _DisTubeHandler_instances);
|
|
935
|
+
var DisTubeHandler = class extends DisTubeBase {
|
|
936
|
+
static {
|
|
937
|
+
__name(this, "DisTubeHandler");
|
|
1062
938
|
}
|
|
1063
939
|
/**
|
|
1064
940
|
* Resolve a url or a supported object to a {@link Song} or {@link Playlist}
|
|
@@ -1075,15 +951,16 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1075
951
|
}
|
|
1076
952
|
if (typeof input === "string") {
|
|
1077
953
|
if (isURL(input)) {
|
|
1078
|
-
const plugin = await this._getPluginFromURL(input) || await this._getPluginFromURL(await this.followRedirectLink(input));
|
|
954
|
+
const plugin = await this._getPluginFromURL(input) || await this._getPluginFromURL(input = await this.followRedirectLink(input));
|
|
1079
955
|
if (!plugin) throw new DisTubeError("NOT_SUPPORTED_URL");
|
|
1080
956
|
this.debug(`[${plugin.constructor.name}] Resolving from url: ${input}`);
|
|
1081
957
|
return plugin.resolve(input, options);
|
|
1082
958
|
}
|
|
1083
959
|
try {
|
|
1084
|
-
const song = await
|
|
960
|
+
const song = await this.#searchSong(input, options);
|
|
1085
961
|
if (song) return song;
|
|
1086
962
|
} catch {
|
|
963
|
+
throw new DisTubeError("NO_RESULT", input);
|
|
1087
964
|
}
|
|
1088
965
|
}
|
|
1089
966
|
throw new DisTubeError("CANNOT_RESOLVE_SONG", input);
|
|
@@ -1102,6 +979,19 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1102
979
|
}
|
|
1103
980
|
return null;
|
|
1104
981
|
}
|
|
982
|
+
async #searchSong(query, options = {}, getStreamURL = false) {
|
|
983
|
+
const plugins = this.plugins.filter((p) => p.type === "extractor" /* EXTRACTOR */);
|
|
984
|
+
if (!plugins.length) throw new DisTubeError("NO_EXTRACTOR_PLUGIN");
|
|
985
|
+
for (const plugin of plugins) {
|
|
986
|
+
this.debug(`[${plugin.constructor.name}] Searching for song: ${query}`);
|
|
987
|
+
const result = await plugin.searchSong(query, options);
|
|
988
|
+
if (result) {
|
|
989
|
+
if (getStreamURL && result.stream.playFromSource) result.stream.url = await plugin.getStreamURL(result);
|
|
990
|
+
return result;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
return null;
|
|
994
|
+
}
|
|
1105
995
|
/**
|
|
1106
996
|
* Get {@link Song}'s stream info and attach it to the song.
|
|
1107
997
|
* @param song - A Song
|
|
@@ -1123,7 +1013,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1123
1013
|
this.debug(`[${plugin.constructor.name}] Creating search query for: ${song}`);
|
|
1124
1014
|
const query = await plugin.createSearchQuery(song);
|
|
1125
1015
|
if (!query) throw new DisTubeError("CANNOT_GET_SEARCH_QUERY", song.toString());
|
|
1126
|
-
const altSong = await
|
|
1016
|
+
const altSong = await this.#searchSong(query, { metadata: song.metadata, member: song.member }, true);
|
|
1127
1017
|
if (!altSong || !altSong.stream.playFromSource) throw new DisTubeError("NO_RESULT", query || song.toString());
|
|
1128
1018
|
song.stream.song = altSong;
|
|
1129
1019
|
}
|
|
@@ -1133,7 +1023,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1133
1023
|
const res = await (0, import_undici.request)(url, {
|
|
1134
1024
|
method: "HEAD",
|
|
1135
1025
|
headers: {
|
|
1136
|
-
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
1026
|
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.3"
|
|
1137
1027
|
}
|
|
1138
1028
|
});
|
|
1139
1029
|
if (REDIRECT_CODES.has(res.statusCode ?? 200)) {
|
|
@@ -1144,37 +1034,22 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1144
1034
|
return url;
|
|
1145
1035
|
}
|
|
1146
1036
|
};
|
|
1147
|
-
_DisTubeHandler_instances = new WeakSet();
|
|
1148
|
-
searchSong_fn = /* @__PURE__ */ __name(async function(query, options = {}, getStreamURL = false) {
|
|
1149
|
-
for (const plugin of this.plugins) {
|
|
1150
|
-
if (plugin.type === "extractor" /* EXTRACTOR */) {
|
|
1151
|
-
this.debug(`[${plugin.constructor.name}] Searching for song: ${query}`);
|
|
1152
|
-
const result = await plugin.searchSong(query, options);
|
|
1153
|
-
if (result) {
|
|
1154
|
-
if (getStreamURL && result.stream.playFromSource) result.stream.url = await plugin.getStreamURL(result);
|
|
1155
|
-
return result;
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
return null;
|
|
1160
|
-
}, "#searchSong");
|
|
1161
|
-
__name(_DisTubeHandler, "DisTubeHandler");
|
|
1162
|
-
var DisTubeHandler = _DisTubeHandler;
|
|
1163
1037
|
|
|
1164
1038
|
// src/core/DisTubeOptions.ts
|
|
1165
|
-
var
|
|
1166
|
-
|
|
1039
|
+
var Options = class {
|
|
1040
|
+
static {
|
|
1041
|
+
__name(this, "Options");
|
|
1042
|
+
}
|
|
1043
|
+
plugins;
|
|
1044
|
+
emitNewSongOnly;
|
|
1045
|
+
savePreviousSongs;
|
|
1046
|
+
customFilters;
|
|
1047
|
+
nsfw;
|
|
1048
|
+
emitAddSongWhenCreatingQueue;
|
|
1049
|
+
emitAddListWhenCreatingQueue;
|
|
1050
|
+
joinNewVoiceChannel;
|
|
1051
|
+
ffmpeg;
|
|
1167
1052
|
constructor(options) {
|
|
1168
|
-
__privateAdd(this, _Options_instances);
|
|
1169
|
-
__publicField(this, "plugins");
|
|
1170
|
-
__publicField(this, "emitNewSongOnly");
|
|
1171
|
-
__publicField(this, "savePreviousSongs");
|
|
1172
|
-
__publicField(this, "customFilters");
|
|
1173
|
-
__publicField(this, "nsfw");
|
|
1174
|
-
__publicField(this, "emitAddSongWhenCreatingQueue");
|
|
1175
|
-
__publicField(this, "emitAddListWhenCreatingQueue");
|
|
1176
|
-
__publicField(this, "joinNewVoiceChannel");
|
|
1177
|
-
__publicField(this, "ffmpeg");
|
|
1178
1053
|
if (typeof options !== "object" || Array.isArray(options)) {
|
|
1179
1054
|
throw new DisTubeError("INVALID_TYPE", "object", options, "DisTubeOptions");
|
|
1180
1055
|
}
|
|
@@ -1187,89 +1062,86 @@ var _Options = class _Options {
|
|
|
1187
1062
|
this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;
|
|
1188
1063
|
this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;
|
|
1189
1064
|
this.joinNewVoiceChannel = opts.joinNewVoiceChannel;
|
|
1190
|
-
this.ffmpeg =
|
|
1065
|
+
this.ffmpeg = this.#ffmpegOption(options);
|
|
1191
1066
|
checkInvalidKey(opts, this, "DisTubeOptions");
|
|
1192
|
-
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
throw new DisTubeError("INVALID_TYPE", "object", value, `DisTubeOptions.${key}`);
|
|
1067
|
+
this.#validateOptions();
|
|
1068
|
+
}
|
|
1069
|
+
#validateOptions(options = this) {
|
|
1070
|
+
const booleanOptions = /* @__PURE__ */ new Set([
|
|
1071
|
+
"emitNewSongOnly",
|
|
1072
|
+
"savePreviousSongs",
|
|
1073
|
+
"joinNewVoiceChannel",
|
|
1074
|
+
"nsfw",
|
|
1075
|
+
"emitAddSongWhenCreatingQueue",
|
|
1076
|
+
"emitAddListWhenCreatingQueue"
|
|
1077
|
+
]);
|
|
1078
|
+
const numberOptions = /* @__PURE__ */ new Set();
|
|
1079
|
+
const stringOptions = /* @__PURE__ */ new Set();
|
|
1080
|
+
const objectOptions = /* @__PURE__ */ new Set(["customFilters", "ffmpeg"]);
|
|
1081
|
+
const optionalOptions = /* @__PURE__ */ new Set(["customFilters"]);
|
|
1082
|
+
for (const [key, value] of Object.entries(options)) {
|
|
1083
|
+
if (value === void 0 && optionalOptions.has(key)) continue;
|
|
1084
|
+
if (key === "plugins" && !Array.isArray(value)) {
|
|
1085
|
+
throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", value, `DisTubeOptions.${key}`);
|
|
1086
|
+
} else if (booleanOptions.has(key)) {
|
|
1087
|
+
if (typeof value !== "boolean") {
|
|
1088
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", value, `DisTubeOptions.${key}`);
|
|
1089
|
+
}
|
|
1090
|
+
} else if (numberOptions.has(key)) {
|
|
1091
|
+
if (typeof value !== "number" || isNaN(value)) {
|
|
1092
|
+
throw new DisTubeError("INVALID_TYPE", "number", value, `DisTubeOptions.${key}`);
|
|
1093
|
+
}
|
|
1094
|
+
} else if (stringOptions.has(key)) {
|
|
1095
|
+
if (typeof value !== "string") {
|
|
1096
|
+
throw new DisTubeError("INVALID_TYPE", "string", value, `DisTubeOptions.${key}`);
|
|
1097
|
+
}
|
|
1098
|
+
} else if (objectOptions.has(key)) {
|
|
1099
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
1100
|
+
throw new DisTubeError("INVALID_TYPE", "object", value, `DisTubeOptions.${key}`);
|
|
1101
|
+
}
|
|
1228
1102
|
}
|
|
1229
1103
|
}
|
|
1230
1104
|
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
if (opts.ffmpeg.args.output) args.output = opts.ffmpeg.args.output;
|
|
1238
|
-
}
|
|
1239
|
-
const path = opts.ffmpeg?.path ?? "ffmpeg";
|
|
1240
|
-
if (typeof path !== "string") {
|
|
1241
|
-
throw new DisTubeError("INVALID_TYPE", "string", path, "DisTubeOptions.ffmpeg.path");
|
|
1242
|
-
}
|
|
1243
|
-
for (const [key, value] of Object.entries(args)) {
|
|
1244
|
-
if (typeof value !== "object" || Array.isArray(value)) {
|
|
1245
|
-
throw new DisTubeError("INVALID_TYPE", "object", value, `DisTubeOptions.ffmpeg.${key}`);
|
|
1105
|
+
#ffmpegOption(opts) {
|
|
1106
|
+
const args = { global: {}, input: {}, output: {} };
|
|
1107
|
+
if (opts.ffmpeg?.args) {
|
|
1108
|
+
if (opts.ffmpeg.args.global) args.global = opts.ffmpeg.args.global;
|
|
1109
|
+
if (opts.ffmpeg.args.input) args.input = opts.ffmpeg.args.input;
|
|
1110
|
+
if (opts.ffmpeg.args.output) args.output = opts.ffmpeg.args.output;
|
|
1246
1111
|
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1112
|
+
const path = opts.ffmpeg?.path ?? "ffmpeg";
|
|
1113
|
+
if (typeof path !== "string") {
|
|
1114
|
+
throw new DisTubeError("INVALID_TYPE", "string", path, "DisTubeOptions.ffmpeg.path");
|
|
1115
|
+
}
|
|
1116
|
+
for (const [key, value] of Object.entries(args)) {
|
|
1117
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
1118
|
+
throw new DisTubeError("INVALID_TYPE", "object", value, `DisTubeOptions.ffmpeg.${key}`);
|
|
1119
|
+
}
|
|
1120
|
+
for (const [k, v] of Object.entries(value)) {
|
|
1121
|
+
if (typeof v !== "string" && typeof v !== "number" && typeof v !== "boolean" && !Array.isArray(v) && v !== null && v !== void 0) {
|
|
1122
|
+
throw new DisTubeError(
|
|
1123
|
+
"INVALID_TYPE",
|
|
1124
|
+
["string", "number", "boolean", "Array<string | null | undefined>", "null", "undefined"],
|
|
1125
|
+
v,
|
|
1126
|
+
`DisTubeOptions.ffmpeg.${key}.${k}`
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1255
1129
|
}
|
|
1256
1130
|
}
|
|
1131
|
+
return { path, args };
|
|
1257
1132
|
}
|
|
1258
|
-
|
|
1259
|
-
}, "#ffmpegOption");
|
|
1260
|
-
__name(_Options, "Options");
|
|
1261
|
-
var Options = _Options;
|
|
1133
|
+
};
|
|
1262
1134
|
|
|
1263
1135
|
// src/core/manager/BaseManager.ts
|
|
1264
1136
|
var import_discord2 = require("discord.js");
|
|
1265
|
-
var
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
/**
|
|
1269
|
-
* The collection of items for this manager.
|
|
1270
|
-
*/
|
|
1271
|
-
__publicField(this, "collection", new import_discord2.Collection());
|
|
1137
|
+
var BaseManager = class extends DisTubeBase {
|
|
1138
|
+
static {
|
|
1139
|
+
__name(this, "BaseManager");
|
|
1272
1140
|
}
|
|
1141
|
+
/**
|
|
1142
|
+
* The collection of items for this manager.
|
|
1143
|
+
*/
|
|
1144
|
+
collection = new import_discord2.Collection();
|
|
1273
1145
|
/**
|
|
1274
1146
|
* The size of the collection.
|
|
1275
1147
|
*/
|
|
@@ -1277,11 +1149,12 @@ var _BaseManager = class _BaseManager extends DisTubeBase {
|
|
|
1277
1149
|
return this.collection.size;
|
|
1278
1150
|
}
|
|
1279
1151
|
};
|
|
1280
|
-
__name(_BaseManager, "BaseManager");
|
|
1281
|
-
var BaseManager = _BaseManager;
|
|
1282
1152
|
|
|
1283
1153
|
// src/core/manager/GuildIdManager.ts
|
|
1284
|
-
var
|
|
1154
|
+
var GuildIdManager = class extends BaseManager {
|
|
1155
|
+
static {
|
|
1156
|
+
__name(this, "GuildIdManager");
|
|
1157
|
+
}
|
|
1285
1158
|
add(idOrInstance, data) {
|
|
1286
1159
|
const id = resolveGuildId(idOrInstance);
|
|
1287
1160
|
const existing = this.get(id);
|
|
@@ -1299,15 +1172,16 @@ var _GuildIdManager = class _GuildIdManager extends BaseManager {
|
|
|
1299
1172
|
return this.collection.has(resolveGuildId(idOrInstance));
|
|
1300
1173
|
}
|
|
1301
1174
|
};
|
|
1302
|
-
__name(_GuildIdManager, "GuildIdManager");
|
|
1303
|
-
var GuildIdManager = _GuildIdManager;
|
|
1304
1175
|
|
|
1305
1176
|
// src/core/manager/DisTubeVoiceManager.ts
|
|
1306
1177
|
var import_voice3 = require("@discordjs/voice");
|
|
1307
|
-
var
|
|
1178
|
+
var DisTubeVoiceManager = class extends GuildIdManager {
|
|
1179
|
+
static {
|
|
1180
|
+
__name(this, "DisTubeVoiceManager");
|
|
1181
|
+
}
|
|
1308
1182
|
/**
|
|
1309
1183
|
* Create a {@link DisTubeVoice} instance
|
|
1310
|
-
* @param channel - A voice
|
|
1184
|
+
* @param channel - A voice channel to join
|
|
1311
1185
|
*/
|
|
1312
1186
|
create(channel) {
|
|
1313
1187
|
const existing = this.get(channel.guildId);
|
|
@@ -1345,21 +1219,36 @@ var _DisTubeVoiceManager = class _DisTubeVoiceManager extends GuildIdManager {
|
|
|
1345
1219
|
}
|
|
1346
1220
|
}
|
|
1347
1221
|
};
|
|
1348
|
-
__name(_DisTubeVoiceManager, "DisTubeVoiceManager");
|
|
1349
|
-
var DisTubeVoiceManager = _DisTubeVoiceManager;
|
|
1350
1222
|
|
|
1351
1223
|
// src/core/manager/FilterManager.ts
|
|
1352
|
-
var
|
|
1353
|
-
|
|
1224
|
+
var FilterManager = class extends BaseManager {
|
|
1225
|
+
static {
|
|
1226
|
+
__name(this, "FilterManager");
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* The queue to manage
|
|
1230
|
+
*/
|
|
1231
|
+
queue;
|
|
1354
1232
|
constructor(queue) {
|
|
1355
1233
|
super(queue.distube);
|
|
1356
|
-
__privateAdd(this, _FilterManager_instances);
|
|
1357
|
-
/**
|
|
1358
|
-
* The queue to manage
|
|
1359
|
-
*/
|
|
1360
|
-
__publicField(this, "queue");
|
|
1361
1234
|
this.queue = queue;
|
|
1362
1235
|
}
|
|
1236
|
+
#resolve(filter) {
|
|
1237
|
+
if (typeof filter === "object" && typeof filter.name === "string" && typeof filter.value === "string") {
|
|
1238
|
+
return filter;
|
|
1239
|
+
}
|
|
1240
|
+
if (typeof filter === "string" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter)) {
|
|
1241
|
+
return {
|
|
1242
|
+
name: filter,
|
|
1243
|
+
value: this.distube.filters[filter]
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
throw new DisTubeError("INVALID_TYPE", "FilterResolvable", filter, "filter");
|
|
1247
|
+
}
|
|
1248
|
+
#apply() {
|
|
1249
|
+
this.queue._beginTime = this.queue.currentTime;
|
|
1250
|
+
this.queue.play(false);
|
|
1251
|
+
}
|
|
1363
1252
|
/**
|
|
1364
1253
|
* Enable a filter or multiple filters to the manager
|
|
1365
1254
|
* @param filterOrFilters - The filter or filters to enable
|
|
@@ -1368,14 +1257,14 @@ var _FilterManager = class _FilterManager extends BaseManager {
|
|
|
1368
1257
|
add(filterOrFilters, override = false) {
|
|
1369
1258
|
if (Array.isArray(filterOrFilters)) {
|
|
1370
1259
|
for (const filter of filterOrFilters) {
|
|
1371
|
-
const ft =
|
|
1260
|
+
const ft = this.#resolve(filter);
|
|
1372
1261
|
if (override || !this.has(ft)) this.collection.set(ft.name, ft);
|
|
1373
1262
|
}
|
|
1374
1263
|
} else {
|
|
1375
|
-
const ft =
|
|
1264
|
+
const ft = this.#resolve(filterOrFilters);
|
|
1376
1265
|
if (override || !this.has(ft)) this.collection.set(ft.name, ft);
|
|
1377
1266
|
}
|
|
1378
|
-
|
|
1267
|
+
this.#apply();
|
|
1379
1268
|
return this;
|
|
1380
1269
|
}
|
|
1381
1270
|
/**
|
|
@@ -1392,20 +1281,23 @@ var _FilterManager = class _FilterManager extends BaseManager {
|
|
|
1392
1281
|
if (!Array.isArray(filters)) throw new DisTubeError("INVALID_TYPE", "Array<FilterResolvable>", filters, "filters");
|
|
1393
1282
|
this.collection.clear();
|
|
1394
1283
|
for (const f of filters) {
|
|
1395
|
-
const filter =
|
|
1284
|
+
const filter = this.#resolve(f);
|
|
1396
1285
|
this.collection.set(filter.name, filter);
|
|
1397
1286
|
}
|
|
1398
|
-
|
|
1287
|
+
this.#apply();
|
|
1399
1288
|
return this;
|
|
1400
1289
|
}
|
|
1290
|
+
#removeFn(f) {
|
|
1291
|
+
return this.collection.delete(this.#resolve(f).name);
|
|
1292
|
+
}
|
|
1401
1293
|
/**
|
|
1402
1294
|
* Disable a filter or multiple filters
|
|
1403
1295
|
* @param filterOrFilters - The filter or filters to disable
|
|
1404
1296
|
*/
|
|
1405
1297
|
remove(filterOrFilters) {
|
|
1406
|
-
if (Array.isArray(filterOrFilters)) filterOrFilters.forEach((f) =>
|
|
1407
|
-
else
|
|
1408
|
-
|
|
1298
|
+
if (Array.isArray(filterOrFilters)) filterOrFilters.forEach((f) => this.#removeFn(f));
|
|
1299
|
+
else this.#removeFn(filterOrFilters);
|
|
1300
|
+
this.#apply();
|
|
1409
1301
|
return this;
|
|
1410
1302
|
}
|
|
1411
1303
|
/**
|
|
@@ -1413,7 +1305,7 @@ var _FilterManager = class _FilterManager extends BaseManager {
|
|
|
1413
1305
|
* @param filter - The filter to check
|
|
1414
1306
|
*/
|
|
1415
1307
|
has(filter) {
|
|
1416
|
-
return this.collection.has(typeof filter === "string" ? filter :
|
|
1308
|
+
return this.collection.has(typeof filter === "string" ? filter : this.#resolve(filter).name);
|
|
1417
1309
|
}
|
|
1418
1310
|
/**
|
|
1419
1311
|
* Array of enabled filter names
|
|
@@ -1434,35 +1326,11 @@ var _FilterManager = class _FilterManager extends BaseManager {
|
|
|
1434
1326
|
return this.names.toString();
|
|
1435
1327
|
}
|
|
1436
1328
|
};
|
|
1437
|
-
_FilterManager_instances = new WeakSet();
|
|
1438
|
-
resolve_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1439
|
-
if (typeof filter === "object" && typeof filter.name === "string" && typeof filter.value === "string") {
|
|
1440
|
-
return filter;
|
|
1441
|
-
}
|
|
1442
|
-
if (typeof filter === "string" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter)) {
|
|
1443
|
-
return {
|
|
1444
|
-
name: filter,
|
|
1445
|
-
value: this.distube.filters[filter]
|
|
1446
|
-
};
|
|
1447
|
-
}
|
|
1448
|
-
throw new DisTubeError("INVALID_TYPE", "FilterResolvable", filter, "filter");
|
|
1449
|
-
}, "#resolve");
|
|
1450
|
-
apply_fn = /* @__PURE__ */ __name(function() {
|
|
1451
|
-
this.queue._beginTime = this.queue.currentTime;
|
|
1452
|
-
this.queue.play(false);
|
|
1453
|
-
}, "#apply");
|
|
1454
|
-
removeFn_fn = /* @__PURE__ */ __name(function(f) {
|
|
1455
|
-
return this.collection.delete(__privateMethod(this, _FilterManager_instances, resolve_fn).call(this, f).name);
|
|
1456
|
-
}, "#removeFn");
|
|
1457
|
-
__name(_FilterManager, "FilterManager");
|
|
1458
|
-
var FilterManager = _FilterManager;
|
|
1459
1329
|
|
|
1460
1330
|
// src/core/manager/QueueManager.ts
|
|
1461
|
-
var
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
super(...arguments);
|
|
1465
|
-
__privateAdd(this, _QueueManager_instances);
|
|
1331
|
+
var QueueManager = class extends GuildIdManager {
|
|
1332
|
+
static {
|
|
1333
|
+
__name(this, "QueueManager");
|
|
1466
1334
|
}
|
|
1467
1335
|
/**
|
|
1468
1336
|
* Create a {@link Queue}
|
|
@@ -1480,7 +1348,7 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1480
1348
|
checkFFmpeg(this.distube);
|
|
1481
1349
|
this.debug(`[QueueManager] Joining voice channel: ${channel.id}`);
|
|
1482
1350
|
await voice.join();
|
|
1483
|
-
|
|
1351
|
+
this.#voiceEventHandler(queue);
|
|
1484
1352
|
this.add(queue.id, queue);
|
|
1485
1353
|
this.emit("initQueue" /* INIT_QUEUE */, queue);
|
|
1486
1354
|
return queue;
|
|
@@ -1488,6 +1356,106 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1488
1356
|
queue._taskQueue.resolve();
|
|
1489
1357
|
}
|
|
1490
1358
|
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Listen to DisTubeVoice events and handle the Queue
|
|
1361
|
+
* @param queue - Queue
|
|
1362
|
+
*/
|
|
1363
|
+
#voiceEventHandler(queue) {
|
|
1364
|
+
queue._listeners = {
|
|
1365
|
+
disconnect: /* @__PURE__ */ __name((error) => {
|
|
1366
|
+
queue.remove();
|
|
1367
|
+
this.emit("disconnect" /* DISCONNECT */, queue);
|
|
1368
|
+
if (error) this.emitError(error, queue, queue.songs?.[0]);
|
|
1369
|
+
}, "disconnect"),
|
|
1370
|
+
error: /* @__PURE__ */ __name((error) => this.#handlePlayingError(queue, error), "error"),
|
|
1371
|
+
finish: /* @__PURE__ */ __name(() => this.#handleSongFinish(queue), "finish")
|
|
1372
|
+
};
|
|
1373
|
+
for (const event of objectKeys(queue._listeners)) {
|
|
1374
|
+
queue.voice.on(event, queue._listeners[event]);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Whether or not emit playSong event
|
|
1379
|
+
* @param queue - Queue
|
|
1380
|
+
*/
|
|
1381
|
+
#emitPlaySong(queue) {
|
|
1382
|
+
if (!this.options.emitNewSongOnly) return true;
|
|
1383
|
+
if (queue.repeatMode === 1 /* SONG */) return queue._next || queue._prev;
|
|
1384
|
+
return queue.songs[0].id !== queue.songs[1].id;
|
|
1385
|
+
}
|
|
1386
|
+
/**
|
|
1387
|
+
* Handle the queue when a Song finish
|
|
1388
|
+
* @param queue - queue
|
|
1389
|
+
*/
|
|
1390
|
+
async #handleSongFinish(queue) {
|
|
1391
|
+
this.debug(`[QueueManager] Handling song finish: ${queue.id}`);
|
|
1392
|
+
const song = queue.songs[0];
|
|
1393
|
+
this.emit("finishSong" /* FINISH_SONG */, queue, queue.songs[0]);
|
|
1394
|
+
await queue._taskQueue.queuing();
|
|
1395
|
+
try {
|
|
1396
|
+
if (queue.stopped) return;
|
|
1397
|
+
if (queue.repeatMode === 2 /* QUEUE */ && !queue._prev) queue.songs.push(song);
|
|
1398
|
+
if (queue._prev) {
|
|
1399
|
+
if (queue.repeatMode === 2 /* QUEUE */) queue.songs.unshift(queue.songs.pop());
|
|
1400
|
+
else queue.songs.unshift(queue.previousSongs.pop());
|
|
1401
|
+
}
|
|
1402
|
+
if (queue.songs.length <= 1 && (queue._next || queue.repeatMode === 0 /* DISABLED */)) {
|
|
1403
|
+
if (queue.autoplay) {
|
|
1404
|
+
try {
|
|
1405
|
+
this.debug(`[QueueManager] Adding related song: ${queue.id}`);
|
|
1406
|
+
await queue.addRelatedSong();
|
|
1407
|
+
} catch (e) {
|
|
1408
|
+
this.debug(`[${queue.id}] Add related song error: ${e.message}`);
|
|
1409
|
+
this.emit("noRelated" /* NO_RELATED */, queue, e);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
if (queue.songs.length <= 1) {
|
|
1413
|
+
this.debug(`[${queue.id}] Queue is empty, stopping...`);
|
|
1414
|
+
if (!queue.autoplay) this.emit("finish" /* FINISH */, queue);
|
|
1415
|
+
queue.remove();
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
const emitPlaySong = this.#emitPlaySong(queue);
|
|
1420
|
+
if (!queue._prev && (queue.repeatMode !== 1 /* SONG */ || queue._next)) {
|
|
1421
|
+
const prev = queue.songs.shift();
|
|
1422
|
+
if (this.options.savePreviousSongs) queue.previousSongs.push(prev);
|
|
1423
|
+
else queue.previousSongs.push({ id: prev.id });
|
|
1424
|
+
}
|
|
1425
|
+
queue._next = queue._prev = false;
|
|
1426
|
+
queue._beginTime = 0;
|
|
1427
|
+
if (song !== queue.songs[0]) {
|
|
1428
|
+
const playedSong = song.stream.playFromSource ? song : song.stream.song;
|
|
1429
|
+
if (playedSong?.stream.playFromSource) delete playedSong.stream.url;
|
|
1430
|
+
}
|
|
1431
|
+
await this.playSong(queue, emitPlaySong);
|
|
1432
|
+
} finally {
|
|
1433
|
+
queue._taskQueue.resolve();
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* Handle error while playing
|
|
1438
|
+
* @param queue - queue
|
|
1439
|
+
* @param error - error
|
|
1440
|
+
*/
|
|
1441
|
+
#handlePlayingError(queue, error) {
|
|
1442
|
+
const song = queue.songs.shift();
|
|
1443
|
+
try {
|
|
1444
|
+
error.name = "PlayingError";
|
|
1445
|
+
} catch {
|
|
1446
|
+
}
|
|
1447
|
+
this.debug(`[${queue.id}] Error while playing: ${error.stack || error.message}`);
|
|
1448
|
+
this.emitError(error, queue, song);
|
|
1449
|
+
if (queue.songs.length > 0) {
|
|
1450
|
+
this.debug(`[${queue.id}] Playing next song: ${queue.songs[0]}`);
|
|
1451
|
+
queue._next = queue._prev = false;
|
|
1452
|
+
queue._beginTime = 0;
|
|
1453
|
+
this.playSong(queue);
|
|
1454
|
+
} else {
|
|
1455
|
+
this.debug(`[${queue.id}] Queue is empty, stopping...`);
|
|
1456
|
+
queue.stop();
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1491
1459
|
/**
|
|
1492
1460
|
* Play a song on voice connection with queue properties
|
|
1493
1461
|
* @param queue - The guild queue to play
|
|
@@ -1524,113 +1492,83 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1524
1492
|
queue.voice.play(dtStream);
|
|
1525
1493
|
if (emitPlaySong) this.emit("playSong" /* PLAY_SONG */, queue, song);
|
|
1526
1494
|
} catch (e) {
|
|
1527
|
-
|
|
1495
|
+
this.#handlePlayingError(queue, e);
|
|
1528
1496
|
}
|
|
1529
1497
|
}
|
|
1530
1498
|
};
|
|
1531
|
-
_QueueManager_instances = new WeakSet();
|
|
1532
|
-
/**
|
|
1533
|
-
* Listen to DisTubeVoice events and handle the Queue
|
|
1534
|
-
* @param queue - Queue
|
|
1535
|
-
*/
|
|
1536
|
-
voiceEventHandler_fn = /* @__PURE__ */ __name(function(queue) {
|
|
1537
|
-
queue._listeners = {
|
|
1538
|
-
disconnect: /* @__PURE__ */ __name((error) => {
|
|
1539
|
-
queue.remove();
|
|
1540
|
-
this.emit("disconnect" /* DISCONNECT */, queue);
|
|
1541
|
-
if (error) this.emitError(error, queue, queue.songs?.[0]);
|
|
1542
|
-
}, "disconnect"),
|
|
1543
|
-
error: /* @__PURE__ */ __name((error) => __privateMethod(this, _QueueManager_instances, handlePlayingError_fn).call(this, queue, error), "error"),
|
|
1544
|
-
finish: /* @__PURE__ */ __name(() => __privateMethod(this, _QueueManager_instances, handleSongFinish_fn).call(this, queue), "finish")
|
|
1545
|
-
};
|
|
1546
|
-
for (const event of objectKeys(queue._listeners)) {
|
|
1547
|
-
queue.voice.on(event, queue._listeners[event]);
|
|
1548
|
-
}
|
|
1549
|
-
}, "#voiceEventHandler");
|
|
1550
|
-
/**
|
|
1551
|
-
* Whether or not emit playSong event
|
|
1552
|
-
* @param queue - Queue
|
|
1553
|
-
*/
|
|
1554
|
-
emitPlaySong_fn = /* @__PURE__ */ __name(function(queue) {
|
|
1555
|
-
if (!this.options.emitNewSongOnly) return true;
|
|
1556
|
-
if (queue.repeatMode === 1 /* SONG */) return queue._next || queue._prev;
|
|
1557
|
-
return queue.songs[0].id !== queue.songs[1].id;
|
|
1558
|
-
}, "#emitPlaySong");
|
|
1559
|
-
handleSongFinish_fn = /* @__PURE__ */ __name(async function(queue) {
|
|
1560
|
-
this.debug(`[QueueManager] Handling song finish: ${queue.id}`);
|
|
1561
|
-
const song = queue.songs[0];
|
|
1562
|
-
this.emit("finishSong" /* FINISH_SONG */, queue, queue.songs[0]);
|
|
1563
|
-
await queue._taskQueue.queuing();
|
|
1564
|
-
try {
|
|
1565
|
-
if (queue.stopped) return;
|
|
1566
|
-
if (queue.repeatMode === 2 /* QUEUE */ && !queue._prev) queue.songs.push(song);
|
|
1567
|
-
if (queue._prev) {
|
|
1568
|
-
if (queue.repeatMode === 2 /* QUEUE */) queue.songs.unshift(queue.songs.pop());
|
|
1569
|
-
else queue.songs.unshift(queue.previousSongs.pop());
|
|
1570
|
-
}
|
|
1571
|
-
if (queue.songs.length <= 1 && (queue._next || queue.repeatMode === 0 /* DISABLED */)) {
|
|
1572
|
-
if (queue.autoplay) {
|
|
1573
|
-
try {
|
|
1574
|
-
this.debug(`[QueueManager] Adding related song: ${queue.id}`);
|
|
1575
|
-
await queue.addRelatedSong();
|
|
1576
|
-
} catch (e) {
|
|
1577
|
-
this.debug(`[${queue.id}] Add related song error: ${e.message}`);
|
|
1578
|
-
this.emit("noRelated" /* NO_RELATED */, queue, e);
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
if (queue.songs.length <= 1) {
|
|
1582
|
-
this.debug(`[${queue.id}] Queue is empty, stopping...`);
|
|
1583
|
-
if (!queue.autoplay) this.emit("finish" /* FINISH */, queue);
|
|
1584
|
-
queue.remove();
|
|
1585
|
-
return;
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
|
-
const emitPlaySong = __privateMethod(this, _QueueManager_instances, emitPlaySong_fn).call(this, queue);
|
|
1589
|
-
if (!queue._prev && (queue.repeatMode !== 1 /* SONG */ || queue._next)) {
|
|
1590
|
-
const prev = queue.songs.shift();
|
|
1591
|
-
if (this.options.savePreviousSongs) queue.previousSongs.push(prev);
|
|
1592
|
-
else queue.previousSongs.push({ id: prev.id });
|
|
1593
|
-
}
|
|
1594
|
-
queue._next = queue._prev = false;
|
|
1595
|
-
queue._beginTime = 0;
|
|
1596
|
-
if (song !== queue.songs[0]) {
|
|
1597
|
-
const playedSong = song.stream.playFromSource ? song : song.stream.song;
|
|
1598
|
-
if (playedSong?.stream.playFromSource) delete playedSong.stream.url;
|
|
1599
|
-
}
|
|
1600
|
-
await this.playSong(queue, emitPlaySong);
|
|
1601
|
-
} finally {
|
|
1602
|
-
queue._taskQueue.resolve();
|
|
1603
|
-
}
|
|
1604
|
-
}, "#handleSongFinish");
|
|
1605
|
-
/**
|
|
1606
|
-
* Handle error while playing
|
|
1607
|
-
* @param queue - queue
|
|
1608
|
-
* @param error - error
|
|
1609
|
-
*/
|
|
1610
|
-
handlePlayingError_fn = /* @__PURE__ */ __name(function(queue, error) {
|
|
1611
|
-
const song = queue.songs.shift();
|
|
1612
|
-
try {
|
|
1613
|
-
error.name = "PlayingError";
|
|
1614
|
-
} catch {
|
|
1615
|
-
}
|
|
1616
|
-
this.debug(`[${queue.id}] Error while playing: ${error.stack || error.message}`);
|
|
1617
|
-
this.emitError(error, queue, song);
|
|
1618
|
-
if (queue.songs.length > 0) {
|
|
1619
|
-
this.debug(`[${queue.id}] Playing next song: ${queue.songs[0]}`);
|
|
1620
|
-
queue._next = queue._prev = false;
|
|
1621
|
-
queue._beginTime = 0;
|
|
1622
|
-
this.playSong(queue);
|
|
1623
|
-
} else {
|
|
1624
|
-
this.debug(`[${queue.id}] Queue is empty, stopping...`);
|
|
1625
|
-
queue.stop();
|
|
1626
|
-
}
|
|
1627
|
-
}, "#handlePlayingError");
|
|
1628
|
-
__name(_QueueManager, "QueueManager");
|
|
1629
|
-
var QueueManager = _QueueManager;
|
|
1630
1499
|
|
|
1631
1500
|
// src/struct/Queue.ts
|
|
1632
|
-
var
|
|
1633
|
-
|
|
1501
|
+
var Queue = class extends DisTubeBase {
|
|
1502
|
+
static {
|
|
1503
|
+
__name(this, "Queue");
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Queue id (Guild id)
|
|
1507
|
+
*/
|
|
1508
|
+
id;
|
|
1509
|
+
/**
|
|
1510
|
+
* Voice connection of this queue.
|
|
1511
|
+
*/
|
|
1512
|
+
voice;
|
|
1513
|
+
/**
|
|
1514
|
+
* List of songs in the queue (The first one is the playing song)
|
|
1515
|
+
*/
|
|
1516
|
+
songs;
|
|
1517
|
+
/**
|
|
1518
|
+
* List of the previous songs.
|
|
1519
|
+
*/
|
|
1520
|
+
previousSongs;
|
|
1521
|
+
/**
|
|
1522
|
+
* Whether stream is currently stopped.
|
|
1523
|
+
*/
|
|
1524
|
+
stopped;
|
|
1525
|
+
/**
|
|
1526
|
+
* Whether or not the stream is currently playing.
|
|
1527
|
+
*/
|
|
1528
|
+
playing;
|
|
1529
|
+
/**
|
|
1530
|
+
* Whether or not the stream is currently paused.
|
|
1531
|
+
*/
|
|
1532
|
+
paused;
|
|
1533
|
+
/**
|
|
1534
|
+
* Type of repeat mode (`0` is disabled, `1` is repeating a song, `2` is repeating
|
|
1535
|
+
* all the queue). Default value: `0` (disabled)
|
|
1536
|
+
*/
|
|
1537
|
+
repeatMode;
|
|
1538
|
+
/**
|
|
1539
|
+
* Whether or not the autoplay mode is enabled. Default value: `false`
|
|
1540
|
+
*/
|
|
1541
|
+
autoplay;
|
|
1542
|
+
/**
|
|
1543
|
+
* FFmpeg arguments for the current queue. Default value is defined with {@link DisTubeOptions}.ffmpeg.args.
|
|
1544
|
+
* `af` output argument will be replaced with {@link Queue#filters} manager
|
|
1545
|
+
*/
|
|
1546
|
+
ffmpegArgs;
|
|
1547
|
+
/**
|
|
1548
|
+
* The text channel of the Queue. (Default: where the first command is called).
|
|
1549
|
+
*/
|
|
1550
|
+
textChannel;
|
|
1551
|
+
#filters;
|
|
1552
|
+
/**
|
|
1553
|
+
* What time in the song to begin (in seconds).
|
|
1554
|
+
*/
|
|
1555
|
+
_beginTime;
|
|
1556
|
+
/**
|
|
1557
|
+
* Whether or not the last song was skipped to next song.
|
|
1558
|
+
*/
|
|
1559
|
+
_next;
|
|
1560
|
+
/**
|
|
1561
|
+
* Whether or not the last song was skipped to previous song.
|
|
1562
|
+
*/
|
|
1563
|
+
_prev;
|
|
1564
|
+
/**
|
|
1565
|
+
* Task queuing system
|
|
1566
|
+
*/
|
|
1567
|
+
_taskQueue;
|
|
1568
|
+
/**
|
|
1569
|
+
* {@link DisTubeVoice} listener
|
|
1570
|
+
*/
|
|
1571
|
+
_listeners;
|
|
1634
1572
|
/**
|
|
1635
1573
|
* Create a queue for the guild
|
|
1636
1574
|
* @param distube - DisTube
|
|
@@ -1639,74 +1577,6 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1639
1577
|
*/
|
|
1640
1578
|
constructor(distube, voice, textChannel) {
|
|
1641
1579
|
super(distube);
|
|
1642
|
-
__privateAdd(this, _Queue_instances);
|
|
1643
|
-
/**
|
|
1644
|
-
* Queue id (Guild id)
|
|
1645
|
-
*/
|
|
1646
|
-
__publicField(this, "id");
|
|
1647
|
-
/**
|
|
1648
|
-
* Voice connection of this queue.
|
|
1649
|
-
*/
|
|
1650
|
-
__publicField(this, "voice");
|
|
1651
|
-
/**
|
|
1652
|
-
* List of songs in the queue (The first one is the playing song)
|
|
1653
|
-
*/
|
|
1654
|
-
__publicField(this, "songs");
|
|
1655
|
-
/**
|
|
1656
|
-
* List of the previous songs.
|
|
1657
|
-
*/
|
|
1658
|
-
__publicField(this, "previousSongs");
|
|
1659
|
-
/**
|
|
1660
|
-
* Whether stream is currently stopped.
|
|
1661
|
-
*/
|
|
1662
|
-
__publicField(this, "stopped");
|
|
1663
|
-
/**
|
|
1664
|
-
* Whether or not the stream is currently playing.
|
|
1665
|
-
*/
|
|
1666
|
-
__publicField(this, "playing");
|
|
1667
|
-
/**
|
|
1668
|
-
* Whether or not the stream is currently paused.
|
|
1669
|
-
*/
|
|
1670
|
-
__publicField(this, "paused");
|
|
1671
|
-
/**
|
|
1672
|
-
* Type of repeat mode (`0` is disabled, `1` is repeating a song, `2` is repeating
|
|
1673
|
-
* all the queue). Default value: `0` (disabled)
|
|
1674
|
-
*/
|
|
1675
|
-
__publicField(this, "repeatMode");
|
|
1676
|
-
/**
|
|
1677
|
-
* Whether or not the autoplay mode is enabled. Default value: `false`
|
|
1678
|
-
*/
|
|
1679
|
-
__publicField(this, "autoplay");
|
|
1680
|
-
/**
|
|
1681
|
-
* FFmpeg arguments for the current queue. Default value is defined with {@link DisTubeOptions}.ffmpeg.args.
|
|
1682
|
-
* `af` output argument will be replaced with {@link Queue#filters} manager
|
|
1683
|
-
*/
|
|
1684
|
-
__publicField(this, "ffmpegArgs");
|
|
1685
|
-
/**
|
|
1686
|
-
* The text channel of the Queue. (Default: where the first command is called).
|
|
1687
|
-
*/
|
|
1688
|
-
__publicField(this, "textChannel");
|
|
1689
|
-
__privateAdd(this, _filters);
|
|
1690
|
-
/**
|
|
1691
|
-
* What time in the song to begin (in seconds).
|
|
1692
|
-
*/
|
|
1693
|
-
__publicField(this, "_beginTime");
|
|
1694
|
-
/**
|
|
1695
|
-
* Whether or not the last song was skipped to next song.
|
|
1696
|
-
*/
|
|
1697
|
-
__publicField(this, "_next");
|
|
1698
|
-
/**
|
|
1699
|
-
* Whether or not the last song was skipped to previous song.
|
|
1700
|
-
*/
|
|
1701
|
-
__publicField(this, "_prev");
|
|
1702
|
-
/**
|
|
1703
|
-
* Task queuing system
|
|
1704
|
-
*/
|
|
1705
|
-
__publicField(this, "_taskQueue");
|
|
1706
|
-
/**
|
|
1707
|
-
* {@link DisTubeVoice} listener
|
|
1708
|
-
*/
|
|
1709
|
-
__publicField(this, "_listeners");
|
|
1710
1580
|
this.voice = voice;
|
|
1711
1581
|
this.id = voice.id;
|
|
1712
1582
|
this.volume = 50;
|
|
@@ -1719,7 +1589,7 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1719
1589
|
this.paused = false;
|
|
1720
1590
|
this.repeatMode = 0 /* DISABLED */;
|
|
1721
1591
|
this.autoplay = false;
|
|
1722
|
-
|
|
1592
|
+
this.#filters = new FilterManager(this);
|
|
1723
1593
|
this._beginTime = 0;
|
|
1724
1594
|
this.textChannel = textChannel;
|
|
1725
1595
|
this._taskQueue = new TaskQueue();
|
|
@@ -1740,7 +1610,7 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1740
1610
|
* The filter manager of the queue
|
|
1741
1611
|
*/
|
|
1742
1612
|
get filters() {
|
|
1743
|
-
return
|
|
1613
|
+
return this.#filters;
|
|
1744
1614
|
}
|
|
1745
1615
|
/**
|
|
1746
1616
|
* Formatted duration string.
|
|
@@ -1805,6 +1675,18 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1805
1675
|
}
|
|
1806
1676
|
return this;
|
|
1807
1677
|
}
|
|
1678
|
+
/**
|
|
1679
|
+
* @returns `true` if the queue is playing
|
|
1680
|
+
*/
|
|
1681
|
+
isPlaying() {
|
|
1682
|
+
return this.playing;
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* @returns `true` if the queue is paused
|
|
1686
|
+
*/
|
|
1687
|
+
isPaused() {
|
|
1688
|
+
return this.paused;
|
|
1689
|
+
}
|
|
1808
1690
|
/**
|
|
1809
1691
|
* Pause the guild stream
|
|
1810
1692
|
* @returns The guild queue
|
|
@@ -1958,6 +1840,11 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1958
1840
|
this.play(false);
|
|
1959
1841
|
return this;
|
|
1960
1842
|
}
|
|
1843
|
+
async #getRelatedSong(current) {
|
|
1844
|
+
const plugin = await this.handler._getPluginFromSong(current);
|
|
1845
|
+
if (plugin) return plugin.getRelatedSongs(current);
|
|
1846
|
+
return [];
|
|
1847
|
+
}
|
|
1961
1848
|
/**
|
|
1962
1849
|
* Add a related song of the playing song to the queue
|
|
1963
1850
|
* @returns The added song
|
|
@@ -1966,11 +1853,11 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1966
1853
|
const current = this.songs?.[0];
|
|
1967
1854
|
if (!current) throw new DisTubeError("NO_PLAYING_SONG");
|
|
1968
1855
|
const prevIds = this.previousSongs.map((p) => p.id);
|
|
1969
|
-
const relatedSongs = (await
|
|
1856
|
+
const relatedSongs = (await this.#getRelatedSong(current)).filter((s) => !prevIds.includes(s.id));
|
|
1970
1857
|
this.debug(`[${this.id}] Getting related songs from: ${current}`);
|
|
1971
1858
|
if (!relatedSongs.length && !current.stream.playFromSource) {
|
|
1972
1859
|
const altSong = current.stream.song;
|
|
1973
|
-
if (altSong) relatedSongs.push(...(await
|
|
1860
|
+
if (altSong) relatedSongs.push(...(await this.#getRelatedSong(altSong)).filter((s) => !prevIds.includes(s.id)));
|
|
1974
1861
|
this.debug(`[${this.id}] Getting related songs from streamed song: ${altSong}`);
|
|
1975
1862
|
}
|
|
1976
1863
|
const song = relatedSongs[0];
|
|
@@ -2019,7 +1906,7 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
2019
1906
|
return this.autoplay;
|
|
2020
1907
|
}
|
|
2021
1908
|
/**
|
|
2022
|
-
* Play the queue
|
|
1909
|
+
* Play the first song in the queue
|
|
2023
1910
|
* @param emitPlaySong - Whether or not emit {@link Events.PLAY_SONG} event
|
|
2024
1911
|
*/
|
|
2025
1912
|
play(emitPlaySong = true) {
|
|
@@ -2028,60 +1915,44 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
2028
1915
|
return this.queues.playSong(this, emitPlaySong);
|
|
2029
1916
|
}
|
|
2030
1917
|
};
|
|
2031
|
-
_filters = new WeakMap();
|
|
2032
|
-
_Queue_instances = new WeakSet();
|
|
2033
|
-
getRelatedSong_fn = /* @__PURE__ */ __name(async function(current) {
|
|
2034
|
-
const plugin = await this.handler._getPluginFromSong(current);
|
|
2035
|
-
if (plugin) return plugin.getRelatedSongs(current);
|
|
2036
|
-
return [];
|
|
2037
|
-
}, "#getRelatedSong");
|
|
2038
|
-
__name(_Queue, "Queue");
|
|
2039
|
-
var Queue = _Queue;
|
|
2040
1918
|
|
|
2041
1919
|
// src/struct/Plugin.ts
|
|
2042
|
-
var
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
* DisTube
|
|
2046
|
-
*/
|
|
2047
|
-
__publicField(this, "distube");
|
|
1920
|
+
var Plugin = class {
|
|
1921
|
+
static {
|
|
1922
|
+
__name(this, "Plugin");
|
|
2048
1923
|
}
|
|
1924
|
+
/**
|
|
1925
|
+
* DisTube
|
|
1926
|
+
*/
|
|
1927
|
+
distube;
|
|
2049
1928
|
init(distube) {
|
|
2050
1929
|
this.distube = distube;
|
|
2051
1930
|
}
|
|
2052
1931
|
};
|
|
2053
|
-
__name(_Plugin, "Plugin");
|
|
2054
|
-
var Plugin = _Plugin;
|
|
2055
1932
|
|
|
2056
1933
|
// src/struct/ExtractorPlugin.ts
|
|
2057
|
-
var
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
__publicField(this, "type", "extractor" /* EXTRACTOR */);
|
|
1934
|
+
var ExtractorPlugin = class extends Plugin {
|
|
1935
|
+
static {
|
|
1936
|
+
__name(this, "ExtractorPlugin");
|
|
2061
1937
|
}
|
|
1938
|
+
type = "extractor" /* EXTRACTOR */;
|
|
2062
1939
|
};
|
|
2063
|
-
__name(_ExtractorPlugin, "ExtractorPlugin");
|
|
2064
|
-
var ExtractorPlugin = _ExtractorPlugin;
|
|
2065
1940
|
|
|
2066
1941
|
// src/struct/InfoExtratorPlugin.ts
|
|
2067
|
-
var
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
__publicField(this, "type", "info-extractor" /* INFO_EXTRACTOR */);
|
|
1942
|
+
var InfoExtractorPlugin = class extends Plugin {
|
|
1943
|
+
static {
|
|
1944
|
+
__name(this, "InfoExtractorPlugin");
|
|
2071
1945
|
}
|
|
1946
|
+
type = "info-extractor" /* INFO_EXTRACTOR */;
|
|
2072
1947
|
};
|
|
2073
|
-
__name(_InfoExtractorPlugin, "InfoExtractorPlugin");
|
|
2074
|
-
var InfoExtractorPlugin = _InfoExtractorPlugin;
|
|
2075
1948
|
|
|
2076
1949
|
// src/struct/PlayableExtratorPlugin.ts
|
|
2077
|
-
var
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
__publicField(this, "type", "playable-extractor" /* PLAYABLE_EXTRACTOR */);
|
|
1950
|
+
var PlayableExtractorPlugin = class extends Plugin {
|
|
1951
|
+
static {
|
|
1952
|
+
__name(this, "PlayableExtractorPlugin");
|
|
2081
1953
|
}
|
|
1954
|
+
type = "playable-extractor" /* PLAYABLE_EXTRACTOR */;
|
|
2082
1955
|
};
|
|
2083
|
-
__name(_PlayableExtractorPlugin, "PlayableExtractorPlugin");
|
|
2084
|
-
var PlayableExtractorPlugin = _PlayableExtractorPlugin;
|
|
2085
1956
|
|
|
2086
1957
|
// src/util.ts
|
|
2087
1958
|
var import_url = require("url");
|
|
@@ -2196,12 +2067,134 @@ function isNsfwChannel(channel) {
|
|
|
2196
2067
|
}
|
|
2197
2068
|
__name(isNsfwChannel, "isNsfwChannel");
|
|
2198
2069
|
var isTruthy = /* @__PURE__ */ __name((x) => Boolean(x), "isTruthy");
|
|
2070
|
+
var checkEncryptionLibraries = /* @__PURE__ */ __name(() => {
|
|
2071
|
+
for (const lib of ["sodium-native", "sodium", "libsodium-wrappers", "tweetnacl"]) {
|
|
2072
|
+
try {
|
|
2073
|
+
require(lib);
|
|
2074
|
+
return true;
|
|
2075
|
+
} catch {
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
return false;
|
|
2079
|
+
}, "checkEncryptionLibraries");
|
|
2199
2080
|
|
|
2200
2081
|
// src/DisTube.ts
|
|
2201
2082
|
var import_tiny_typed_emitter3 = require("tiny-typed-emitter");
|
|
2202
|
-
var
|
|
2203
|
-
|
|
2204
|
-
|
|
2083
|
+
var DisTube = class extends import_tiny_typed_emitter3.TypedEmitter {
|
|
2084
|
+
static {
|
|
2085
|
+
__name(this, "DisTube");
|
|
2086
|
+
}
|
|
2087
|
+
/**
|
|
2088
|
+
* @event
|
|
2089
|
+
* Emitted after DisTube add a new playlist to the playing {@link Queue}.
|
|
2090
|
+
* @param queue - The guild queue
|
|
2091
|
+
* @param playlist - Playlist info
|
|
2092
|
+
*/
|
|
2093
|
+
static ["addList" /* ADD_LIST */];
|
|
2094
|
+
/**
|
|
2095
|
+
* @event
|
|
2096
|
+
* Emitted after DisTube add a new song to the playing {@link Queue}.
|
|
2097
|
+
* @param queue - The guild queue
|
|
2098
|
+
* @param song - Added song
|
|
2099
|
+
*/
|
|
2100
|
+
static ["addSong" /* ADD_SONG */];
|
|
2101
|
+
/**
|
|
2102
|
+
* @event
|
|
2103
|
+
* Emitted when a {@link Queue} is deleted with any reasons.
|
|
2104
|
+
* @param queue - The guild queue
|
|
2105
|
+
*/
|
|
2106
|
+
static ["deleteQueue" /* DELETE_QUEUE */];
|
|
2107
|
+
/**
|
|
2108
|
+
* @event
|
|
2109
|
+
* Emitted when the bot is disconnected to a voice channel.
|
|
2110
|
+
* @param queue - The guild queue
|
|
2111
|
+
*/
|
|
2112
|
+
static ["disconnect" /* DISCONNECT */];
|
|
2113
|
+
/**
|
|
2114
|
+
* @event
|
|
2115
|
+
* Emitted when DisTube encounters an error while playing songs.
|
|
2116
|
+
* @param error - error
|
|
2117
|
+
* @param queue - The queue encountered the error
|
|
2118
|
+
* @param song - The playing song when encountered the error
|
|
2119
|
+
*/
|
|
2120
|
+
static ["error" /* ERROR */];
|
|
2121
|
+
/**
|
|
2122
|
+
* @event
|
|
2123
|
+
* Emitted for logging FFmpeg debug information.
|
|
2124
|
+
* @param debug - Debug message string.
|
|
2125
|
+
*/
|
|
2126
|
+
static ["ffmpegDebug" /* FFMPEG_DEBUG */];
|
|
2127
|
+
/**
|
|
2128
|
+
* @event
|
|
2129
|
+
* Emitted to provide debug information from DisTube's operation.
|
|
2130
|
+
* Useful for troubleshooting or logging purposes.
|
|
2131
|
+
*
|
|
2132
|
+
* @param debug - Debug message string.
|
|
2133
|
+
*/
|
|
2134
|
+
static ["debug" /* DEBUG */];
|
|
2135
|
+
/**
|
|
2136
|
+
* @event
|
|
2137
|
+
* Emitted when there is no more song in the queue and {@link Queue#autoplay} is `false`.
|
|
2138
|
+
* @param queue - The guild queue
|
|
2139
|
+
*/
|
|
2140
|
+
static ["finish" /* FINISH */];
|
|
2141
|
+
/**
|
|
2142
|
+
* @event
|
|
2143
|
+
* Emitted when DisTube finished a song.
|
|
2144
|
+
* @param queue - The guild queue
|
|
2145
|
+
* @param song - Finished song
|
|
2146
|
+
*/
|
|
2147
|
+
static ["finishSong" /* FINISH_SONG */];
|
|
2148
|
+
/**
|
|
2149
|
+
* @event
|
|
2150
|
+
* Emitted when DisTube initialize a queue to change queue default properties.
|
|
2151
|
+
* @param queue - The guild queue
|
|
2152
|
+
*/
|
|
2153
|
+
static ["initQueue" /* INIT_QUEUE */];
|
|
2154
|
+
/**
|
|
2155
|
+
* @event
|
|
2156
|
+
* Emitted when {@link Queue#autoplay} is `true`, {@link Queue#songs} is empty, and
|
|
2157
|
+
* DisTube cannot find related songs to play.
|
|
2158
|
+
* @param queue - The guild queue
|
|
2159
|
+
*/
|
|
2160
|
+
static ["noRelated" /* NO_RELATED */];
|
|
2161
|
+
/**
|
|
2162
|
+
* @event
|
|
2163
|
+
* Emitted when DisTube play a song.
|
|
2164
|
+
* If {@link DisTubeOptions}.emitNewSongOnly is `true`, this event is not emitted
|
|
2165
|
+
* when looping a song or next song is the previous one.
|
|
2166
|
+
* @param queue - The guild queue
|
|
2167
|
+
* @param song - Playing song
|
|
2168
|
+
*/
|
|
2169
|
+
static ["playSong" /* PLAY_SONG */];
|
|
2170
|
+
/**
|
|
2171
|
+
* DisTube internal handler
|
|
2172
|
+
*/
|
|
2173
|
+
handler;
|
|
2174
|
+
/**
|
|
2175
|
+
* DisTube options
|
|
2176
|
+
*/
|
|
2177
|
+
options;
|
|
2178
|
+
/**
|
|
2179
|
+
* Discord.js v14 client
|
|
2180
|
+
*/
|
|
2181
|
+
client;
|
|
2182
|
+
/**
|
|
2183
|
+
* Queues manager
|
|
2184
|
+
*/
|
|
2185
|
+
queues;
|
|
2186
|
+
/**
|
|
2187
|
+
* DisTube voice connections manager
|
|
2188
|
+
*/
|
|
2189
|
+
voices;
|
|
2190
|
+
/**
|
|
2191
|
+
* DisTube plugins
|
|
2192
|
+
*/
|
|
2193
|
+
plugins;
|
|
2194
|
+
/**
|
|
2195
|
+
* DisTube ffmpeg audio filters
|
|
2196
|
+
*/
|
|
2197
|
+
filters;
|
|
2205
2198
|
/**
|
|
2206
2199
|
* Create a new DisTube class.
|
|
2207
2200
|
* @throws {@link DisTubeError}
|
|
@@ -2210,35 +2203,6 @@ var _DisTube = class _DisTube extends (_m = import_tiny_typed_emitter3.TypedEmit
|
|
|
2210
2203
|
*/
|
|
2211
2204
|
constructor(client, opts = {}) {
|
|
2212
2205
|
super();
|
|
2213
|
-
__privateAdd(this, _DisTube_instances);
|
|
2214
|
-
/**
|
|
2215
|
-
* DisTube internal handler
|
|
2216
|
-
*/
|
|
2217
|
-
__publicField(this, "handler");
|
|
2218
|
-
/**
|
|
2219
|
-
* DisTube options
|
|
2220
|
-
*/
|
|
2221
|
-
__publicField(this, "options");
|
|
2222
|
-
/**
|
|
2223
|
-
* Discord.js v14 client
|
|
2224
|
-
*/
|
|
2225
|
-
__publicField(this, "client");
|
|
2226
|
-
/**
|
|
2227
|
-
* Queues manager
|
|
2228
|
-
*/
|
|
2229
|
-
__publicField(this, "queues");
|
|
2230
|
-
/**
|
|
2231
|
-
* DisTube voice connections manager
|
|
2232
|
-
*/
|
|
2233
|
-
__publicField(this, "voices");
|
|
2234
|
-
/**
|
|
2235
|
-
* DisTube plugins
|
|
2236
|
-
*/
|
|
2237
|
-
__publicField(this, "plugins");
|
|
2238
|
-
/**
|
|
2239
|
-
* DisTube ffmpeg audio filters
|
|
2240
|
-
*/
|
|
2241
|
-
__publicField(this, "filters");
|
|
2242
2206
|
this.setMaxListeners(1);
|
|
2243
2207
|
if (!isClientInstance(client)) throw new DisTubeError("INVALID_TYPE", "Discord.Client", client, "client");
|
|
2244
2208
|
this.client = client;
|
|
@@ -2314,6 +2278,7 @@ var _DisTube = class _DisTube extends (_m = import_tiny_typed_emitter3.TypedEmit
|
|
|
2314
2278
|
if (queue.playing || this.options.emitAddSongWhenCreatingQueue) this.emit("addSong" /* ADD_SONG */, queue, resolved);
|
|
2315
2279
|
}
|
|
2316
2280
|
if (!queue.playing) await queue.play();
|
|
2281
|
+
else if (skip) await queue.skip();
|
|
2317
2282
|
} catch (e) {
|
|
2318
2283
|
if (!(e instanceof DisTubeError)) {
|
|
2319
2284
|
this.debug(`[${queue.id}] Unexpected error while playing song: ${e.stack || e.message}`);
|
|
@@ -2373,13 +2338,18 @@ ${e.message}`;
|
|
|
2373
2338
|
getQueue(guild) {
|
|
2374
2339
|
return this.queues.get(guild);
|
|
2375
2340
|
}
|
|
2341
|
+
#getQueue(guild) {
|
|
2342
|
+
const queue = this.getQueue(guild);
|
|
2343
|
+
if (!queue) throw new DisTubeError("NO_QUEUE");
|
|
2344
|
+
return queue;
|
|
2345
|
+
}
|
|
2376
2346
|
/**
|
|
2377
2347
|
* Pause the guild stream
|
|
2378
2348
|
* @param guild - The type can be resolved to give a {@link Queue}
|
|
2379
2349
|
* @returns The guild queue
|
|
2380
2350
|
*/
|
|
2381
2351
|
pause(guild) {
|
|
2382
|
-
return
|
|
2352
|
+
return this.#getQueue(guild).pause();
|
|
2383
2353
|
}
|
|
2384
2354
|
/**
|
|
2385
2355
|
* Resume the guild stream
|
|
@@ -2387,14 +2357,14 @@ ${e.message}`;
|
|
|
2387
2357
|
* @returns The guild queue
|
|
2388
2358
|
*/
|
|
2389
2359
|
resume(guild) {
|
|
2390
|
-
return
|
|
2360
|
+
return this.#getQueue(guild).resume();
|
|
2391
2361
|
}
|
|
2392
2362
|
/**
|
|
2393
2363
|
* Stop the guild stream
|
|
2394
2364
|
* @param guild - The type can be resolved to give a {@link Queue}
|
|
2395
2365
|
*/
|
|
2396
2366
|
stop(guild) {
|
|
2397
|
-
return
|
|
2367
|
+
return this.#getQueue(guild).stop();
|
|
2398
2368
|
}
|
|
2399
2369
|
/**
|
|
2400
2370
|
* Set the guild stream's volume
|
|
@@ -2403,7 +2373,7 @@ ${e.message}`;
|
|
|
2403
2373
|
* @returns The guild queue
|
|
2404
2374
|
*/
|
|
2405
2375
|
setVolume(guild, percent) {
|
|
2406
|
-
return
|
|
2376
|
+
return this.#getQueue(guild).setVolume(percent);
|
|
2407
2377
|
}
|
|
2408
2378
|
/**
|
|
2409
2379
|
* Skip the playing song if there is a next song in the queue. <info>If {@link
|
|
@@ -2413,7 +2383,7 @@ ${e.message}`;
|
|
|
2413
2383
|
* @returns The new Song will be played
|
|
2414
2384
|
*/
|
|
2415
2385
|
skip(guild) {
|
|
2416
|
-
return
|
|
2386
|
+
return this.#getQueue(guild).skip();
|
|
2417
2387
|
}
|
|
2418
2388
|
/**
|
|
2419
2389
|
* Play the previous song
|
|
@@ -2421,7 +2391,7 @@ ${e.message}`;
|
|
|
2421
2391
|
* @returns The new Song will be played
|
|
2422
2392
|
*/
|
|
2423
2393
|
previous(guild) {
|
|
2424
|
-
return
|
|
2394
|
+
return this.#getQueue(guild).previous();
|
|
2425
2395
|
}
|
|
2426
2396
|
/**
|
|
2427
2397
|
* Shuffle the guild queue songs
|
|
@@ -2429,7 +2399,7 @@ ${e.message}`;
|
|
|
2429
2399
|
* @returns The guild queue
|
|
2430
2400
|
*/
|
|
2431
2401
|
shuffle(guild) {
|
|
2432
|
-
return
|
|
2402
|
+
return this.#getQueue(guild).shuffle();
|
|
2433
2403
|
}
|
|
2434
2404
|
/**
|
|
2435
2405
|
* Jump to the song number in the queue. The next one is 1, 2,... The previous one
|
|
@@ -2439,7 +2409,7 @@ ${e.message}`;
|
|
|
2439
2409
|
* @returns The new Song will be played
|
|
2440
2410
|
*/
|
|
2441
2411
|
jump(guild, num) {
|
|
2442
|
-
return
|
|
2412
|
+
return this.#getQueue(guild).jump(num);
|
|
2443
2413
|
}
|
|
2444
2414
|
/**
|
|
2445
2415
|
* Set the repeat mode of the guild queue.
|
|
@@ -2449,7 +2419,7 @@ ${e.message}`;
|
|
|
2449
2419
|
* @returns The new repeat mode
|
|
2450
2420
|
*/
|
|
2451
2421
|
setRepeatMode(guild, mode) {
|
|
2452
|
-
return
|
|
2422
|
+
return this.#getQueue(guild).setRepeatMode(mode);
|
|
2453
2423
|
}
|
|
2454
2424
|
/**
|
|
2455
2425
|
* Toggle autoplay mode
|
|
@@ -2457,7 +2427,7 @@ ${e.message}`;
|
|
|
2457
2427
|
* @returns Autoplay mode state
|
|
2458
2428
|
*/
|
|
2459
2429
|
toggleAutoplay(guild) {
|
|
2460
|
-
const queue =
|
|
2430
|
+
const queue = this.#getQueue(guild);
|
|
2461
2431
|
queue.autoplay = !queue.autoplay;
|
|
2462
2432
|
return queue.autoplay;
|
|
2463
2433
|
}
|
|
@@ -2467,7 +2437,7 @@ ${e.message}`;
|
|
|
2467
2437
|
* @returns The guild queue
|
|
2468
2438
|
*/
|
|
2469
2439
|
addRelatedSong(guild) {
|
|
2470
|
-
return
|
|
2440
|
+
return this.#getQueue(guild).addRelatedSong();
|
|
2471
2441
|
}
|
|
2472
2442
|
/**
|
|
2473
2443
|
* Set the playing time to another position
|
|
@@ -2476,7 +2446,7 @@ ${e.message}`;
|
|
|
2476
2446
|
* @returns Seeked queue
|
|
2477
2447
|
*/
|
|
2478
2448
|
seek(guild, time) {
|
|
2479
|
-
return
|
|
2449
|
+
return this.#getQueue(guild).seek(time);
|
|
2480
2450
|
}
|
|
2481
2451
|
/**
|
|
2482
2452
|
* Emit error event
|
|
@@ -2495,97 +2465,9 @@ ${e.message}`;
|
|
|
2495
2465
|
this.emit("debug" /* DEBUG */, message);
|
|
2496
2466
|
}
|
|
2497
2467
|
};
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
if (!queue) throw new DisTubeError("NO_QUEUE");
|
|
2502
|
-
return queue;
|
|
2503
|
-
}, "#getQueue");
|
|
2504
|
-
__name(_DisTube, "DisTube");
|
|
2505
|
-
/**
|
|
2506
|
-
* @event
|
|
2507
|
-
* Emitted after DisTube add a new playlist to the playing {@link Queue}.
|
|
2508
|
-
* @param queue - The guild queue
|
|
2509
|
-
* @param playlist - Playlist info
|
|
2510
|
-
*/
|
|
2511
|
-
__publicField(_DisTube, _l);
|
|
2512
|
-
/**
|
|
2513
|
-
* @event
|
|
2514
|
-
* Emitted after DisTube add a new song to the playing {@link Queue}.
|
|
2515
|
-
* @param queue - The guild queue
|
|
2516
|
-
* @param song - Added song
|
|
2517
|
-
*/
|
|
2518
|
-
__publicField(_DisTube, _k);
|
|
2519
|
-
/**
|
|
2520
|
-
* @event
|
|
2521
|
-
* Emitted when a {@link Queue} is deleted with any reasons.
|
|
2522
|
-
* @param queue - The guild queue
|
|
2523
|
-
*/
|
|
2524
|
-
__publicField(_DisTube, _j);
|
|
2525
|
-
/**
|
|
2526
|
-
* @event
|
|
2527
|
-
* Emitted when the bot is disconnected to a voice channel.
|
|
2528
|
-
* @param queue - The guild queue
|
|
2529
|
-
*/
|
|
2530
|
-
__publicField(_DisTube, _i);
|
|
2531
|
-
/**
|
|
2532
|
-
* @event
|
|
2533
|
-
* Emitted when DisTube encounters an error while playing songs.
|
|
2534
|
-
* @param error - error
|
|
2535
|
-
* @param queue - The queue encountered the error
|
|
2536
|
-
* @param song - The playing song when encountered the error
|
|
2537
|
-
*/
|
|
2538
|
-
__publicField(_DisTube, _h);
|
|
2539
|
-
/**
|
|
2540
|
-
* @event
|
|
2541
|
-
* Emitted for logging FFmpeg debug information.
|
|
2542
|
-
* @param debug - Debug message string.
|
|
2543
|
-
*/
|
|
2544
|
-
__publicField(_DisTube, _g);
|
|
2545
|
-
/**
|
|
2546
|
-
* @event
|
|
2547
|
-
* Emitted to provide debug information from DisTube's operation.
|
|
2548
|
-
* Useful for troubleshooting or logging purposes.
|
|
2549
|
-
*
|
|
2550
|
-
* @param debug - Debug message string.
|
|
2551
|
-
*/
|
|
2552
|
-
__publicField(_DisTube, _f);
|
|
2553
|
-
/**
|
|
2554
|
-
* @event
|
|
2555
|
-
* Emitted when there is no more song in the queue and {@link Queue#autoplay} is `false`.
|
|
2556
|
-
* @param queue - The guild queue
|
|
2557
|
-
*/
|
|
2558
|
-
__publicField(_DisTube, _e);
|
|
2559
|
-
/**
|
|
2560
|
-
* @event
|
|
2561
|
-
* Emitted when DisTube finished a song.
|
|
2562
|
-
* @param queue - The guild queue
|
|
2563
|
-
* @param song - Finished song
|
|
2564
|
-
*/
|
|
2565
|
-
__publicField(_DisTube, _d);
|
|
2566
|
-
/**
|
|
2567
|
-
* @event
|
|
2568
|
-
* Emitted when DisTube initialize a queue to change queue default properties.
|
|
2569
|
-
* @param queue - The guild queue
|
|
2570
|
-
*/
|
|
2571
|
-
__publicField(_DisTube, _c);
|
|
2572
|
-
/**
|
|
2573
|
-
* @event
|
|
2574
|
-
* Emitted when {@link Queue#autoplay} is `true`, {@link Queue#songs} is empty, and
|
|
2575
|
-
* DisTube cannot find related songs to play.
|
|
2576
|
-
* @param queue - The guild queue
|
|
2577
|
-
*/
|
|
2578
|
-
__publicField(_DisTube, _b);
|
|
2579
|
-
/**
|
|
2580
|
-
* @event
|
|
2581
|
-
* Emitted when DisTube play a song.
|
|
2582
|
-
* If {@link DisTubeOptions}.emitNewSongOnly is `true`, this event is not emitted
|
|
2583
|
-
* when looping a song or next song is the previous one.
|
|
2584
|
-
* @param queue - The guild queue
|
|
2585
|
-
* @param song - Playing song
|
|
2586
|
-
*/
|
|
2587
|
-
__publicField(_DisTube, _a);
|
|
2588
|
-
var DisTube = _DisTube;
|
|
2468
|
+
|
|
2469
|
+
// src/index.ts
|
|
2470
|
+
var version = "5.0.3";
|
|
2589
2471
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2590
2472
|
0 && (module.exports = {
|
|
2591
2473
|
BaseManager,
|
|
@@ -2611,6 +2493,7 @@ var DisTube = _DisTube;
|
|
|
2611
2493
|
RepeatMode,
|
|
2612
2494
|
Song,
|
|
2613
2495
|
TaskQueue,
|
|
2496
|
+
checkEncryptionLibraries,
|
|
2614
2497
|
checkFFmpeg,
|
|
2615
2498
|
checkIntents,
|
|
2616
2499
|
checkInvalidKey,
|