distube 5.0.1 → 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 +23 -6
- package/dist/index.js +710 -831
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2463 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +41 -31
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,121 +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.1",
|
|
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: "jest",
|
|
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
|
-
"build:check": "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
|
-
"dev:add-docs-to-worktree": "git worktree add --track -b docs docs origin/docs"
|
|
64
|
-
},
|
|
65
|
-
repository: {
|
|
66
|
-
type: "git",
|
|
67
|
-
url: "git+https://github.com/skick1234/DisTube.git"
|
|
68
|
-
},
|
|
69
|
-
keywords: [
|
|
70
|
-
"youtube",
|
|
71
|
-
"music",
|
|
72
|
-
"discord",
|
|
73
|
-
"discordjs",
|
|
74
|
-
"bot",
|
|
75
|
-
"distube",
|
|
76
|
-
"queue",
|
|
77
|
-
"musicbot",
|
|
78
|
-
"discord-music-bot",
|
|
79
|
-
"music-bot",
|
|
80
|
-
"discord-js"
|
|
81
|
-
],
|
|
82
|
-
author: "Skick (https://github.com/skick1234)",
|
|
83
|
-
license: "MIT",
|
|
84
|
-
bugs: {
|
|
85
|
-
url: "https://github.com/skick1234/DisTube/issues"
|
|
86
|
-
},
|
|
87
|
-
funding: "https://github.com/skick1234/DisTube?sponsor",
|
|
88
|
-
homepage: "https://distube.js.org/",
|
|
89
|
-
dependencies: {
|
|
90
|
-
"tiny-typed-emitter": "^2.1.0",
|
|
91
|
-
undici: "^6.18.2"
|
|
92
|
-
},
|
|
93
|
-
devDependencies: {
|
|
94
|
-
"@babel/core": "^7.24.6",
|
|
95
|
-
"@babel/plugin-transform-class-properties": "^7.24.6",
|
|
96
|
-
"@babel/plugin-transform-object-rest-spread": "^7.24.6",
|
|
97
|
-
"@babel/plugin-transform-private-methods": "^7.24.6",
|
|
98
|
-
"@babel/preset-env": "^7.24.6",
|
|
99
|
-
"@babel/preset-typescript": "^7.24.6",
|
|
100
|
-
"@commitlint/cli": "^19.3.0",
|
|
101
|
-
"@commitlint/config-conventional": "^19.2.2",
|
|
102
|
-
"@discordjs/voice": "^0.17.0",
|
|
103
|
-
"@types/jest": "^29.5.12",
|
|
104
|
-
"@types/node": "^20.14.1",
|
|
105
|
-
"@types/tough-cookie": "^4.0.5",
|
|
106
|
-
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
|
107
|
-
"@typescript-eslint/parser": "^7.12.0",
|
|
108
|
-
"babel-jest": "^29.7.0",
|
|
109
|
-
"discord.js": "^14.15.3",
|
|
110
|
-
eslint: "^8.57.0",
|
|
111
|
-
"eslint-config-distube": "^1.7.0",
|
|
112
|
-
husky: "^9.0.11",
|
|
113
|
-
jest: "^29.7.0",
|
|
114
|
-
"nano-staged": "^0.8.0",
|
|
115
|
-
prettier: "^3.3.0",
|
|
116
|
-
"sodium-native": "^4.1.1",
|
|
117
|
-
"ts-node": "^10.9.2",
|
|
118
|
-
tsup: "^8.1.0",
|
|
119
|
-
typedoc: "^0.25.13",
|
|
120
|
-
"typedoc-material-theme": "^1.0.2",
|
|
121
|
-
typescript: "^5.4.5"
|
|
122
|
-
},
|
|
123
|
-
peerDependencies: {
|
|
124
|
-
"@discordjs/voice": "*",
|
|
125
|
-
"discord.js": "14"
|
|
126
|
-
},
|
|
127
|
-
"nano-staged": {
|
|
128
|
-
"*.ts": [
|
|
129
|
-
"prettier --write",
|
|
130
|
-
"eslint"
|
|
131
|
-
],
|
|
132
|
-
"*.{json,yml,yaml,md}": [
|
|
133
|
-
"prettier --write"
|
|
134
|
-
]
|
|
135
|
-
},
|
|
136
|
-
engines: {
|
|
137
|
-
node: ">=18.17"
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
20
|
|
|
143
21
|
// src/index.ts
|
|
144
22
|
var src_exports = {};
|
|
@@ -166,6 +44,7 @@ __export(src_exports, {
|
|
|
166
44
|
RepeatMode: () => RepeatMode,
|
|
167
45
|
Song: () => Song,
|
|
168
46
|
TaskQueue: () => TaskQueue,
|
|
47
|
+
checkEncryptionLibraries: () => checkEncryptionLibraries,
|
|
169
48
|
checkFFmpeg: () => checkFFmpeg,
|
|
170
49
|
checkIntents: () => checkIntents,
|
|
171
50
|
checkInvalidKey: () => checkInvalidKey,
|
|
@@ -273,6 +152,7 @@ var ERROR_MESSAGES = {
|
|
|
273
152
|
VOICE_DIFFERENT_CLIENT: "Cannot join a voice channel created by a different client",
|
|
274
153
|
FFMPEG_EXITED: /* @__PURE__ */ __name((code) => `ffmpeg exited with code ${code}`, "FFMPEG_EXITED"),
|
|
275
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.",
|
|
276
156
|
NO_QUEUE: "There is no playing queue in this guild",
|
|
277
157
|
QUEUE_EXIST: "This guild has a Queue already",
|
|
278
158
|
QUEUE_STOPPED: "The queue has been stopped already",
|
|
@@ -282,6 +162,7 @@ var ERROR_MESSAGES = {
|
|
|
282
162
|
NO_UP_NEXT: "There is no up next song",
|
|
283
163
|
NO_SONG_POSITION: "Does not have any song at this position",
|
|
284
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",
|
|
285
166
|
NO_RELATED: "Cannot find any related songs",
|
|
286
167
|
CANNOT_PLAY_RELATED: "Cannot play the related song",
|
|
287
168
|
UNAVAILABLE_VIDEO: "This video is unavailable",
|
|
@@ -291,9 +172,9 @@ var ERROR_MESSAGES = {
|
|
|
291
172
|
NOT_SUPPORTED_SONG: /* @__PURE__ */ __name((song) => `There is no plugin supporting this song (${song})`, "NOT_SUPPORTED_SONG"),
|
|
292
173
|
NO_VALID_SONG: "'songs' array does not have any valid Song or url",
|
|
293
174
|
CANNOT_RESOLVE_SONG: /* @__PURE__ */ __name((t) => `Cannot resolve ${(0, import_node_util.inspect)(t)} to a Song`, "CANNOT_RESOLVE_SONG"),
|
|
294
|
-
CANNOT_GET_STREAM_URL: /* @__PURE__ */ __name((song) => `Cannot get stream url
|
|
295
|
-
CANNOT_GET_SEARCH_QUERY: /* @__PURE__ */ __name((song) => `Cannot get search query
|
|
296
|
-
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"),
|
|
297
178
|
NO_STREAM_URL: /* @__PURE__ */ __name((song) => `No stream url attached (${song})`, "NO_STREAM_URL"),
|
|
298
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",
|
|
299
180
|
EMPTY_PLAYLIST: "There is no valid video in the playlist"
|
|
@@ -301,10 +182,13 @@ var ERROR_MESSAGES = {
|
|
|
301
182
|
var haveCode = /* @__PURE__ */ __name((code) => Object.keys(ERROR_MESSAGES).includes(code), "haveCode");
|
|
302
183
|
var parseMessage = /* @__PURE__ */ __name((m, ...args) => typeof m === "string" ? m : m(...args), "parseMessage");
|
|
303
184
|
var getErrorMessage = /* @__PURE__ */ __name((code, ...args) => haveCode(code) ? parseMessage(ERROR_MESSAGES[code], ...args) : args[0], "getErrorMessage");
|
|
304
|
-
var
|
|
185
|
+
var DisTubeError = class _DisTubeError extends Error {
|
|
186
|
+
static {
|
|
187
|
+
__name(this, "DisTubeError");
|
|
188
|
+
}
|
|
189
|
+
errorCode;
|
|
305
190
|
constructor(code, ...args) {
|
|
306
191
|
super(getErrorMessage(code, ...args));
|
|
307
|
-
__publicField(this, "errorCode");
|
|
308
192
|
this.errorCode = code;
|
|
309
193
|
if (Error.captureStackTrace) Error.captureStackTrace(this, _DisTubeError);
|
|
310
194
|
}
|
|
@@ -315,89 +199,87 @@ var _DisTubeError = class _DisTubeError extends Error {
|
|
|
315
199
|
return this.errorCode;
|
|
316
200
|
}
|
|
317
201
|
};
|
|
318
|
-
__name(_DisTubeError, "DisTubeError");
|
|
319
|
-
var DisTubeError = _DisTubeError;
|
|
320
202
|
|
|
321
203
|
// src/struct/TaskQueue.ts
|
|
322
|
-
var
|
|
204
|
+
var Task = class {
|
|
205
|
+
static {
|
|
206
|
+
__name(this, "Task");
|
|
207
|
+
}
|
|
208
|
+
resolve;
|
|
209
|
+
promise;
|
|
323
210
|
constructor() {
|
|
324
|
-
__publicField(this, "resolve");
|
|
325
|
-
__publicField(this, "promise");
|
|
326
211
|
this.promise = new Promise((res) => {
|
|
327
212
|
this.resolve = res;
|
|
328
213
|
});
|
|
329
214
|
}
|
|
330
215
|
};
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
var _TaskQueue = class _TaskQueue {
|
|
335
|
-
constructor() {
|
|
336
|
-
/**
|
|
337
|
-
* The task array
|
|
338
|
-
*/
|
|
339
|
-
__privateAdd(this, _tasks, []);
|
|
216
|
+
var TaskQueue = class {
|
|
217
|
+
static {
|
|
218
|
+
__name(this, "TaskQueue");
|
|
340
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* The task array
|
|
222
|
+
*/
|
|
223
|
+
#tasks = [];
|
|
341
224
|
/**
|
|
342
225
|
* Waits for last task finished and queues a new task
|
|
343
226
|
*/
|
|
344
227
|
queuing() {
|
|
345
|
-
const next = this.remaining ?
|
|
346
|
-
|
|
228
|
+
const next = this.remaining ? this.#tasks[this.#tasks.length - 1].promise : Promise.resolve();
|
|
229
|
+
this.#tasks.push(new Task());
|
|
347
230
|
return next;
|
|
348
231
|
}
|
|
349
232
|
/**
|
|
350
233
|
* Removes the finished task and processes the next task
|
|
351
234
|
*/
|
|
352
235
|
resolve() {
|
|
353
|
-
|
|
236
|
+
this.#tasks.shift()?.resolve();
|
|
354
237
|
}
|
|
355
238
|
/**
|
|
356
239
|
* The remaining number of tasks
|
|
357
240
|
*/
|
|
358
241
|
get remaining() {
|
|
359
|
-
return
|
|
242
|
+
return this.#tasks.length;
|
|
360
243
|
}
|
|
361
244
|
};
|
|
362
|
-
_tasks = new WeakMap();
|
|
363
|
-
__name(_TaskQueue, "TaskQueue");
|
|
364
|
-
var TaskQueue = _TaskQueue;
|
|
365
245
|
|
|
366
246
|
// src/struct/Playlist.ts
|
|
367
|
-
var
|
|
368
|
-
|
|
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;
|
|
369
277
|
/**
|
|
370
278
|
* Create a Playlist
|
|
371
279
|
* @param playlist - Raw playlist info
|
|
372
280
|
* @param options - Optional data
|
|
373
281
|
*/
|
|
374
282
|
constructor(playlist, { member, metadata } = {}) {
|
|
375
|
-
/**
|
|
376
|
-
* Playlist source.
|
|
377
|
-
*/
|
|
378
|
-
__publicField(this, "source");
|
|
379
|
-
/**
|
|
380
|
-
* Songs in the playlist.
|
|
381
|
-
*/
|
|
382
|
-
__publicField(this, "songs");
|
|
383
|
-
/**
|
|
384
|
-
* Playlist ID.
|
|
385
|
-
*/
|
|
386
|
-
__publicField(this, "id");
|
|
387
|
-
/**
|
|
388
|
-
* Playlist name.
|
|
389
|
-
*/
|
|
390
|
-
__publicField(this, "name");
|
|
391
|
-
/**
|
|
392
|
-
* Playlist URL.
|
|
393
|
-
*/
|
|
394
|
-
__publicField(this, "url");
|
|
395
|
-
/**
|
|
396
|
-
* Playlist thumbnail.
|
|
397
|
-
*/
|
|
398
|
-
__publicField(this, "thumbnail");
|
|
399
|
-
__privateAdd(this, _metadata);
|
|
400
|
-
__privateAdd(this, _member);
|
|
401
283
|
if (!Array.isArray(playlist.songs) || !playlist.songs.length) throw new DisTubeError("EMPTY_PLAYLIST");
|
|
402
284
|
this.source = playlist.source.toLowerCase();
|
|
403
285
|
this.songs = playlist.songs;
|
|
@@ -425,11 +307,11 @@ var _Playlist = class _Playlist {
|
|
|
425
307
|
* User requested.
|
|
426
308
|
*/
|
|
427
309
|
get member() {
|
|
428
|
-
return
|
|
310
|
+
return this.#member;
|
|
429
311
|
}
|
|
430
312
|
set member(member) {
|
|
431
313
|
if (!isMemberInstance(member)) return;
|
|
432
|
-
|
|
314
|
+
this.#member = member;
|
|
433
315
|
this.songs.forEach((s) => s.member = this.member);
|
|
434
316
|
}
|
|
435
317
|
/**
|
|
@@ -442,24 +324,89 @@ var _Playlist = class _Playlist {
|
|
|
442
324
|
* Optional metadata that can be used to identify the playlist.
|
|
443
325
|
*/
|
|
444
326
|
get metadata() {
|
|
445
|
-
return
|
|
327
|
+
return this.#metadata;
|
|
446
328
|
}
|
|
447
329
|
set metadata(metadata) {
|
|
448
|
-
|
|
330
|
+
this.#metadata = metadata;
|
|
449
331
|
this.songs.forEach((s) => s.metadata = metadata);
|
|
450
332
|
}
|
|
451
333
|
toString() {
|
|
452
334
|
return `${this.name} (${this.songs.length} songs)`;
|
|
453
335
|
}
|
|
454
336
|
};
|
|
455
|
-
_metadata = new WeakMap();
|
|
456
|
-
_member = new WeakMap();
|
|
457
|
-
__name(_Playlist, "Playlist");
|
|
458
|
-
var Playlist = _Playlist;
|
|
459
337
|
|
|
460
338
|
// src/struct/Song.ts
|
|
461
|
-
var
|
|
462
|
-
|
|
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;
|
|
463
410
|
/**
|
|
464
411
|
* Create a Song
|
|
465
412
|
*
|
|
@@ -467,73 +414,6 @@ var _Song = class _Song {
|
|
|
467
414
|
* @param options - Optional data
|
|
468
415
|
*/
|
|
469
416
|
constructor(info, { member, metadata } = {}) {
|
|
470
|
-
/**
|
|
471
|
-
* The source of this song info
|
|
472
|
-
*/
|
|
473
|
-
__publicField(this, "source");
|
|
474
|
-
/**
|
|
475
|
-
* Song ID.
|
|
476
|
-
*/
|
|
477
|
-
__publicField(this, "id");
|
|
478
|
-
/**
|
|
479
|
-
* Song name.
|
|
480
|
-
*/
|
|
481
|
-
__publicField(this, "name");
|
|
482
|
-
/**
|
|
483
|
-
* Indicates if the song is an active live.
|
|
484
|
-
*/
|
|
485
|
-
__publicField(this, "isLive");
|
|
486
|
-
/**
|
|
487
|
-
* Song duration.
|
|
488
|
-
*/
|
|
489
|
-
__publicField(this, "duration");
|
|
490
|
-
/**
|
|
491
|
-
* Formatted duration string (`hh:mm:ss`, `mm:ss` or `Live`).
|
|
492
|
-
*/
|
|
493
|
-
__publicField(this, "formattedDuration");
|
|
494
|
-
/**
|
|
495
|
-
* Song URL.
|
|
496
|
-
*/
|
|
497
|
-
__publicField(this, "url");
|
|
498
|
-
/**
|
|
499
|
-
* Song thumbnail.
|
|
500
|
-
*/
|
|
501
|
-
__publicField(this, "thumbnail");
|
|
502
|
-
/**
|
|
503
|
-
* Song view count
|
|
504
|
-
*/
|
|
505
|
-
__publicField(this, "views");
|
|
506
|
-
/**
|
|
507
|
-
* Song like count
|
|
508
|
-
*/
|
|
509
|
-
__publicField(this, "likes");
|
|
510
|
-
/**
|
|
511
|
-
* Song dislike count
|
|
512
|
-
*/
|
|
513
|
-
__publicField(this, "dislikes");
|
|
514
|
-
/**
|
|
515
|
-
* Song repost (share) count
|
|
516
|
-
*/
|
|
517
|
-
__publicField(this, "reposts");
|
|
518
|
-
/**
|
|
519
|
-
* Song uploader
|
|
520
|
-
*/
|
|
521
|
-
__publicField(this, "uploader");
|
|
522
|
-
/**
|
|
523
|
-
* Whether or not an age-restricted content
|
|
524
|
-
*/
|
|
525
|
-
__publicField(this, "ageRestricted");
|
|
526
|
-
/**
|
|
527
|
-
* Stream info
|
|
528
|
-
*/
|
|
529
|
-
__publicField(this, "stream");
|
|
530
|
-
/**
|
|
531
|
-
* The plugin that created this song
|
|
532
|
-
*/
|
|
533
|
-
__publicField(this, "plugin");
|
|
534
|
-
__privateAdd(this, _metadata2);
|
|
535
|
-
__privateAdd(this, _member2);
|
|
536
|
-
__privateAdd(this, _playlist);
|
|
537
417
|
this.source = info.source.toLowerCase();
|
|
538
418
|
this.metadata = metadata;
|
|
539
419
|
this.member = member;
|
|
@@ -560,21 +440,21 @@ var _Song = class _Song {
|
|
|
560
440
|
* The playlist this song belongs to
|
|
561
441
|
*/
|
|
562
442
|
get playlist() {
|
|
563
|
-
return
|
|
443
|
+
return this.#playlist;
|
|
564
444
|
}
|
|
565
445
|
set playlist(playlist) {
|
|
566
446
|
if (!(playlist instanceof Playlist)) throw new DisTubeError("INVALID_TYPE", "Playlist", playlist, "Song#playlist");
|
|
567
|
-
|
|
447
|
+
this.#playlist = playlist;
|
|
568
448
|
this.member = playlist.member;
|
|
569
449
|
}
|
|
570
450
|
/**
|
|
571
451
|
* User requested to play this song.
|
|
572
452
|
*/
|
|
573
453
|
get member() {
|
|
574
|
-
return
|
|
454
|
+
return this.#member;
|
|
575
455
|
}
|
|
576
456
|
set member(member) {
|
|
577
|
-
if (isMemberInstance(member))
|
|
457
|
+
if (isMemberInstance(member)) this.#member = member;
|
|
578
458
|
}
|
|
579
459
|
/**
|
|
580
460
|
* User requested to play this song.
|
|
@@ -587,25 +467,23 @@ var _Song = class _Song {
|
|
|
587
467
|
* {@link DisTube#play} method.
|
|
588
468
|
*/
|
|
589
469
|
get metadata() {
|
|
590
|
-
return
|
|
470
|
+
return this.#metadata;
|
|
591
471
|
}
|
|
592
472
|
set metadata(metadata) {
|
|
593
|
-
|
|
473
|
+
this.#metadata = metadata;
|
|
594
474
|
}
|
|
595
475
|
toString() {
|
|
596
476
|
return this.name || this.url || this.id || "Unknown";
|
|
597
477
|
}
|
|
598
478
|
};
|
|
599
|
-
_metadata2 = new WeakMap();
|
|
600
|
-
_member2 = new WeakMap();
|
|
601
|
-
_playlist = new WeakMap();
|
|
602
|
-
__name(_Song, "Song");
|
|
603
|
-
var Song = _Song;
|
|
604
479
|
|
|
605
480
|
// src/core/DisTubeBase.ts
|
|
606
|
-
var
|
|
481
|
+
var DisTubeBase = class {
|
|
482
|
+
static {
|
|
483
|
+
__name(this, "DisTubeBase");
|
|
484
|
+
}
|
|
485
|
+
distube;
|
|
607
486
|
constructor(distube) {
|
|
608
|
-
__publicField(this, "distube");
|
|
609
487
|
this.distube = distube;
|
|
610
488
|
}
|
|
611
489
|
/**
|
|
@@ -669,27 +547,26 @@ var _DisTubeBase = class _DisTubeBase {
|
|
|
669
547
|
return this.distube.plugins;
|
|
670
548
|
}
|
|
671
549
|
};
|
|
672
|
-
__name(_DisTubeBase, "DisTubeBase");
|
|
673
|
-
var DisTubeBase = _DisTubeBase;
|
|
674
550
|
|
|
675
551
|
// src/core/DisTubeVoice.ts
|
|
676
552
|
var import_discord = require("discord.js");
|
|
677
553
|
var import_tiny_typed_emitter = require("tiny-typed-emitter");
|
|
678
554
|
var import_voice = require("@discordjs/voice");
|
|
679
|
-
var
|
|
680
|
-
|
|
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;
|
|
681
568
|
constructor(voiceManager, channel) {
|
|
682
569
|
super();
|
|
683
|
-
__privateAdd(this, _DisTubeVoice_instances);
|
|
684
|
-
__publicField(this, "id");
|
|
685
|
-
__publicField(this, "voices");
|
|
686
|
-
__publicField(this, "audioPlayer");
|
|
687
|
-
__publicField(this, "connection");
|
|
688
|
-
__publicField(this, "emittedError");
|
|
689
|
-
__publicField(this, "isDisconnected", false);
|
|
690
|
-
__publicField(this, "stream");
|
|
691
|
-
__privateAdd(this, _channel);
|
|
692
|
-
__privateAdd(this, _volume, 100);
|
|
693
570
|
this.voices = voiceManager;
|
|
694
571
|
this.id = channel.guildId;
|
|
695
572
|
this.channel = channel;
|
|
@@ -732,17 +609,17 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
732
609
|
return this.connection?.joinConfig?.channelId ?? void 0;
|
|
733
610
|
}
|
|
734
611
|
get channel() {
|
|
735
|
-
if (!this.channelId) return
|
|
736
|
-
if (
|
|
612
|
+
if (!this.channelId) return this.#channel;
|
|
613
|
+
if (this.#channel?.id === this.channelId) return this.#channel;
|
|
737
614
|
const channel = this.voices.client.channels.cache.get(this.channelId);
|
|
738
|
-
if (!channel) return
|
|
615
|
+
if (!channel) return this.#channel;
|
|
739
616
|
for (const type of import_discord.Constants.VoiceBasedChannelTypes) {
|
|
740
617
|
if (channel.type === type) {
|
|
741
|
-
|
|
618
|
+
this.#channel = channel;
|
|
742
619
|
return channel;
|
|
743
620
|
}
|
|
744
621
|
}
|
|
745
|
-
return
|
|
622
|
+
return this.#channel;
|
|
746
623
|
}
|
|
747
624
|
set channel(channel) {
|
|
748
625
|
if (!isSupportedVoiceChannel(channel)) {
|
|
@@ -755,8 +632,16 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
755
632
|
if (channel.full) throw new DisTubeError("VOICE_FULL");
|
|
756
633
|
else throw new DisTubeError("VOICE_MISSING_PERMS");
|
|
757
634
|
}
|
|
758
|
-
this.connection =
|
|
759
|
-
|
|
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
|
+
});
|
|
760
645
|
}
|
|
761
646
|
/**
|
|
762
647
|
* Join a voice channel with this connection
|
|
@@ -801,6 +686,10 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
801
686
|
* @param dtStream - DisTubeStream
|
|
802
687
|
*/
|
|
803
688
|
play(dtStream) {
|
|
689
|
+
if (!checkEncryptionLibraries()) {
|
|
690
|
+
dtStream.kill();
|
|
691
|
+
throw new DisTubeError("ENCRYPTION_LIBRARIES_MISSING");
|
|
692
|
+
}
|
|
804
693
|
this.emittedError = false;
|
|
805
694
|
dtStream.on("error", (error) => {
|
|
806
695
|
if (this.emittedError || error.code === "ERR_STREAM_PREMATURE_CLOSE") return;
|
|
@@ -810,7 +699,7 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
810
699
|
if (this.audioPlayer.state.status !== import_voice.AudioPlayerStatus.Paused) this.audioPlayer.play(dtStream.audioResource);
|
|
811
700
|
this.stream?.kill();
|
|
812
701
|
this.stream = dtStream;
|
|
813
|
-
this.volume =
|
|
702
|
+
this.volume = this.#volume;
|
|
814
703
|
dtStream.spawn();
|
|
815
704
|
}
|
|
816
705
|
set volume(volume) {
|
|
@@ -820,14 +709,14 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
820
709
|
if (volume < 0) {
|
|
821
710
|
throw new DisTubeError("NUMBER_COMPARE", "Volume", "bigger or equal to", 0);
|
|
822
711
|
}
|
|
823
|
-
|
|
824
|
-
this.stream?.setVolume(Math.pow(
|
|
712
|
+
this.#volume = volume;
|
|
713
|
+
this.stream?.setVolume(Math.pow(this.#volume / 100, 0.5 / Math.log10(2)));
|
|
825
714
|
}
|
|
826
715
|
/**
|
|
827
716
|
* Get or set the volume percentage
|
|
828
717
|
*/
|
|
829
718
|
get volume() {
|
|
830
|
-
return
|
|
719
|
+
return this.#volume;
|
|
831
720
|
}
|
|
832
721
|
/**
|
|
833
722
|
* Playback duration of the audio resource in seconds
|
|
@@ -894,19 +783,6 @@ var _DisTubeVoice = class _DisTubeVoice extends import_tiny_typed_emitter.TypedE
|
|
|
894
783
|
return this.channel?.guild?.members?.me?.voice;
|
|
895
784
|
}
|
|
896
785
|
};
|
|
897
|
-
_channel = new WeakMap();
|
|
898
|
-
_volume = new WeakMap();
|
|
899
|
-
_DisTubeVoice_instances = new WeakSet();
|
|
900
|
-
join_fn = /* @__PURE__ */ __name(function(channel) {
|
|
901
|
-
return (0, import_voice.joinVoiceChannel)({
|
|
902
|
-
channelId: channel.id,
|
|
903
|
-
guildId: this.id,
|
|
904
|
-
adapterCreator: channel.guild.voiceAdapterCreator,
|
|
905
|
-
group: channel.client.user?.id
|
|
906
|
-
});
|
|
907
|
-
}, "#join");
|
|
908
|
-
__name(_DisTubeVoice, "DisTubeVoice");
|
|
909
|
-
var DisTubeVoice = _DisTubeVoice;
|
|
910
786
|
|
|
911
787
|
// src/core/DisTubeStream.ts
|
|
912
788
|
var import_stream = require("stream");
|
|
@@ -933,8 +809,15 @@ var checkFFmpeg = /* @__PURE__ */ __name((distube) => {
|
|
|
933
809
|
}
|
|
934
810
|
checked = true;
|
|
935
811
|
}, "checkFFmpeg");
|
|
936
|
-
var
|
|
937
|
-
|
|
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;
|
|
938
821
|
/**
|
|
939
822
|
* Create a DisTubeStream to play with {@link DisTubeVoice}
|
|
940
823
|
* @param url - Stream URL
|
|
@@ -942,11 +825,6 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
942
825
|
*/
|
|
943
826
|
constructor(url, options) {
|
|
944
827
|
super();
|
|
945
|
-
__privateAdd(this, _ffmpegPath);
|
|
946
|
-
__privateAdd(this, _opts);
|
|
947
|
-
__publicField(this, "process");
|
|
948
|
-
__publicField(this, "stream");
|
|
949
|
-
__publicField(this, "audioResource");
|
|
950
828
|
const { ffmpeg, seek } = options;
|
|
951
829
|
const opts = {
|
|
952
830
|
reconnect: 1,
|
|
@@ -970,13 +848,13 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
970
848
|
opts.reconnect_delay_max = null;
|
|
971
849
|
opts.i = fileUrl.hostname + fileUrl.pathname;
|
|
972
850
|
}
|
|
973
|
-
|
|
974
|
-
|
|
851
|
+
this.#ffmpegPath = ffmpeg.path;
|
|
852
|
+
this.#opts = [
|
|
975
853
|
...Object.entries(opts).flatMap(
|
|
976
854
|
([key, value]) => Array.isArray(value) ? value.filter(Boolean).map((v) => [`-${key}`, String(v)]) : value == null || value === false ? [] : [value === true ? `-${key}` : [`-${key}`, String(value)]]
|
|
977
855
|
).flat(),
|
|
978
856
|
"pipe:1"
|
|
979
|
-
]
|
|
857
|
+
];
|
|
980
858
|
this.stream = new VolumeTransformer();
|
|
981
859
|
this.stream.on("close", () => this.kill()).on("error", (err) => {
|
|
982
860
|
this.debug(`[stream] error: ${err.message}`);
|
|
@@ -985,8 +863,8 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
985
863
|
this.audioResource = (0, import_voice2.createAudioResource)(this.stream, { inputType: import_voice2.StreamType.Raw, inlineVolume: false });
|
|
986
864
|
}
|
|
987
865
|
spawn() {
|
|
988
|
-
this.debug(`[process] spawn: ${
|
|
989
|
-
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, {
|
|
990
868
|
stdio: ["ignore", "pipe", "pipe"],
|
|
991
869
|
shell: false,
|
|
992
870
|
windowsHide: true
|
|
@@ -1023,17 +901,13 @@ var _DisTubeStream = class _DisTubeStream extends import_tiny_typed_emitter2.Typ
|
|
|
1023
901
|
if (this.process && !this.process.killed) this.process.kill("SIGKILL");
|
|
1024
902
|
}
|
|
1025
903
|
};
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
__name(
|
|
1029
|
-
var DisTubeStream = _DisTubeStream;
|
|
1030
|
-
var _VolumeTransformer = class _VolumeTransformer extends import_stream.Transform {
|
|
1031
|
-
constructor() {
|
|
1032
|
-
super(...arguments);
|
|
1033
|
-
__publicField(this, "buffer", Buffer.allocUnsafe(0));
|
|
1034
|
-
__publicField(this, "extrema", [-Math.pow(2, 16 - 1), Math.pow(2, 16 - 1) - 1]);
|
|
1035
|
-
__publicField(this, "vol", 1);
|
|
904
|
+
var VolumeTransformer = class extends import_stream.Transform {
|
|
905
|
+
static {
|
|
906
|
+
__name(this, "VolumeTransformer");
|
|
1036
907
|
}
|
|
908
|
+
buffer = Buffer.allocUnsafe(0);
|
|
909
|
+
extrema = [-Math.pow(2, 16 - 1), Math.pow(2, 16 - 1) - 1];
|
|
910
|
+
vol = 1;
|
|
1037
911
|
_transform(newChunk, _encoding, done) {
|
|
1038
912
|
const { vol } = this;
|
|
1039
913
|
if (vol === 1) {
|
|
@@ -1054,17 +928,13 @@ var _VolumeTransformer = class _VolumeTransformer extends import_stream.Transfor
|
|
|
1054
928
|
done();
|
|
1055
929
|
}
|
|
1056
930
|
};
|
|
1057
|
-
__name(_VolumeTransformer, "VolumeTransformer");
|
|
1058
|
-
var VolumeTransformer = _VolumeTransformer;
|
|
1059
931
|
|
|
1060
932
|
// src/core/DisTubeHandler.ts
|
|
1061
933
|
var import_undici = require("undici");
|
|
1062
934
|
var REDIRECT_CODES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
1063
|
-
var
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
super(...arguments);
|
|
1067
|
-
__privateAdd(this, _DisTubeHandler_instances);
|
|
935
|
+
var DisTubeHandler = class extends DisTubeBase {
|
|
936
|
+
static {
|
|
937
|
+
__name(this, "DisTubeHandler");
|
|
1068
938
|
}
|
|
1069
939
|
/**
|
|
1070
940
|
* Resolve a url or a supported object to a {@link Song} or {@link Playlist}
|
|
@@ -1081,15 +951,16 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1081
951
|
}
|
|
1082
952
|
if (typeof input === "string") {
|
|
1083
953
|
if (isURL(input)) {
|
|
1084
|
-
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));
|
|
1085
955
|
if (!plugin) throw new DisTubeError("NOT_SUPPORTED_URL");
|
|
1086
956
|
this.debug(`[${plugin.constructor.name}] Resolving from url: ${input}`);
|
|
1087
957
|
return plugin.resolve(input, options);
|
|
1088
958
|
}
|
|
1089
959
|
try {
|
|
1090
|
-
const song = await
|
|
960
|
+
const song = await this.#searchSong(input, options);
|
|
1091
961
|
if (song) return song;
|
|
1092
962
|
} catch {
|
|
963
|
+
throw new DisTubeError("NO_RESULT", input);
|
|
1093
964
|
}
|
|
1094
965
|
}
|
|
1095
966
|
throw new DisTubeError("CANNOT_RESOLVE_SONG", input);
|
|
@@ -1108,6 +979,19 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1108
979
|
}
|
|
1109
980
|
return null;
|
|
1110
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
|
+
}
|
|
1111
995
|
/**
|
|
1112
996
|
* Get {@link Song}'s stream info and attach it to the song.
|
|
1113
997
|
* @param song - A Song
|
|
@@ -1129,7 +1013,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1129
1013
|
this.debug(`[${plugin.constructor.name}] Creating search query for: ${song}`);
|
|
1130
1014
|
const query = await plugin.createSearchQuery(song);
|
|
1131
1015
|
if (!query) throw new DisTubeError("CANNOT_GET_SEARCH_QUERY", song.toString());
|
|
1132
|
-
const altSong = await
|
|
1016
|
+
const altSong = await this.#searchSong(query, { metadata: song.metadata, member: song.member }, true);
|
|
1133
1017
|
if (!altSong || !altSong.stream.playFromSource) throw new DisTubeError("NO_RESULT", query || song.toString());
|
|
1134
1018
|
song.stream.song = altSong;
|
|
1135
1019
|
}
|
|
@@ -1139,7 +1023,7 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1139
1023
|
const res = await (0, import_undici.request)(url, {
|
|
1140
1024
|
method: "HEAD",
|
|
1141
1025
|
headers: {
|
|
1142
|
-
"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"
|
|
1143
1027
|
}
|
|
1144
1028
|
});
|
|
1145
1029
|
if (REDIRECT_CODES.has(res.statusCode ?? 200)) {
|
|
@@ -1150,37 +1034,22 @@ var _DisTubeHandler = class _DisTubeHandler extends DisTubeBase {
|
|
|
1150
1034
|
return url;
|
|
1151
1035
|
}
|
|
1152
1036
|
};
|
|
1153
|
-
_DisTubeHandler_instances = new WeakSet();
|
|
1154
|
-
searchSong_fn = /* @__PURE__ */ __name(async function(query, options = {}, getStreamURL = false) {
|
|
1155
|
-
for (const plugin of this.plugins) {
|
|
1156
|
-
if (plugin.type === "extractor" /* EXTRACTOR */) {
|
|
1157
|
-
this.debug(`[${plugin.constructor.name}] Searching for song: ${query}`);
|
|
1158
|
-
const result = await plugin.searchSong(query, options);
|
|
1159
|
-
if (result) {
|
|
1160
|
-
if (getStreamURL && result.stream.playFromSource) result.stream.url = await plugin.getStreamURL(result);
|
|
1161
|
-
return result;
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
return null;
|
|
1166
|
-
}, "#searchSong");
|
|
1167
|
-
__name(_DisTubeHandler, "DisTubeHandler");
|
|
1168
|
-
var DisTubeHandler = _DisTubeHandler;
|
|
1169
1037
|
|
|
1170
1038
|
// src/core/DisTubeOptions.ts
|
|
1171
|
-
var
|
|
1172
|
-
|
|
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;
|
|
1173
1052
|
constructor(options) {
|
|
1174
|
-
__privateAdd(this, _Options_instances);
|
|
1175
|
-
__publicField(this, "plugins");
|
|
1176
|
-
__publicField(this, "emitNewSongOnly");
|
|
1177
|
-
__publicField(this, "savePreviousSongs");
|
|
1178
|
-
__publicField(this, "customFilters");
|
|
1179
|
-
__publicField(this, "nsfw");
|
|
1180
|
-
__publicField(this, "emitAddSongWhenCreatingQueue");
|
|
1181
|
-
__publicField(this, "emitAddListWhenCreatingQueue");
|
|
1182
|
-
__publicField(this, "joinNewVoiceChannel");
|
|
1183
|
-
__publicField(this, "ffmpeg");
|
|
1184
1053
|
if (typeof options !== "object" || Array.isArray(options)) {
|
|
1185
1054
|
throw new DisTubeError("INVALID_TYPE", "object", options, "DisTubeOptions");
|
|
1186
1055
|
}
|
|
@@ -1193,89 +1062,86 @@ var _Options = class _Options {
|
|
|
1193
1062
|
this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;
|
|
1194
1063
|
this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;
|
|
1195
1064
|
this.joinNewVoiceChannel = opts.joinNewVoiceChannel;
|
|
1196
|
-
this.ffmpeg =
|
|
1065
|
+
this.ffmpeg = this.#ffmpegOption(options);
|
|
1197
1066
|
checkInvalidKey(opts, this, "DisTubeOptions");
|
|
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
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
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
|
+
}
|
|
1234
1102
|
}
|
|
1235
1103
|
}
|
|
1236
1104
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
if (opts.ffmpeg.args.output) args.output = opts.ffmpeg.args.output;
|
|
1244
|
-
}
|
|
1245
|
-
const path = opts.ffmpeg?.path ?? "ffmpeg";
|
|
1246
|
-
if (typeof path !== "string") {
|
|
1247
|
-
throw new DisTubeError("INVALID_TYPE", "string", path, "DisTubeOptions.ffmpeg.path");
|
|
1248
|
-
}
|
|
1249
|
-
for (const [key, value] of Object.entries(args)) {
|
|
1250
|
-
if (typeof value !== "object" || Array.isArray(value)) {
|
|
1251
|
-
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;
|
|
1252
1111
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
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
|
+
}
|
|
1261
1129
|
}
|
|
1262
1130
|
}
|
|
1131
|
+
return { path, args };
|
|
1263
1132
|
}
|
|
1264
|
-
|
|
1265
|
-
}, "#ffmpegOption");
|
|
1266
|
-
__name(_Options, "Options");
|
|
1267
|
-
var Options = _Options;
|
|
1133
|
+
};
|
|
1268
1134
|
|
|
1269
1135
|
// src/core/manager/BaseManager.ts
|
|
1270
1136
|
var import_discord2 = require("discord.js");
|
|
1271
|
-
var
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
/**
|
|
1275
|
-
* The collection of items for this manager.
|
|
1276
|
-
*/
|
|
1277
|
-
__publicField(this, "collection", new import_discord2.Collection());
|
|
1137
|
+
var BaseManager = class extends DisTubeBase {
|
|
1138
|
+
static {
|
|
1139
|
+
__name(this, "BaseManager");
|
|
1278
1140
|
}
|
|
1141
|
+
/**
|
|
1142
|
+
* The collection of items for this manager.
|
|
1143
|
+
*/
|
|
1144
|
+
collection = new import_discord2.Collection();
|
|
1279
1145
|
/**
|
|
1280
1146
|
* The size of the collection.
|
|
1281
1147
|
*/
|
|
@@ -1283,11 +1149,12 @@ var _BaseManager = class _BaseManager extends DisTubeBase {
|
|
|
1283
1149
|
return this.collection.size;
|
|
1284
1150
|
}
|
|
1285
1151
|
};
|
|
1286
|
-
__name(_BaseManager, "BaseManager");
|
|
1287
|
-
var BaseManager = _BaseManager;
|
|
1288
1152
|
|
|
1289
1153
|
// src/core/manager/GuildIdManager.ts
|
|
1290
|
-
var
|
|
1154
|
+
var GuildIdManager = class extends BaseManager {
|
|
1155
|
+
static {
|
|
1156
|
+
__name(this, "GuildIdManager");
|
|
1157
|
+
}
|
|
1291
1158
|
add(idOrInstance, data) {
|
|
1292
1159
|
const id = resolveGuildId(idOrInstance);
|
|
1293
1160
|
const existing = this.get(id);
|
|
@@ -1305,12 +1172,13 @@ var _GuildIdManager = class _GuildIdManager extends BaseManager {
|
|
|
1305
1172
|
return this.collection.has(resolveGuildId(idOrInstance));
|
|
1306
1173
|
}
|
|
1307
1174
|
};
|
|
1308
|
-
__name(_GuildIdManager, "GuildIdManager");
|
|
1309
|
-
var GuildIdManager = _GuildIdManager;
|
|
1310
1175
|
|
|
1311
1176
|
// src/core/manager/DisTubeVoiceManager.ts
|
|
1312
1177
|
var import_voice3 = require("@discordjs/voice");
|
|
1313
|
-
var
|
|
1178
|
+
var DisTubeVoiceManager = class extends GuildIdManager {
|
|
1179
|
+
static {
|
|
1180
|
+
__name(this, "DisTubeVoiceManager");
|
|
1181
|
+
}
|
|
1314
1182
|
/**
|
|
1315
1183
|
* Create a {@link DisTubeVoice} instance
|
|
1316
1184
|
* @param channel - A voice channel to join
|
|
@@ -1351,21 +1219,36 @@ var _DisTubeVoiceManager = class _DisTubeVoiceManager extends GuildIdManager {
|
|
|
1351
1219
|
}
|
|
1352
1220
|
}
|
|
1353
1221
|
};
|
|
1354
|
-
__name(_DisTubeVoiceManager, "DisTubeVoiceManager");
|
|
1355
|
-
var DisTubeVoiceManager = _DisTubeVoiceManager;
|
|
1356
1222
|
|
|
1357
1223
|
// src/core/manager/FilterManager.ts
|
|
1358
|
-
var
|
|
1359
|
-
|
|
1224
|
+
var FilterManager = class extends BaseManager {
|
|
1225
|
+
static {
|
|
1226
|
+
__name(this, "FilterManager");
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* The queue to manage
|
|
1230
|
+
*/
|
|
1231
|
+
queue;
|
|
1360
1232
|
constructor(queue) {
|
|
1361
1233
|
super(queue.distube);
|
|
1362
|
-
__privateAdd(this, _FilterManager_instances);
|
|
1363
|
-
/**
|
|
1364
|
-
* The queue to manage
|
|
1365
|
-
*/
|
|
1366
|
-
__publicField(this, "queue");
|
|
1367
1234
|
this.queue = queue;
|
|
1368
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
|
+
}
|
|
1369
1252
|
/**
|
|
1370
1253
|
* Enable a filter or multiple filters to the manager
|
|
1371
1254
|
* @param filterOrFilters - The filter or filters to enable
|
|
@@ -1374,14 +1257,14 @@ var _FilterManager = class _FilterManager extends BaseManager {
|
|
|
1374
1257
|
add(filterOrFilters, override = false) {
|
|
1375
1258
|
if (Array.isArray(filterOrFilters)) {
|
|
1376
1259
|
for (const filter of filterOrFilters) {
|
|
1377
|
-
const ft =
|
|
1260
|
+
const ft = this.#resolve(filter);
|
|
1378
1261
|
if (override || !this.has(ft)) this.collection.set(ft.name, ft);
|
|
1379
1262
|
}
|
|
1380
1263
|
} else {
|
|
1381
|
-
const ft =
|
|
1264
|
+
const ft = this.#resolve(filterOrFilters);
|
|
1382
1265
|
if (override || !this.has(ft)) this.collection.set(ft.name, ft);
|
|
1383
1266
|
}
|
|
1384
|
-
|
|
1267
|
+
this.#apply();
|
|
1385
1268
|
return this;
|
|
1386
1269
|
}
|
|
1387
1270
|
/**
|
|
@@ -1398,20 +1281,23 @@ var _FilterManager = class _FilterManager extends BaseManager {
|
|
|
1398
1281
|
if (!Array.isArray(filters)) throw new DisTubeError("INVALID_TYPE", "Array<FilterResolvable>", filters, "filters");
|
|
1399
1282
|
this.collection.clear();
|
|
1400
1283
|
for (const f of filters) {
|
|
1401
|
-
const filter =
|
|
1284
|
+
const filter = this.#resolve(f);
|
|
1402
1285
|
this.collection.set(filter.name, filter);
|
|
1403
1286
|
}
|
|
1404
|
-
|
|
1287
|
+
this.#apply();
|
|
1405
1288
|
return this;
|
|
1406
1289
|
}
|
|
1290
|
+
#removeFn(f) {
|
|
1291
|
+
return this.collection.delete(this.#resolve(f).name);
|
|
1292
|
+
}
|
|
1407
1293
|
/**
|
|
1408
1294
|
* Disable a filter or multiple filters
|
|
1409
1295
|
* @param filterOrFilters - The filter or filters to disable
|
|
1410
1296
|
*/
|
|
1411
1297
|
remove(filterOrFilters) {
|
|
1412
|
-
if (Array.isArray(filterOrFilters)) filterOrFilters.forEach((f) =>
|
|
1413
|
-
else
|
|
1414
|
-
|
|
1298
|
+
if (Array.isArray(filterOrFilters)) filterOrFilters.forEach((f) => this.#removeFn(f));
|
|
1299
|
+
else this.#removeFn(filterOrFilters);
|
|
1300
|
+
this.#apply();
|
|
1415
1301
|
return this;
|
|
1416
1302
|
}
|
|
1417
1303
|
/**
|
|
@@ -1419,7 +1305,7 @@ var _FilterManager = class _FilterManager extends BaseManager {
|
|
|
1419
1305
|
* @param filter - The filter to check
|
|
1420
1306
|
*/
|
|
1421
1307
|
has(filter) {
|
|
1422
|
-
return this.collection.has(typeof filter === "string" ? filter :
|
|
1308
|
+
return this.collection.has(typeof filter === "string" ? filter : this.#resolve(filter).name);
|
|
1423
1309
|
}
|
|
1424
1310
|
/**
|
|
1425
1311
|
* Array of enabled filter names
|
|
@@ -1440,35 +1326,11 @@ var _FilterManager = class _FilterManager extends BaseManager {
|
|
|
1440
1326
|
return this.names.toString();
|
|
1441
1327
|
}
|
|
1442
1328
|
};
|
|
1443
|
-
_FilterManager_instances = new WeakSet();
|
|
1444
|
-
resolve_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1445
|
-
if (typeof filter === "object" && typeof filter.name === "string" && typeof filter.value === "string") {
|
|
1446
|
-
return filter;
|
|
1447
|
-
}
|
|
1448
|
-
if (typeof filter === "string" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter)) {
|
|
1449
|
-
return {
|
|
1450
|
-
name: filter,
|
|
1451
|
-
value: this.distube.filters[filter]
|
|
1452
|
-
};
|
|
1453
|
-
}
|
|
1454
|
-
throw new DisTubeError("INVALID_TYPE", "FilterResolvable", filter, "filter");
|
|
1455
|
-
}, "#resolve");
|
|
1456
|
-
apply_fn = /* @__PURE__ */ __name(function() {
|
|
1457
|
-
this.queue._beginTime = this.queue.currentTime;
|
|
1458
|
-
this.queue.play(false);
|
|
1459
|
-
}, "#apply");
|
|
1460
|
-
removeFn_fn = /* @__PURE__ */ __name(function(f) {
|
|
1461
|
-
return this.collection.delete(__privateMethod(this, _FilterManager_instances, resolve_fn).call(this, f).name);
|
|
1462
|
-
}, "#removeFn");
|
|
1463
|
-
__name(_FilterManager, "FilterManager");
|
|
1464
|
-
var FilterManager = _FilterManager;
|
|
1465
1329
|
|
|
1466
1330
|
// src/core/manager/QueueManager.ts
|
|
1467
|
-
var
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
super(...arguments);
|
|
1471
|
-
__privateAdd(this, _QueueManager_instances);
|
|
1331
|
+
var QueueManager = class extends GuildIdManager {
|
|
1332
|
+
static {
|
|
1333
|
+
__name(this, "QueueManager");
|
|
1472
1334
|
}
|
|
1473
1335
|
/**
|
|
1474
1336
|
* Create a {@link Queue}
|
|
@@ -1486,7 +1348,7 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1486
1348
|
checkFFmpeg(this.distube);
|
|
1487
1349
|
this.debug(`[QueueManager] Joining voice channel: ${channel.id}`);
|
|
1488
1350
|
await voice.join();
|
|
1489
|
-
|
|
1351
|
+
this.#voiceEventHandler(queue);
|
|
1490
1352
|
this.add(queue.id, queue);
|
|
1491
1353
|
this.emit("initQueue" /* INIT_QUEUE */, queue);
|
|
1492
1354
|
return queue;
|
|
@@ -1494,6 +1356,106 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1494
1356
|
queue._taskQueue.resolve();
|
|
1495
1357
|
}
|
|
1496
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
|
+
}
|
|
1497
1459
|
/**
|
|
1498
1460
|
* Play a song on voice connection with queue properties
|
|
1499
1461
|
* @param queue - The guild queue to play
|
|
@@ -1530,111 +1492,83 @@ var _QueueManager = class _QueueManager extends GuildIdManager {
|
|
|
1530
1492
|
queue.voice.play(dtStream);
|
|
1531
1493
|
if (emitPlaySong) this.emit("playSong" /* PLAY_SONG */, queue, song);
|
|
1532
1494
|
} catch (e) {
|
|
1533
|
-
|
|
1495
|
+
this.#handlePlayingError(queue, e);
|
|
1534
1496
|
}
|
|
1535
1497
|
}
|
|
1536
1498
|
};
|
|
1537
|
-
_QueueManager_instances = new WeakSet();
|
|
1538
|
-
/**
|
|
1539
|
-
* Listen to DisTubeVoice events and handle the Queue
|
|
1540
|
-
* @param queue - Queue
|
|
1541
|
-
*/
|
|
1542
|
-
voiceEventHandler_fn = /* @__PURE__ */ __name(function(queue) {
|
|
1543
|
-
queue._listeners = {
|
|
1544
|
-
disconnect: /* @__PURE__ */ __name((error) => {
|
|
1545
|
-
queue.remove();
|
|
1546
|
-
this.emit("disconnect" /* DISCONNECT */, queue);
|
|
1547
|
-
if (error) this.emitError(error, queue, queue.songs?.[0]);
|
|
1548
|
-
}, "disconnect"),
|
|
1549
|
-
error: /* @__PURE__ */ __name((error) => __privateMethod(this, _QueueManager_instances, handlePlayingError_fn).call(this, queue, error), "error"),
|
|
1550
|
-
finish: /* @__PURE__ */ __name(() => __privateMethod(this, _QueueManager_instances, handleSongFinish_fn).call(this, queue), "finish")
|
|
1551
|
-
};
|
|
1552
|
-
for (const event of objectKeys(queue._listeners)) {
|
|
1553
|
-
queue.voice.on(event, queue._listeners[event]);
|
|
1554
|
-
}
|
|
1555
|
-
}, "#voiceEventHandler");
|
|
1556
|
-
/**
|
|
1557
|
-
* Whether or not emit playSong event
|
|
1558
|
-
* @param queue - Queue
|
|
1559
|
-
*/
|
|
1560
|
-
emitPlaySong_fn = /* @__PURE__ */ __name(function(queue) {
|
|
1561
|
-
return !this.options.emitNewSongOnly || queue.repeatMode === 1 /* SONG */ && queue._next || queue.repeatMode !== 1 /* SONG */ && queue.songs[0]?.id !== queue.songs[1]?.id;
|
|
1562
|
-
}, "#emitPlaySong");
|
|
1563
|
-
handleSongFinish_fn = /* @__PURE__ */ __name(async function(queue) {
|
|
1564
|
-
this.debug(`[QueueManager] Handling song finish: ${queue.id}`);
|
|
1565
|
-
const song = queue.songs[0];
|
|
1566
|
-
this.emit("finishSong" /* FINISH_SONG */, queue, queue.songs[0]);
|
|
1567
|
-
await queue._taskQueue.queuing();
|
|
1568
|
-
try {
|
|
1569
|
-
if (queue.stopped) return;
|
|
1570
|
-
if (queue.repeatMode === 2 /* QUEUE */ && !queue._prev) queue.songs.push(song);
|
|
1571
|
-
if (queue._prev) {
|
|
1572
|
-
if (queue.repeatMode === 2 /* QUEUE */) queue.songs.unshift(queue.songs.pop());
|
|
1573
|
-
else queue.songs.unshift(queue.previousSongs.pop());
|
|
1574
|
-
}
|
|
1575
|
-
if (queue.songs.length <= 1 && (queue._next || queue.repeatMode === 0 /* DISABLED */)) {
|
|
1576
|
-
if (queue.autoplay) {
|
|
1577
|
-
try {
|
|
1578
|
-
this.debug(`[QueueManager] Adding related song: ${queue.id}`);
|
|
1579
|
-
await queue.addRelatedSong();
|
|
1580
|
-
} catch (e) {
|
|
1581
|
-
this.debug(`[${queue.id}] Add related song error: ${e.message}`);
|
|
1582
|
-
this.emit("noRelated" /* NO_RELATED */, queue, e);
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
if (queue.songs.length <= 1) {
|
|
1586
|
-
this.debug(`[${queue.id}] Queue is empty, stopping...`);
|
|
1587
|
-
if (!queue.autoplay) this.emit("finish" /* FINISH */, queue);
|
|
1588
|
-
queue.remove();
|
|
1589
|
-
return;
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1592
|
-
const emitPlaySong = __privateMethod(this, _QueueManager_instances, emitPlaySong_fn).call(this, queue);
|
|
1593
|
-
if (!queue._prev && (queue.repeatMode !== 1 /* SONG */ || queue._next)) {
|
|
1594
|
-
const prev = queue.songs.shift();
|
|
1595
|
-
if (this.options.savePreviousSongs) queue.previousSongs.push(prev);
|
|
1596
|
-
else queue.previousSongs.push({ id: prev.id });
|
|
1597
|
-
}
|
|
1598
|
-
queue._next = queue._prev = false;
|
|
1599
|
-
queue._beginTime = 0;
|
|
1600
|
-
if (song !== queue.songs[0]) {
|
|
1601
|
-
const playedSong = song.stream.playFromSource ? song : song.stream.song;
|
|
1602
|
-
if (playedSong?.stream.playFromSource) delete playedSong.stream.url;
|
|
1603
|
-
}
|
|
1604
|
-
await this.playSong(queue, emitPlaySong);
|
|
1605
|
-
} finally {
|
|
1606
|
-
queue._taskQueue.resolve();
|
|
1607
|
-
}
|
|
1608
|
-
}, "#handleSongFinish");
|
|
1609
|
-
/**
|
|
1610
|
-
* Handle error while playing
|
|
1611
|
-
* @param queue - queue
|
|
1612
|
-
* @param error - error
|
|
1613
|
-
*/
|
|
1614
|
-
handlePlayingError_fn = /* @__PURE__ */ __name(function(queue, error) {
|
|
1615
|
-
const song = queue.songs.shift();
|
|
1616
|
-
try {
|
|
1617
|
-
error.name = "PlayingError";
|
|
1618
|
-
} catch {
|
|
1619
|
-
}
|
|
1620
|
-
this.debug(`[${queue.id}] Error while playing: ${error.stack || error.message}`);
|
|
1621
|
-
this.emitError(error, queue, song);
|
|
1622
|
-
if (queue.songs.length > 0) {
|
|
1623
|
-
this.debug(`[${queue.id}] Playing next song: ${queue.songs[0]}`);
|
|
1624
|
-
queue._next = queue._prev = false;
|
|
1625
|
-
queue._beginTime = 0;
|
|
1626
|
-
this.playSong(queue);
|
|
1627
|
-
} else {
|
|
1628
|
-
this.debug(`[${queue.id}] Queue is empty, stopping...`);
|
|
1629
|
-
queue.stop();
|
|
1630
|
-
}
|
|
1631
|
-
}, "#handlePlayingError");
|
|
1632
|
-
__name(_QueueManager, "QueueManager");
|
|
1633
|
-
var QueueManager = _QueueManager;
|
|
1634
1499
|
|
|
1635
1500
|
// src/struct/Queue.ts
|
|
1636
|
-
var
|
|
1637
|
-
|
|
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;
|
|
1638
1572
|
/**
|
|
1639
1573
|
* Create a queue for the guild
|
|
1640
1574
|
* @param distube - DisTube
|
|
@@ -1643,74 +1577,6 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1643
1577
|
*/
|
|
1644
1578
|
constructor(distube, voice, textChannel) {
|
|
1645
1579
|
super(distube);
|
|
1646
|
-
__privateAdd(this, _Queue_instances);
|
|
1647
|
-
/**
|
|
1648
|
-
* Queue id (Guild id)
|
|
1649
|
-
*/
|
|
1650
|
-
__publicField(this, "id");
|
|
1651
|
-
/**
|
|
1652
|
-
* Voice connection of this queue.
|
|
1653
|
-
*/
|
|
1654
|
-
__publicField(this, "voice");
|
|
1655
|
-
/**
|
|
1656
|
-
* List of songs in the queue (The first one is the playing song)
|
|
1657
|
-
*/
|
|
1658
|
-
__publicField(this, "songs");
|
|
1659
|
-
/**
|
|
1660
|
-
* List of the previous songs.
|
|
1661
|
-
*/
|
|
1662
|
-
__publicField(this, "previousSongs");
|
|
1663
|
-
/**
|
|
1664
|
-
* Whether stream is currently stopped.
|
|
1665
|
-
*/
|
|
1666
|
-
__publicField(this, "stopped");
|
|
1667
|
-
/**
|
|
1668
|
-
* Whether or not the stream is currently playing.
|
|
1669
|
-
*/
|
|
1670
|
-
__publicField(this, "playing");
|
|
1671
|
-
/**
|
|
1672
|
-
* Whether or not the stream is currently paused.
|
|
1673
|
-
*/
|
|
1674
|
-
__publicField(this, "paused");
|
|
1675
|
-
/**
|
|
1676
|
-
* Type of repeat mode (`0` is disabled, `1` is repeating a song, `2` is repeating
|
|
1677
|
-
* all the queue). Default value: `0` (disabled)
|
|
1678
|
-
*/
|
|
1679
|
-
__publicField(this, "repeatMode");
|
|
1680
|
-
/**
|
|
1681
|
-
* Whether or not the autoplay mode is enabled. Default value: `false`
|
|
1682
|
-
*/
|
|
1683
|
-
__publicField(this, "autoplay");
|
|
1684
|
-
/**
|
|
1685
|
-
* FFmpeg arguments for the current queue. Default value is defined with {@link DisTubeOptions}.ffmpeg.args.
|
|
1686
|
-
* `af` output argument will be replaced with {@link Queue#filters} manager
|
|
1687
|
-
*/
|
|
1688
|
-
__publicField(this, "ffmpegArgs");
|
|
1689
|
-
/**
|
|
1690
|
-
* The text channel of the Queue. (Default: where the first command is called).
|
|
1691
|
-
*/
|
|
1692
|
-
__publicField(this, "textChannel");
|
|
1693
|
-
__privateAdd(this, _filters);
|
|
1694
|
-
/**
|
|
1695
|
-
* What time in the song to begin (in seconds).
|
|
1696
|
-
*/
|
|
1697
|
-
__publicField(this, "_beginTime");
|
|
1698
|
-
/**
|
|
1699
|
-
* Whether or not the last song was skipped to next song.
|
|
1700
|
-
*/
|
|
1701
|
-
__publicField(this, "_next");
|
|
1702
|
-
/**
|
|
1703
|
-
* Whether or not the last song was skipped to previous song.
|
|
1704
|
-
*/
|
|
1705
|
-
__publicField(this, "_prev");
|
|
1706
|
-
/**
|
|
1707
|
-
* Task queuing system
|
|
1708
|
-
*/
|
|
1709
|
-
__publicField(this, "_taskQueue");
|
|
1710
|
-
/**
|
|
1711
|
-
* {@link DisTubeVoice} listener
|
|
1712
|
-
*/
|
|
1713
|
-
__publicField(this, "_listeners");
|
|
1714
1580
|
this.voice = voice;
|
|
1715
1581
|
this.id = voice.id;
|
|
1716
1582
|
this.volume = 50;
|
|
@@ -1723,7 +1589,7 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1723
1589
|
this.paused = false;
|
|
1724
1590
|
this.repeatMode = 0 /* DISABLED */;
|
|
1725
1591
|
this.autoplay = false;
|
|
1726
|
-
|
|
1592
|
+
this.#filters = new FilterManager(this);
|
|
1727
1593
|
this._beginTime = 0;
|
|
1728
1594
|
this.textChannel = textChannel;
|
|
1729
1595
|
this._taskQueue = new TaskQueue();
|
|
@@ -1744,7 +1610,7 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1744
1610
|
* The filter manager of the queue
|
|
1745
1611
|
*/
|
|
1746
1612
|
get filters() {
|
|
1747
|
-
return
|
|
1613
|
+
return this.#filters;
|
|
1748
1614
|
}
|
|
1749
1615
|
/**
|
|
1750
1616
|
* Formatted duration string.
|
|
@@ -1809,6 +1675,18 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1809
1675
|
}
|
|
1810
1676
|
return this;
|
|
1811
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
|
+
}
|
|
1812
1690
|
/**
|
|
1813
1691
|
* Pause the guild stream
|
|
1814
1692
|
* @returns The guild queue
|
|
@@ -1962,6 +1840,11 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1962
1840
|
this.play(false);
|
|
1963
1841
|
return this;
|
|
1964
1842
|
}
|
|
1843
|
+
async #getRelatedSong(current) {
|
|
1844
|
+
const plugin = await this.handler._getPluginFromSong(current);
|
|
1845
|
+
if (plugin) return plugin.getRelatedSongs(current);
|
|
1846
|
+
return [];
|
|
1847
|
+
}
|
|
1965
1848
|
/**
|
|
1966
1849
|
* Add a related song of the playing song to the queue
|
|
1967
1850
|
* @returns The added song
|
|
@@ -1970,11 +1853,11 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
1970
1853
|
const current = this.songs?.[0];
|
|
1971
1854
|
if (!current) throw new DisTubeError("NO_PLAYING_SONG");
|
|
1972
1855
|
const prevIds = this.previousSongs.map((p) => p.id);
|
|
1973
|
-
const relatedSongs = (await
|
|
1856
|
+
const relatedSongs = (await this.#getRelatedSong(current)).filter((s) => !prevIds.includes(s.id));
|
|
1974
1857
|
this.debug(`[${this.id}] Getting related songs from: ${current}`);
|
|
1975
1858
|
if (!relatedSongs.length && !current.stream.playFromSource) {
|
|
1976
1859
|
const altSong = current.stream.song;
|
|
1977
|
-
if (altSong) relatedSongs.push(...(await
|
|
1860
|
+
if (altSong) relatedSongs.push(...(await this.#getRelatedSong(altSong)).filter((s) => !prevIds.includes(s.id)));
|
|
1978
1861
|
this.debug(`[${this.id}] Getting related songs from streamed song: ${altSong}`);
|
|
1979
1862
|
}
|
|
1980
1863
|
const song = relatedSongs[0];
|
|
@@ -2023,7 +1906,7 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
2023
1906
|
return this.autoplay;
|
|
2024
1907
|
}
|
|
2025
1908
|
/**
|
|
2026
|
-
* Play the queue
|
|
1909
|
+
* Play the first song in the queue
|
|
2027
1910
|
* @param emitPlaySong - Whether or not emit {@link Events.PLAY_SONG} event
|
|
2028
1911
|
*/
|
|
2029
1912
|
play(emitPlaySong = true) {
|
|
@@ -2032,60 +1915,44 @@ var _Queue = class _Queue extends DisTubeBase {
|
|
|
2032
1915
|
return this.queues.playSong(this, emitPlaySong);
|
|
2033
1916
|
}
|
|
2034
1917
|
};
|
|
2035
|
-
_filters = new WeakMap();
|
|
2036
|
-
_Queue_instances = new WeakSet();
|
|
2037
|
-
getRelatedSong_fn = /* @__PURE__ */ __name(async function(current) {
|
|
2038
|
-
const plugin = await this.handler._getPluginFromSong(current);
|
|
2039
|
-
if (plugin) return plugin.getRelatedSongs(current);
|
|
2040
|
-
return [];
|
|
2041
|
-
}, "#getRelatedSong");
|
|
2042
|
-
__name(_Queue, "Queue");
|
|
2043
|
-
var Queue = _Queue;
|
|
2044
1918
|
|
|
2045
1919
|
// src/struct/Plugin.ts
|
|
2046
|
-
var
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
* DisTube
|
|
2050
|
-
*/
|
|
2051
|
-
__publicField(this, "distube");
|
|
1920
|
+
var Plugin = class {
|
|
1921
|
+
static {
|
|
1922
|
+
__name(this, "Plugin");
|
|
2052
1923
|
}
|
|
1924
|
+
/**
|
|
1925
|
+
* DisTube
|
|
1926
|
+
*/
|
|
1927
|
+
distube;
|
|
2053
1928
|
init(distube) {
|
|
2054
1929
|
this.distube = distube;
|
|
2055
1930
|
}
|
|
2056
1931
|
};
|
|
2057
|
-
__name(_Plugin, "Plugin");
|
|
2058
|
-
var Plugin = _Plugin;
|
|
2059
1932
|
|
|
2060
1933
|
// src/struct/ExtractorPlugin.ts
|
|
2061
|
-
var
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
__publicField(this, "type", "extractor" /* EXTRACTOR */);
|
|
1934
|
+
var ExtractorPlugin = class extends Plugin {
|
|
1935
|
+
static {
|
|
1936
|
+
__name(this, "ExtractorPlugin");
|
|
2065
1937
|
}
|
|
1938
|
+
type = "extractor" /* EXTRACTOR */;
|
|
2066
1939
|
};
|
|
2067
|
-
__name(_ExtractorPlugin, "ExtractorPlugin");
|
|
2068
|
-
var ExtractorPlugin = _ExtractorPlugin;
|
|
2069
1940
|
|
|
2070
1941
|
// src/struct/InfoExtratorPlugin.ts
|
|
2071
|
-
var
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
__publicField(this, "type", "info-extractor" /* INFO_EXTRACTOR */);
|
|
1942
|
+
var InfoExtractorPlugin = class extends Plugin {
|
|
1943
|
+
static {
|
|
1944
|
+
__name(this, "InfoExtractorPlugin");
|
|
2075
1945
|
}
|
|
1946
|
+
type = "info-extractor" /* INFO_EXTRACTOR */;
|
|
2076
1947
|
};
|
|
2077
|
-
__name(_InfoExtractorPlugin, "InfoExtractorPlugin");
|
|
2078
|
-
var InfoExtractorPlugin = _InfoExtractorPlugin;
|
|
2079
1948
|
|
|
2080
1949
|
// src/struct/PlayableExtratorPlugin.ts
|
|
2081
|
-
var
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
__publicField(this, "type", "playable-extractor" /* PLAYABLE_EXTRACTOR */);
|
|
1950
|
+
var PlayableExtractorPlugin = class extends Plugin {
|
|
1951
|
+
static {
|
|
1952
|
+
__name(this, "PlayableExtractorPlugin");
|
|
2085
1953
|
}
|
|
1954
|
+
type = "playable-extractor" /* PLAYABLE_EXTRACTOR */;
|
|
2086
1955
|
};
|
|
2087
|
-
__name(_PlayableExtractorPlugin, "PlayableExtractorPlugin");
|
|
2088
|
-
var PlayableExtractorPlugin = _PlayableExtractorPlugin;
|
|
2089
1956
|
|
|
2090
1957
|
// src/util.ts
|
|
2091
1958
|
var import_url = require("url");
|
|
@@ -2200,12 +2067,134 @@ function isNsfwChannel(channel) {
|
|
|
2200
2067
|
}
|
|
2201
2068
|
__name(isNsfwChannel, "isNsfwChannel");
|
|
2202
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");
|
|
2203
2080
|
|
|
2204
2081
|
// src/DisTube.ts
|
|
2205
2082
|
var import_tiny_typed_emitter3 = require("tiny-typed-emitter");
|
|
2206
|
-
var
|
|
2207
|
-
|
|
2208
|
-
|
|
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;
|
|
2209
2198
|
/**
|
|
2210
2199
|
* Create a new DisTube class.
|
|
2211
2200
|
* @throws {@link DisTubeError}
|
|
@@ -2214,35 +2203,6 @@ var _DisTube = class _DisTube extends (_m = import_tiny_typed_emitter3.TypedEmit
|
|
|
2214
2203
|
*/
|
|
2215
2204
|
constructor(client, opts = {}) {
|
|
2216
2205
|
super();
|
|
2217
|
-
__privateAdd(this, _DisTube_instances);
|
|
2218
|
-
/**
|
|
2219
|
-
* DisTube internal handler
|
|
2220
|
-
*/
|
|
2221
|
-
__publicField(this, "handler");
|
|
2222
|
-
/**
|
|
2223
|
-
* DisTube options
|
|
2224
|
-
*/
|
|
2225
|
-
__publicField(this, "options");
|
|
2226
|
-
/**
|
|
2227
|
-
* Discord.js v14 client
|
|
2228
|
-
*/
|
|
2229
|
-
__publicField(this, "client");
|
|
2230
|
-
/**
|
|
2231
|
-
* Queues manager
|
|
2232
|
-
*/
|
|
2233
|
-
__publicField(this, "queues");
|
|
2234
|
-
/**
|
|
2235
|
-
* DisTube voice connections manager
|
|
2236
|
-
*/
|
|
2237
|
-
__publicField(this, "voices");
|
|
2238
|
-
/**
|
|
2239
|
-
* DisTube plugins
|
|
2240
|
-
*/
|
|
2241
|
-
__publicField(this, "plugins");
|
|
2242
|
-
/**
|
|
2243
|
-
* DisTube ffmpeg audio filters
|
|
2244
|
-
*/
|
|
2245
|
-
__publicField(this, "filters");
|
|
2246
2206
|
this.setMaxListeners(1);
|
|
2247
2207
|
if (!isClientInstance(client)) throw new DisTubeError("INVALID_TYPE", "Discord.Client", client, "client");
|
|
2248
2208
|
this.client = client;
|
|
@@ -2318,6 +2278,7 @@ var _DisTube = class _DisTube extends (_m = import_tiny_typed_emitter3.TypedEmit
|
|
|
2318
2278
|
if (queue.playing || this.options.emitAddSongWhenCreatingQueue) this.emit("addSong" /* ADD_SONG */, queue, resolved);
|
|
2319
2279
|
}
|
|
2320
2280
|
if (!queue.playing) await queue.play();
|
|
2281
|
+
else if (skip) await queue.skip();
|
|
2321
2282
|
} catch (e) {
|
|
2322
2283
|
if (!(e instanceof DisTubeError)) {
|
|
2323
2284
|
this.debug(`[${queue.id}] Unexpected error while playing song: ${e.stack || e.message}`);
|
|
@@ -2377,13 +2338,18 @@ ${e.message}`;
|
|
|
2377
2338
|
getQueue(guild) {
|
|
2378
2339
|
return this.queues.get(guild);
|
|
2379
2340
|
}
|
|
2341
|
+
#getQueue(guild) {
|
|
2342
|
+
const queue = this.getQueue(guild);
|
|
2343
|
+
if (!queue) throw new DisTubeError("NO_QUEUE");
|
|
2344
|
+
return queue;
|
|
2345
|
+
}
|
|
2380
2346
|
/**
|
|
2381
2347
|
* Pause the guild stream
|
|
2382
2348
|
* @param guild - The type can be resolved to give a {@link Queue}
|
|
2383
2349
|
* @returns The guild queue
|
|
2384
2350
|
*/
|
|
2385
2351
|
pause(guild) {
|
|
2386
|
-
return
|
|
2352
|
+
return this.#getQueue(guild).pause();
|
|
2387
2353
|
}
|
|
2388
2354
|
/**
|
|
2389
2355
|
* Resume the guild stream
|
|
@@ -2391,14 +2357,14 @@ ${e.message}`;
|
|
|
2391
2357
|
* @returns The guild queue
|
|
2392
2358
|
*/
|
|
2393
2359
|
resume(guild) {
|
|
2394
|
-
return
|
|
2360
|
+
return this.#getQueue(guild).resume();
|
|
2395
2361
|
}
|
|
2396
2362
|
/**
|
|
2397
2363
|
* Stop the guild stream
|
|
2398
2364
|
* @param guild - The type can be resolved to give a {@link Queue}
|
|
2399
2365
|
*/
|
|
2400
2366
|
stop(guild) {
|
|
2401
|
-
return
|
|
2367
|
+
return this.#getQueue(guild).stop();
|
|
2402
2368
|
}
|
|
2403
2369
|
/**
|
|
2404
2370
|
* Set the guild stream's volume
|
|
@@ -2407,7 +2373,7 @@ ${e.message}`;
|
|
|
2407
2373
|
* @returns The guild queue
|
|
2408
2374
|
*/
|
|
2409
2375
|
setVolume(guild, percent) {
|
|
2410
|
-
return
|
|
2376
|
+
return this.#getQueue(guild).setVolume(percent);
|
|
2411
2377
|
}
|
|
2412
2378
|
/**
|
|
2413
2379
|
* Skip the playing song if there is a next song in the queue. <info>If {@link
|
|
@@ -2417,7 +2383,7 @@ ${e.message}`;
|
|
|
2417
2383
|
* @returns The new Song will be played
|
|
2418
2384
|
*/
|
|
2419
2385
|
skip(guild) {
|
|
2420
|
-
return
|
|
2386
|
+
return this.#getQueue(guild).skip();
|
|
2421
2387
|
}
|
|
2422
2388
|
/**
|
|
2423
2389
|
* Play the previous song
|
|
@@ -2425,7 +2391,7 @@ ${e.message}`;
|
|
|
2425
2391
|
* @returns The new Song will be played
|
|
2426
2392
|
*/
|
|
2427
2393
|
previous(guild) {
|
|
2428
|
-
return
|
|
2394
|
+
return this.#getQueue(guild).previous();
|
|
2429
2395
|
}
|
|
2430
2396
|
/**
|
|
2431
2397
|
* Shuffle the guild queue songs
|
|
@@ -2433,7 +2399,7 @@ ${e.message}`;
|
|
|
2433
2399
|
* @returns The guild queue
|
|
2434
2400
|
*/
|
|
2435
2401
|
shuffle(guild) {
|
|
2436
|
-
return
|
|
2402
|
+
return this.#getQueue(guild).shuffle();
|
|
2437
2403
|
}
|
|
2438
2404
|
/**
|
|
2439
2405
|
* Jump to the song number in the queue. The next one is 1, 2,... The previous one
|
|
@@ -2443,7 +2409,7 @@ ${e.message}`;
|
|
|
2443
2409
|
* @returns The new Song will be played
|
|
2444
2410
|
*/
|
|
2445
2411
|
jump(guild, num) {
|
|
2446
|
-
return
|
|
2412
|
+
return this.#getQueue(guild).jump(num);
|
|
2447
2413
|
}
|
|
2448
2414
|
/**
|
|
2449
2415
|
* Set the repeat mode of the guild queue.
|
|
@@ -2453,7 +2419,7 @@ ${e.message}`;
|
|
|
2453
2419
|
* @returns The new repeat mode
|
|
2454
2420
|
*/
|
|
2455
2421
|
setRepeatMode(guild, mode) {
|
|
2456
|
-
return
|
|
2422
|
+
return this.#getQueue(guild).setRepeatMode(mode);
|
|
2457
2423
|
}
|
|
2458
2424
|
/**
|
|
2459
2425
|
* Toggle autoplay mode
|
|
@@ -2461,7 +2427,7 @@ ${e.message}`;
|
|
|
2461
2427
|
* @returns Autoplay mode state
|
|
2462
2428
|
*/
|
|
2463
2429
|
toggleAutoplay(guild) {
|
|
2464
|
-
const queue =
|
|
2430
|
+
const queue = this.#getQueue(guild);
|
|
2465
2431
|
queue.autoplay = !queue.autoplay;
|
|
2466
2432
|
return queue.autoplay;
|
|
2467
2433
|
}
|
|
@@ -2471,7 +2437,7 @@ ${e.message}`;
|
|
|
2471
2437
|
* @returns The guild queue
|
|
2472
2438
|
*/
|
|
2473
2439
|
addRelatedSong(guild) {
|
|
2474
|
-
return
|
|
2440
|
+
return this.#getQueue(guild).addRelatedSong();
|
|
2475
2441
|
}
|
|
2476
2442
|
/**
|
|
2477
2443
|
* Set the playing time to another position
|
|
@@ -2480,7 +2446,7 @@ ${e.message}`;
|
|
|
2480
2446
|
* @returns Seeked queue
|
|
2481
2447
|
*/
|
|
2482
2448
|
seek(guild, time) {
|
|
2483
|
-
return
|
|
2449
|
+
return this.#getQueue(guild).seek(time);
|
|
2484
2450
|
}
|
|
2485
2451
|
/**
|
|
2486
2452
|
* Emit error event
|
|
@@ -2499,97 +2465,9 @@ ${e.message}`;
|
|
|
2499
2465
|
this.emit("debug" /* DEBUG */, message);
|
|
2500
2466
|
}
|
|
2501
2467
|
};
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
if (!queue) throw new DisTubeError("NO_QUEUE");
|
|
2506
|
-
return queue;
|
|
2507
|
-
}, "#getQueue");
|
|
2508
|
-
__name(_DisTube, "DisTube");
|
|
2509
|
-
/**
|
|
2510
|
-
* @event
|
|
2511
|
-
* Emitted after DisTube add a new playlist to the playing {@link Queue}.
|
|
2512
|
-
* @param queue - The guild queue
|
|
2513
|
-
* @param playlist - Playlist info
|
|
2514
|
-
*/
|
|
2515
|
-
__publicField(_DisTube, _l);
|
|
2516
|
-
/**
|
|
2517
|
-
* @event
|
|
2518
|
-
* Emitted after DisTube add a new song to the playing {@link Queue}.
|
|
2519
|
-
* @param queue - The guild queue
|
|
2520
|
-
* @param song - Added song
|
|
2521
|
-
*/
|
|
2522
|
-
__publicField(_DisTube, _k);
|
|
2523
|
-
/**
|
|
2524
|
-
* @event
|
|
2525
|
-
* Emitted when a {@link Queue} is deleted with any reasons.
|
|
2526
|
-
* @param queue - The guild queue
|
|
2527
|
-
*/
|
|
2528
|
-
__publicField(_DisTube, _j);
|
|
2529
|
-
/**
|
|
2530
|
-
* @event
|
|
2531
|
-
* Emitted when the bot is disconnected to a voice channel.
|
|
2532
|
-
* @param queue - The guild queue
|
|
2533
|
-
*/
|
|
2534
|
-
__publicField(_DisTube, _i);
|
|
2535
|
-
/**
|
|
2536
|
-
* @event
|
|
2537
|
-
* Emitted when DisTube encounters an error while playing songs.
|
|
2538
|
-
* @param error - error
|
|
2539
|
-
* @param queue - The queue encountered the error
|
|
2540
|
-
* @param song - The playing song when encountered the error
|
|
2541
|
-
*/
|
|
2542
|
-
__publicField(_DisTube, _h);
|
|
2543
|
-
/**
|
|
2544
|
-
* @event
|
|
2545
|
-
* Emitted for logging FFmpeg debug information.
|
|
2546
|
-
* @param debug - Debug message string.
|
|
2547
|
-
*/
|
|
2548
|
-
__publicField(_DisTube, _g);
|
|
2549
|
-
/**
|
|
2550
|
-
* @event
|
|
2551
|
-
* Emitted to provide debug information from DisTube's operation.
|
|
2552
|
-
* Useful for troubleshooting or logging purposes.
|
|
2553
|
-
*
|
|
2554
|
-
* @param debug - Debug message string.
|
|
2555
|
-
*/
|
|
2556
|
-
__publicField(_DisTube, _f);
|
|
2557
|
-
/**
|
|
2558
|
-
* @event
|
|
2559
|
-
* Emitted when there is no more song in the queue and {@link Queue#autoplay} is `false`.
|
|
2560
|
-
* @param queue - The guild queue
|
|
2561
|
-
*/
|
|
2562
|
-
__publicField(_DisTube, _e);
|
|
2563
|
-
/**
|
|
2564
|
-
* @event
|
|
2565
|
-
* Emitted when DisTube finished a song.
|
|
2566
|
-
* @param queue - The guild queue
|
|
2567
|
-
* @param song - Finished song
|
|
2568
|
-
*/
|
|
2569
|
-
__publicField(_DisTube, _d);
|
|
2570
|
-
/**
|
|
2571
|
-
* @event
|
|
2572
|
-
* Emitted when DisTube initialize a queue to change queue default properties.
|
|
2573
|
-
* @param queue - The guild queue
|
|
2574
|
-
*/
|
|
2575
|
-
__publicField(_DisTube, _c);
|
|
2576
|
-
/**
|
|
2577
|
-
* @event
|
|
2578
|
-
* Emitted when {@link Queue#autoplay} is `true`, {@link Queue#songs} is empty, and
|
|
2579
|
-
* DisTube cannot find related songs to play.
|
|
2580
|
-
* @param queue - The guild queue
|
|
2581
|
-
*/
|
|
2582
|
-
__publicField(_DisTube, _b);
|
|
2583
|
-
/**
|
|
2584
|
-
* @event
|
|
2585
|
-
* Emitted when DisTube play a song.
|
|
2586
|
-
* If {@link DisTubeOptions}.emitNewSongOnly is `true`, this event is not emitted
|
|
2587
|
-
* when looping a song or next song is the previous one.
|
|
2588
|
-
* @param queue - The guild queue
|
|
2589
|
-
* @param song - Playing song
|
|
2590
|
-
*/
|
|
2591
|
-
__publicField(_DisTube, _a);
|
|
2592
|
-
var DisTube = _DisTube;
|
|
2468
|
+
|
|
2469
|
+
// src/index.ts
|
|
2470
|
+
var version = "5.0.3";
|
|
2593
2471
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2594
2472
|
0 && (module.exports = {
|
|
2595
2473
|
BaseManager,
|
|
@@ -2615,6 +2493,7 @@ var DisTube = _DisTube;
|
|
|
2615
2493
|
RepeatMode,
|
|
2616
2494
|
Song,
|
|
2617
2495
|
TaskQueue,
|
|
2496
|
+
checkEncryptionLibraries,
|
|
2618
2497
|
checkFFmpeg,
|
|
2619
2498
|
checkIntents,
|
|
2620
2499
|
checkInvalidKey,
|