distube 4.0.0-dev.3 → 4.0.0-dev.6
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.ts +119 -89
- package/dist/index.js +723 -647
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +720 -645
- package/dist/index.mjs.map +1 -1
- package/package.json +26 -26
package/dist/index.mjs
CHANGED
|
@@ -44,7 +44,7 @@ var require_package = __commonJS({
|
|
|
44
44
|
"package.json"(exports, module) {
|
|
45
45
|
module.exports = {
|
|
46
46
|
name: "distube",
|
|
47
|
-
version: "4.0.0-dev.
|
|
47
|
+
version: "4.0.0-dev.6",
|
|
48
48
|
description: "A Discord.js module to simplify your music commands and play songs with audio filters on Discord without any API key.",
|
|
49
49
|
main: "./dist/index.js",
|
|
50
50
|
module: "./dist/index.mjs",
|
|
@@ -65,7 +65,7 @@ var require_package = __commonJS({
|
|
|
65
65
|
docs: "docgen -s src/*.ts src/**/*.ts -o docs.json -c pages/index.yml -g -j jsdoc.config.json",
|
|
66
66
|
lint: "prettier --check . && eslint .",
|
|
67
67
|
"lint:fix": "eslint . --fix",
|
|
68
|
-
prettier:
|
|
68
|
+
prettier: 'prettier --write "**/*.{ts,json,yml,yaml,md}"',
|
|
69
69
|
build: "tsup",
|
|
70
70
|
"build:check": "tsc --noEmit",
|
|
71
71
|
update: "ncu -u --dep dev,prod && yarn up '**' -R",
|
|
@@ -108,43 +108,43 @@ var require_package = __commonJS({
|
|
|
108
108
|
],
|
|
109
109
|
homepage: "https://distube.js.org/",
|
|
110
110
|
dependencies: {
|
|
111
|
-
"@distube/ytdl-core": "^4.11.
|
|
111
|
+
"@distube/ytdl-core": "^4.11.3",
|
|
112
112
|
"@distube/ytpl": "^1.1.1",
|
|
113
|
-
"@distube/ytsr": "^1.1.
|
|
113
|
+
"@distube/ytsr": "^1.1.7",
|
|
114
114
|
"prism-media": "https://codeload.github.com/distubejs/prism-media/tar.gz/main#workaround.tar.gz",
|
|
115
115
|
"tiny-typed-emitter": "^2.1.0",
|
|
116
|
-
tslib: "^2.
|
|
116
|
+
tslib: "^2.4.0"
|
|
117
117
|
},
|
|
118
118
|
devDependencies: {
|
|
119
|
-
"@babel/core": "^7.
|
|
120
|
-
"@babel/plugin-proposal-class-properties": "^7.
|
|
121
|
-
"@babel/plugin-proposal-object-rest-spread": "^7.
|
|
122
|
-
"@babel/preset-env": "^7.
|
|
123
|
-
"@babel/preset-typescript": "^7.
|
|
124
|
-
"@commitlint/cli": "^
|
|
125
|
-
"@commitlint/config-conventional": "^
|
|
119
|
+
"@babel/core": "^7.18.6",
|
|
120
|
+
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
121
|
+
"@babel/plugin-proposal-object-rest-spread": "^7.18.6",
|
|
122
|
+
"@babel/preset-env": "^7.18.6",
|
|
123
|
+
"@babel/preset-typescript": "^7.18.6",
|
|
124
|
+
"@commitlint/cli": "^17.0.3",
|
|
125
|
+
"@commitlint/config-conventional": "^17.0.3",
|
|
126
126
|
"@discordjs/voice": "dev",
|
|
127
127
|
"@distube/docgen": "distubejs/docgen",
|
|
128
|
-
"@types/jest": "^
|
|
129
|
-
"@types/node": "^
|
|
130
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
131
|
-
"@typescript-eslint/parser": "^5.
|
|
132
|
-
"babel-jest": "^
|
|
128
|
+
"@types/jest": "^28.1.5",
|
|
129
|
+
"@types/node": "^18.0.4",
|
|
130
|
+
"@typescript-eslint/eslint-plugin": "^5.30.6",
|
|
131
|
+
"@typescript-eslint/parser": "^5.30.6",
|
|
132
|
+
"babel-jest": "^28.1.3",
|
|
133
133
|
"discord.js": "dev",
|
|
134
|
-
eslint: "^8.
|
|
134
|
+
eslint: "^8.19.0",
|
|
135
135
|
"eslint-config-distube": "^1.6.4",
|
|
136
136
|
"eslint-config-prettier": "^8.5.0",
|
|
137
137
|
"eslint-plugin-deprecation": "^1.3.2",
|
|
138
|
-
"eslint-plugin-jsdoc": "^
|
|
139
|
-
husky: "^
|
|
140
|
-
jest: "^
|
|
138
|
+
"eslint-plugin-jsdoc": "^39.3.3",
|
|
139
|
+
husky: "^8.0.1",
|
|
140
|
+
jest: "^28.1.3",
|
|
141
141
|
"jsdoc-babel": "^0.5.0",
|
|
142
|
-
"nano-staged": "^0.
|
|
143
|
-
"npm-check-updates": "^
|
|
142
|
+
"nano-staged": "^0.8.0",
|
|
143
|
+
"npm-check-updates": "^15.3.0",
|
|
144
144
|
pinst: "^3.0.0",
|
|
145
|
-
prettier: "^2.
|
|
146
|
-
tsup: "^
|
|
147
|
-
typescript: "^4.
|
|
145
|
+
prettier: "^2.7.1",
|
|
146
|
+
tsup: "^6.1.3",
|
|
147
|
+
typescript: "^4.7.4"
|
|
148
148
|
},
|
|
149
149
|
peerDependencies: {
|
|
150
150
|
"@discordjs/opus": "*",
|
|
@@ -191,6 +191,11 @@ var SearchResultType = /* @__PURE__ */ ((SearchResultType2) => {
|
|
|
191
191
|
SearchResultType2["PLAYLIST"] = "playlist";
|
|
192
192
|
return SearchResultType2;
|
|
193
193
|
})(SearchResultType || {});
|
|
194
|
+
var StreamType = /* @__PURE__ */ ((StreamType2) => {
|
|
195
|
+
StreamType2[StreamType2["OPUS"] = 0] = "OPUS";
|
|
196
|
+
StreamType2[StreamType2["RAW"] = 1] = "RAW";
|
|
197
|
+
return StreamType2;
|
|
198
|
+
})(StreamType || {});
|
|
194
199
|
|
|
195
200
|
// src/constant.ts
|
|
196
201
|
var defaultFilters = {
|
|
@@ -224,13 +229,14 @@ var defaultOptions = {
|
|
|
224
229
|
nsfw: false,
|
|
225
230
|
emitAddSongWhenCreatingQueue: true,
|
|
226
231
|
emitAddListWhenCreatingQueue: true,
|
|
227
|
-
joinNewVoiceChannel: true
|
|
232
|
+
joinNewVoiceChannel: true,
|
|
233
|
+
streamType: 0 /* OPUS */
|
|
228
234
|
};
|
|
229
235
|
|
|
230
236
|
// src/struct/DisTubeError.ts
|
|
231
237
|
import { inspect } from "node:util";
|
|
232
238
|
var ERROR_MESSAGES = {
|
|
233
|
-
INVALID_TYPE: (expected, got, name) => `Expected ${Array.isArray(expected) ? expected.map((e) => typeof e === "number" ? e : `'${e}'`).join(" or ") : `'${expected}'`}${name ? ` for '${name}'` : ""}, but got ${inspect(got)}`,
|
|
239
|
+
INVALID_TYPE: (expected, got, name) => `Expected ${Array.isArray(expected) ? expected.map((e) => typeof e === "number" ? e : `'${e}'`).join(" or ") : `'${expected}'`}${name ? ` for '${name}'` : ""}, but got ${inspect(got)} (${typeof got})`,
|
|
234
240
|
NUMBER_COMPARE: (name, expected, value) => `'${name}' must be ${expected} ${value}`,
|
|
235
241
|
EMPTY_ARRAY: (name) => `'${name}' is an empty array`,
|
|
236
242
|
EMPTY_FILTERED_ARRAY: (name, type) => `There is no valid '${type}' in the '${name}' array`,
|
|
@@ -246,7 +252,8 @@ var ERROR_MESSAGES = {
|
|
|
246
252
|
VOICE_CONNECT_FAILED: (s) => `Cannot connect to the voice channel after ${s} seconds`,
|
|
247
253
|
VOICE_MISSING_PERMS: "I do not have permission to join this voice channel",
|
|
248
254
|
VOICE_RECONNECT_FAILED: "Cannot reconnect to the voice channel",
|
|
249
|
-
VOICE_DIFFERENT_GUILD: "Cannot join a channel in a different guild",
|
|
255
|
+
VOICE_DIFFERENT_GUILD: "Cannot join a voice channel in a different guild",
|
|
256
|
+
VOICE_DIFFERENT_CLIENT: "Cannot join a voice channel created by a different client",
|
|
250
257
|
NO_QUEUE: "There is no playing queue in this guild",
|
|
251
258
|
QUEUE_EXIST: "This guild has a Queue already",
|
|
252
259
|
PAUSED: "The queue has been paused already",
|
|
@@ -285,6 +292,7 @@ var DisTubeError = class extends Error {
|
|
|
285
292
|
return this.errorCode;
|
|
286
293
|
}
|
|
287
294
|
};
|
|
295
|
+
__name(DisTubeError, "DisTubeError");
|
|
288
296
|
|
|
289
297
|
// src/struct/TaskQueue.ts
|
|
290
298
|
var Task = class {
|
|
@@ -298,6 +306,7 @@ var Task = class {
|
|
|
298
306
|
});
|
|
299
307
|
}
|
|
300
308
|
};
|
|
309
|
+
__name(Task, "Task");
|
|
301
310
|
var _tasks;
|
|
302
311
|
var TaskQueue = class {
|
|
303
312
|
constructor() {
|
|
@@ -318,6 +327,7 @@ var TaskQueue = class {
|
|
|
318
327
|
return !!__privateGet(this, _tasks).find((t) => t.resolveInfo);
|
|
319
328
|
}
|
|
320
329
|
};
|
|
330
|
+
__name(TaskQueue, "TaskQueue");
|
|
321
331
|
_tasks = new WeakMap();
|
|
322
332
|
|
|
323
333
|
// src/struct/Playlist.ts
|
|
@@ -332,26 +342,33 @@ var Playlist = class {
|
|
|
332
342
|
__publicField(this, "url");
|
|
333
343
|
__publicField(this, "thumbnail");
|
|
334
344
|
const { member, properties, metadata } = options;
|
|
335
|
-
if (typeof playlist !== "object") {
|
|
336
|
-
throw new DisTubeError("INVALID_TYPE", ["Array<Song>", "
|
|
345
|
+
if (typeof playlist !== "object" || !Array.isArray(playlist) && ["source", "songs"].some((key) => !(key in playlist))) {
|
|
346
|
+
throw new DisTubeError("INVALID_TYPE", ["Array<Song>", "PlaylistInfo"], playlist, "playlist");
|
|
337
347
|
}
|
|
338
348
|
if (typeof properties !== "undefined" && !isRecord(properties)) {
|
|
339
349
|
throw new DisTubeError("INVALID_TYPE", "object", properties, "properties");
|
|
340
350
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
351
|
+
if (Array.isArray(playlist)) {
|
|
352
|
+
this.source = "youtube";
|
|
353
|
+
if (!playlist.length)
|
|
354
|
+
throw new DisTubeError("EMPTY_PLAYLIST");
|
|
355
|
+
this.songs = playlist;
|
|
356
|
+
this.name = this.songs[0].name ? `${this.songs[0].name} and ${this.songs.length - 1} more songs.` : `${this.songs.length} songs playlist`;
|
|
357
|
+
this.thumbnail = this.songs[0].thumbnail;
|
|
358
|
+
} else {
|
|
359
|
+
this.source = (playlist.source || "youtube").toLowerCase();
|
|
360
|
+
if (!Array.isArray(playlist.songs) || !playlist.songs.length)
|
|
361
|
+
throw new DisTubeError("EMPTY_PLAYLIST");
|
|
362
|
+
this.songs = playlist.songs;
|
|
363
|
+
this.name = playlist.name || playlist.title || (this.songs[0].name ? `${this.songs[0].name} and ${this.songs.length - 1} more songs.` : `${this.songs.length} songs playlist`);
|
|
364
|
+
this.url = playlist.url || playlist.webpage_url;
|
|
365
|
+
this.thumbnail = playlist.thumbnail || this.songs[0].thumbnail;
|
|
346
366
|
}
|
|
347
367
|
this.songs.map((s) => s.constructor.name === "Song" && (s.playlist = this));
|
|
348
|
-
this.member = member || info.member || void 0;
|
|
349
|
-
this.name = info.name || info.title || (this.songs[0].name ? `${this.songs[0].name} and ${this.songs.length - 1} more songs.` : `${this.songs.length} songs playlist`);
|
|
350
|
-
this.url = info.url || info.webpage_url;
|
|
351
|
-
this.thumbnail = info.thumbnail?.url || info.thumbnail || this.songs[0].thumbnail;
|
|
352
368
|
if (properties)
|
|
353
369
|
for (const [key, value] of Object.entries(properties))
|
|
354
370
|
this[key] = value;
|
|
371
|
+
this.member = member;
|
|
355
372
|
this.metadata = metadata;
|
|
356
373
|
}
|
|
357
374
|
get duration() {
|
|
@@ -380,44 +397,69 @@ var Playlist = class {
|
|
|
380
397
|
this.songs.map((s) => s.constructor.name === "Song" && (s.metadata = metadata));
|
|
381
398
|
}
|
|
382
399
|
};
|
|
400
|
+
__name(Playlist, "Playlist");
|
|
383
401
|
_metadata = new WeakMap();
|
|
384
402
|
_member = new WeakMap();
|
|
385
403
|
|
|
386
404
|
// src/struct/SearchResult.ts
|
|
387
|
-
var
|
|
405
|
+
var ISearchResult = class {
|
|
388
406
|
constructor(info) {
|
|
389
407
|
__publicField(this, "source");
|
|
390
|
-
__publicField(this, "type");
|
|
391
408
|
__publicField(this, "id");
|
|
392
409
|
__publicField(this, "name");
|
|
393
410
|
__publicField(this, "url");
|
|
394
|
-
__publicField(this, "views");
|
|
395
|
-
__publicField(this, "isLive");
|
|
396
|
-
__publicField(this, "duration");
|
|
397
|
-
__publicField(this, "formattedDuration");
|
|
398
|
-
__publicField(this, "thumbnail");
|
|
399
411
|
__publicField(this, "uploader");
|
|
400
412
|
this.source = "youtube";
|
|
401
|
-
this.type = info.type === "video" ? "video" /* VIDEO */ : "playlist" /* PLAYLIST */;
|
|
402
413
|
this.id = info.id;
|
|
403
414
|
this.name = info.name;
|
|
404
415
|
this.url = info.url;
|
|
405
|
-
if (this.type === "video" /* VIDEO */) {
|
|
406
|
-
info = info;
|
|
407
|
-
this.views = info.views;
|
|
408
|
-
this.isLive = info.isLive;
|
|
409
|
-
this.duration = this.isLive ? 0 : toSecond(info.duration);
|
|
410
|
-
this.formattedDuration = this.isLive ? "Live" : formatDuration(this.duration);
|
|
411
|
-
this.thumbnail = info.thumbnail;
|
|
412
|
-
} else if (this.type !== "playlist") {
|
|
413
|
-
throw new DisTubeError("INVALID_TYPE", ["video", "playlist"], this.type, "SearchResult.type");
|
|
414
|
-
}
|
|
415
416
|
this.uploader = {
|
|
416
|
-
name:
|
|
417
|
-
url:
|
|
417
|
+
name: void 0,
|
|
418
|
+
url: void 0
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
__name(ISearchResult, "ISearchResult");
|
|
423
|
+
var SearchResultVideo = class extends ISearchResult {
|
|
424
|
+
constructor(info) {
|
|
425
|
+
super(info);
|
|
426
|
+
__publicField(this, "type");
|
|
427
|
+
__publicField(this, "views");
|
|
428
|
+
__publicField(this, "isLive");
|
|
429
|
+
__publicField(this, "duration");
|
|
430
|
+
__publicField(this, "formattedDuration");
|
|
431
|
+
__publicField(this, "thumbnail");
|
|
432
|
+
if (info.type !== "video")
|
|
433
|
+
throw new DisTubeError("INVALID_TYPE", "video", info.type, "type");
|
|
434
|
+
this.type = "video" /* VIDEO */;
|
|
435
|
+
this.views = info.views;
|
|
436
|
+
this.isLive = info.isLive;
|
|
437
|
+
this.duration = this.isLive ? 0 : toSecond(info.duration);
|
|
438
|
+
this.formattedDuration = this.isLive ? "Live" : formatDuration(this.duration);
|
|
439
|
+
this.thumbnail = info.thumbnail;
|
|
440
|
+
this.uploader = {
|
|
441
|
+
name: info.author?.name,
|
|
442
|
+
url: info.author?.url
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
__name(SearchResultVideo, "SearchResultVideo");
|
|
447
|
+
var SearchResultPlaylist = class extends ISearchResult {
|
|
448
|
+
constructor(info) {
|
|
449
|
+
super(info);
|
|
450
|
+
__publicField(this, "type");
|
|
451
|
+
__publicField(this, "length");
|
|
452
|
+
if (info.type !== "playlist")
|
|
453
|
+
throw new DisTubeError("INVALID_TYPE", "playlist", info.type, "type");
|
|
454
|
+
this.type = "playlist" /* PLAYLIST */;
|
|
455
|
+
this.length = info.length;
|
|
456
|
+
this.uploader = {
|
|
457
|
+
name: info.owner?.name,
|
|
458
|
+
url: info.owner?.url
|
|
418
459
|
};
|
|
419
460
|
}
|
|
420
461
|
};
|
|
462
|
+
__name(SearchResultPlaylist, "SearchResultPlaylist");
|
|
421
463
|
|
|
422
464
|
// src/struct/Song.ts
|
|
423
465
|
var _metadata2, _member2, _playlist;
|
|
@@ -552,112 +594,11 @@ var _Song = class {
|
|
|
552
594
|
}
|
|
553
595
|
};
|
|
554
596
|
var Song = _Song;
|
|
597
|
+
__name(Song, "Song");
|
|
555
598
|
_metadata2 = new WeakMap();
|
|
556
599
|
_member2 = new WeakMap();
|
|
557
600
|
_playlist = new WeakMap();
|
|
558
601
|
|
|
559
|
-
// src/core/DisTubeOptions.ts
|
|
560
|
-
var _validateOptions, validateOptions_fn;
|
|
561
|
-
var Options = class {
|
|
562
|
-
constructor(options) {
|
|
563
|
-
__privateAdd(this, _validateOptions);
|
|
564
|
-
__publicField(this, "plugins");
|
|
565
|
-
__publicField(this, "emitNewSongOnly");
|
|
566
|
-
__publicField(this, "leaveOnFinish");
|
|
567
|
-
__publicField(this, "leaveOnStop");
|
|
568
|
-
__publicField(this, "leaveOnEmpty");
|
|
569
|
-
__publicField(this, "emptyCooldown");
|
|
570
|
-
__publicField(this, "savePreviousSongs");
|
|
571
|
-
__publicField(this, "searchSongs");
|
|
572
|
-
__publicField(this, "searchCooldown");
|
|
573
|
-
__publicField(this, "youtubeCookie");
|
|
574
|
-
__publicField(this, "youtubeIdentityToken");
|
|
575
|
-
__publicField(this, "customFilters");
|
|
576
|
-
__publicField(this, "ytdlOptions");
|
|
577
|
-
__publicField(this, "nsfw");
|
|
578
|
-
__publicField(this, "emitAddSongWhenCreatingQueue");
|
|
579
|
-
__publicField(this, "emitAddListWhenCreatingQueue");
|
|
580
|
-
__publicField(this, "joinNewVoiceChannel");
|
|
581
|
-
if (typeof options !== "object" || Array.isArray(options)) {
|
|
582
|
-
throw new DisTubeError("INVALID_TYPE", "object", options, "DisTubeOptions");
|
|
583
|
-
}
|
|
584
|
-
const opts = { ...defaultOptions, ...options };
|
|
585
|
-
this.plugins = opts.plugins;
|
|
586
|
-
this.emitNewSongOnly = opts.emitNewSongOnly;
|
|
587
|
-
this.leaveOnEmpty = opts.leaveOnEmpty;
|
|
588
|
-
this.leaveOnFinish = opts.leaveOnFinish;
|
|
589
|
-
this.leaveOnStop = opts.leaveOnStop;
|
|
590
|
-
this.savePreviousSongs = opts.savePreviousSongs;
|
|
591
|
-
this.searchSongs = opts.searchSongs;
|
|
592
|
-
this.youtubeCookie = opts.youtubeCookie;
|
|
593
|
-
this.youtubeIdentityToken = opts.youtubeIdentityToken;
|
|
594
|
-
this.customFilters = opts.customFilters;
|
|
595
|
-
this.ytdlOptions = opts.ytdlOptions;
|
|
596
|
-
this.searchCooldown = opts.searchCooldown;
|
|
597
|
-
this.emptyCooldown = opts.emptyCooldown;
|
|
598
|
-
this.nsfw = opts.nsfw;
|
|
599
|
-
this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;
|
|
600
|
-
this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;
|
|
601
|
-
this.joinNewVoiceChannel = opts.joinNewVoiceChannel;
|
|
602
|
-
checkInvalidKey(opts, this, "DisTubeOptions");
|
|
603
|
-
__privateMethod(this, _validateOptions, validateOptions_fn).call(this);
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
_validateOptions = new WeakSet();
|
|
607
|
-
validateOptions_fn = /* @__PURE__ */ __name(function(options = this) {
|
|
608
|
-
if (typeof options.emitNewSongOnly !== "boolean") {
|
|
609
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitNewSongOnly, "DisTubeOptions.emitNewSongOnly");
|
|
610
|
-
}
|
|
611
|
-
if (typeof options.leaveOnEmpty !== "boolean") {
|
|
612
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnEmpty, "DisTubeOptions.leaveOnEmpty");
|
|
613
|
-
}
|
|
614
|
-
if (typeof options.leaveOnFinish !== "boolean") {
|
|
615
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnFinish, "DisTubeOptions.leaveOnFinish");
|
|
616
|
-
}
|
|
617
|
-
if (typeof options.leaveOnStop !== "boolean") {
|
|
618
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnStop, "DisTubeOptions.leaveOnStop");
|
|
619
|
-
}
|
|
620
|
-
if (typeof options.savePreviousSongs !== "boolean") {
|
|
621
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.savePreviousSongs, "DisTubeOptions.savePreviousSongs");
|
|
622
|
-
}
|
|
623
|
-
if (typeof options.joinNewVoiceChannel !== "boolean") {
|
|
624
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.joinNewVoiceChannel, "DisTubeOptions.joinNewVoiceChannel");
|
|
625
|
-
}
|
|
626
|
-
if (typeof options.youtubeCookie !== "undefined" && typeof options.youtubeCookie !== "string") {
|
|
627
|
-
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeCookie, "DisTubeOptions.youtubeCookie");
|
|
628
|
-
}
|
|
629
|
-
if (typeof options.youtubeIdentityToken !== "undefined" && typeof options.youtubeIdentityToken !== "string") {
|
|
630
|
-
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeIdentityToken, "DisTubeOptions.youtubeIdentityToken");
|
|
631
|
-
}
|
|
632
|
-
if (typeof options.customFilters !== "undefined" && typeof options.customFilters !== "object" || Array.isArray(options.customFilters)) {
|
|
633
|
-
throw new DisTubeError("INVALID_TYPE", "object", options.customFilters, "DisTubeOptions.customFilters");
|
|
634
|
-
}
|
|
635
|
-
if (typeof options.ytdlOptions !== "object" || Array.isArray(options.ytdlOptions)) {
|
|
636
|
-
throw new DisTubeError("INVALID_TYPE", "object", options.ytdlOptions, "DisTubeOptions.ytdlOptions");
|
|
637
|
-
}
|
|
638
|
-
if (typeof options.searchCooldown !== "number" || isNaN(options.searchCooldown)) {
|
|
639
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.searchCooldown, "DisTubeOptions.searchCooldown");
|
|
640
|
-
}
|
|
641
|
-
if (typeof options.emptyCooldown !== "number" || isNaN(options.emptyCooldown)) {
|
|
642
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.emptyCooldown, "DisTubeOptions.emptyCooldown");
|
|
643
|
-
}
|
|
644
|
-
if (typeof options.searchSongs !== "number" || isNaN(options.searchSongs)) {
|
|
645
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.searchSongs, "DisTubeOptions.searchSongs");
|
|
646
|
-
}
|
|
647
|
-
if (!Array.isArray(options.plugins)) {
|
|
648
|
-
throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", options.plugins, "DisTubeOptions.plugins");
|
|
649
|
-
}
|
|
650
|
-
if (typeof options.nsfw !== "boolean") {
|
|
651
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.nsfw, "DisTubeOptions.nsfw");
|
|
652
|
-
}
|
|
653
|
-
if (typeof options.emitAddSongWhenCreatingQueue !== "boolean") {
|
|
654
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddSongWhenCreatingQueue, "DisTubeOptions.emitAddSongWhenCreatingQueue");
|
|
655
|
-
}
|
|
656
|
-
if (typeof options.emitAddListWhenCreatingQueue !== "boolean") {
|
|
657
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddListWhenCreatingQueue, "DisTubeOptions.emitAddListWhenCreatingQueue");
|
|
658
|
-
}
|
|
659
|
-
}, "#validateOptions");
|
|
660
|
-
|
|
661
602
|
// src/core/DisTubeBase.ts
|
|
662
603
|
var DisTubeBase = class {
|
|
663
604
|
constructor(distube) {
|
|
@@ -686,75 +627,206 @@ var DisTubeBase = class {
|
|
|
686
627
|
return this.distube.handler;
|
|
687
628
|
}
|
|
688
629
|
};
|
|
630
|
+
__name(DisTubeBase, "DisTubeBase");
|
|
689
631
|
|
|
690
|
-
// src/core/
|
|
691
|
-
import {
|
|
692
|
-
import {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
this
|
|
706
|
-
this
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
632
|
+
// src/core/DisTubeVoice.ts
|
|
633
|
+
import { TypedEmitter } from "tiny-typed-emitter";
|
|
634
|
+
import {
|
|
635
|
+
AudioPlayerStatus,
|
|
636
|
+
VoiceConnectionDisconnectReason,
|
|
637
|
+
VoiceConnectionStatus,
|
|
638
|
+
createAudioPlayer,
|
|
639
|
+
createAudioResource,
|
|
640
|
+
entersState,
|
|
641
|
+
joinVoiceChannel
|
|
642
|
+
} from "@discordjs/voice";
|
|
643
|
+
var _channel, _volume, _br, br_fn, _join, join_fn;
|
|
644
|
+
var DisTubeVoice = class extends TypedEmitter {
|
|
645
|
+
constructor(voiceManager, channel) {
|
|
646
|
+
super();
|
|
647
|
+
__privateAdd(this, _br);
|
|
648
|
+
__privateAdd(this, _join);
|
|
649
|
+
__publicField(this, "id");
|
|
650
|
+
__publicField(this, "voices");
|
|
651
|
+
__publicField(this, "audioPlayer");
|
|
652
|
+
__publicField(this, "connection");
|
|
653
|
+
__publicField(this, "audioResource");
|
|
654
|
+
__publicField(this, "emittedError");
|
|
655
|
+
__publicField(this, "isDisconnected", false);
|
|
656
|
+
__privateAdd(this, _channel, void 0);
|
|
657
|
+
__privateAdd(this, _volume, 100);
|
|
658
|
+
this.voices = voiceManager;
|
|
659
|
+
this.id = channel.guildId;
|
|
660
|
+
this.channel = channel;
|
|
661
|
+
this.voices.add(this.id, this);
|
|
662
|
+
this.audioPlayer = createAudioPlayer().on(AudioPlayerStatus.Idle, (oldState) => {
|
|
663
|
+
if (oldState.status !== AudioPlayerStatus.Idle) {
|
|
664
|
+
delete this.audioResource;
|
|
665
|
+
this.emit("finish");
|
|
666
|
+
}
|
|
667
|
+
}).on(AudioPlayerStatus.Playing, () => __privateMethod(this, _br, br_fn).call(this)).on("error", (error) => {
|
|
668
|
+
if (this.emittedError)
|
|
669
|
+
return;
|
|
670
|
+
this.emittedError = true;
|
|
671
|
+
this.emit("error", error);
|
|
672
|
+
});
|
|
673
|
+
this.connection.on(VoiceConnectionStatus.Disconnected, (_, newState) => {
|
|
674
|
+
if (newState.reason === VoiceConnectionDisconnectReason.Manual) {
|
|
675
|
+
this.leave();
|
|
676
|
+
} else if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
|
|
677
|
+
entersState(this.connection, VoiceConnectionStatus.Connecting, 5e3).catch(() => {
|
|
678
|
+
if (![VoiceConnectionStatus.Ready, VoiceConnectionStatus.Connecting].includes(this.connection.state.status)) {
|
|
679
|
+
this.leave();
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
} else if (this.connection.rejoinAttempts < 5) {
|
|
683
|
+
setTimeout(() => {
|
|
684
|
+
this.connection.rejoin();
|
|
685
|
+
}, (this.connection.rejoinAttempts + 1) * 5e3).unref();
|
|
686
|
+
} else if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) {
|
|
687
|
+
this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
|
|
688
|
+
}
|
|
689
|
+
}).on(VoiceConnectionStatus.Destroyed, () => {
|
|
690
|
+
this.leave();
|
|
691
|
+
}).on("error", () => void 0);
|
|
692
|
+
this.connection.subscribe(this.audioPlayer);
|
|
734
693
|
}
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
throw new DisTubeError("UNAVAILABLE_VIDEO");
|
|
738
|
-
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
739
|
-
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
740
|
-
}
|
|
741
|
-
const bestFormat = chooseBestVideoFormat(formats, options.isLive);
|
|
742
|
-
if (!bestFormat)
|
|
743
|
-
throw new DisTubeError("UNPLAYABLE_FORMATS");
|
|
744
|
-
return new DisTubeStream(bestFormat.url, options);
|
|
694
|
+
get channel() {
|
|
695
|
+
return __privateGet(this, _channel);
|
|
745
696
|
}
|
|
746
|
-
|
|
747
|
-
if (!
|
|
748
|
-
throw new DisTubeError("INVALID_TYPE", "
|
|
749
|
-
}
|
|
750
|
-
if (typeof url !== "string" || !isURL(url)) {
|
|
751
|
-
throw new DisTubeError("INVALID_TYPE", "an URL", url);
|
|
697
|
+
set channel(channel) {
|
|
698
|
+
if (!isSupportedVoiceChannel(channel)) {
|
|
699
|
+
throw new DisTubeError("INVALID_TYPE", "BaseGuildVoiceChannel", channel, "DisTubeVoice#channel");
|
|
752
700
|
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
701
|
+
if (channel.guildId !== this.id)
|
|
702
|
+
throw new DisTubeError("VOICE_DIFFERENT_GUILD");
|
|
703
|
+
if (channel.client.user?.id !== this.voices.client.user?.id)
|
|
704
|
+
throw new DisTubeError("VOICE_DIFFERENT_CLIENT");
|
|
705
|
+
if (channel.id === __privateGet(this, _channel)?.id)
|
|
706
|
+
return;
|
|
707
|
+
if (!channel.joinable) {
|
|
708
|
+
if (channel.full)
|
|
709
|
+
throw new DisTubeError("VOICE_FULL");
|
|
710
|
+
else
|
|
711
|
+
throw new DisTubeError("VOICE_MISSING_PERMS");
|
|
712
|
+
}
|
|
713
|
+
this.connection = __privateMethod(this, _join, join_fn).call(this, channel);
|
|
714
|
+
__privateSet(this, _channel, channel);
|
|
715
|
+
__privateMethod(this, _br, br_fn).call(this);
|
|
716
|
+
}
|
|
717
|
+
async join(channel) {
|
|
718
|
+
const TIMEOUT = 3e4;
|
|
719
|
+
if (channel)
|
|
720
|
+
this.channel = channel;
|
|
721
|
+
try {
|
|
722
|
+
await entersState(this.connection, VoiceConnectionStatus.Ready, TIMEOUT);
|
|
723
|
+
} catch {
|
|
724
|
+
if (this.connection.state.status === VoiceConnectionStatus.Ready)
|
|
725
|
+
return this;
|
|
726
|
+
if (this.connection.state.status !== VoiceConnectionStatus.Destroyed)
|
|
727
|
+
this.connection.destroy();
|
|
728
|
+
this.voices.remove(this.id);
|
|
729
|
+
throw new DisTubeError("VOICE_CONNECT_FAILED", TIMEOUT / 1e3);
|
|
730
|
+
}
|
|
731
|
+
return this;
|
|
732
|
+
}
|
|
733
|
+
leave(error) {
|
|
734
|
+
this.stop(true);
|
|
735
|
+
if (!this.isDisconnected) {
|
|
736
|
+
this.emit("disconnect", error);
|
|
737
|
+
this.isDisconnected = true;
|
|
738
|
+
}
|
|
739
|
+
if (this.connection.state.status !== VoiceConnectionStatus.Destroyed)
|
|
740
|
+
this.connection.destroy();
|
|
741
|
+
this.voices.remove(this.id);
|
|
742
|
+
}
|
|
743
|
+
stop(force = false) {
|
|
744
|
+
this.audioPlayer.stop(force);
|
|
745
|
+
}
|
|
746
|
+
play(stream) {
|
|
747
|
+
this.emittedError = false;
|
|
748
|
+
stream.stream.on("error", (error) => {
|
|
749
|
+
if (this.emittedError || error.code === "ERR_STREAM_PREMATURE_CLOSE")
|
|
750
|
+
return;
|
|
751
|
+
this.emittedError = true;
|
|
752
|
+
this.emit("error", error);
|
|
753
|
+
});
|
|
754
|
+
this.audioResource = createAudioResource(stream.stream, {
|
|
755
|
+
inputType: stream.type,
|
|
756
|
+
inlineVolume: true
|
|
757
|
+
});
|
|
758
|
+
this.volume = __privateGet(this, _volume);
|
|
759
|
+
this.audioPlayer.play(this.audioResource);
|
|
760
|
+
}
|
|
761
|
+
set volume(volume) {
|
|
762
|
+
if (typeof volume !== "number" || isNaN(volume)) {
|
|
763
|
+
throw new DisTubeError("INVALID_TYPE", "number", volume, "volume");
|
|
764
|
+
}
|
|
765
|
+
if (volume < 0) {
|
|
766
|
+
throw new DisTubeError("NUMBER_COMPARE", "Volume", "bigger or equal to", 0);
|
|
767
|
+
}
|
|
768
|
+
__privateSet(this, _volume, volume);
|
|
769
|
+
this.audioResource?.volume?.setVolume(Math.pow(__privateGet(this, _volume) / 100, 0.5 / Math.log10(2)));
|
|
770
|
+
}
|
|
771
|
+
get volume() {
|
|
772
|
+
return __privateGet(this, _volume);
|
|
773
|
+
}
|
|
774
|
+
get playbackDuration() {
|
|
775
|
+
return (this.audioResource?.playbackDuration ?? 0) / 1e3;
|
|
776
|
+
}
|
|
777
|
+
pause() {
|
|
778
|
+
this.audioPlayer.pause();
|
|
779
|
+
}
|
|
780
|
+
unpause() {
|
|
781
|
+
this.audioPlayer.unpause();
|
|
782
|
+
}
|
|
783
|
+
get selfDeaf() {
|
|
784
|
+
return this.connection.joinConfig.selfDeaf;
|
|
785
|
+
}
|
|
786
|
+
get selfMute() {
|
|
787
|
+
return this.connection.joinConfig.selfMute;
|
|
788
|
+
}
|
|
789
|
+
setSelfDeaf(selfDeaf) {
|
|
790
|
+
if (typeof selfDeaf !== "boolean") {
|
|
791
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", selfDeaf, "selfDeaf");
|
|
792
|
+
}
|
|
793
|
+
return this.connection.rejoin({
|
|
794
|
+
...this.connection.joinConfig,
|
|
795
|
+
selfDeaf
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
setSelfMute(selfMute) {
|
|
799
|
+
if (typeof selfMute !== "boolean") {
|
|
800
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", selfMute, "selfMute");
|
|
801
|
+
}
|
|
802
|
+
return this.connection.rejoin({
|
|
803
|
+
...this.connection.joinConfig,
|
|
804
|
+
selfMute
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
get voiceState() {
|
|
808
|
+
return this.channel?.guild?.members?.me?.voice;
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
__name(DisTubeVoice, "DisTubeVoice");
|
|
812
|
+
_channel = new WeakMap();
|
|
813
|
+
_volume = new WeakMap();
|
|
814
|
+
_br = new WeakSet();
|
|
815
|
+
br_fn = /* @__PURE__ */ __name(function() {
|
|
816
|
+
if (this.audioResource?.encoder?.encoder)
|
|
817
|
+
this.audioResource.encoder.setBitrate(this.channel.bitrate);
|
|
818
|
+
}, "#br");
|
|
819
|
+
_join = new WeakSet();
|
|
820
|
+
join_fn = /* @__PURE__ */ __name(function(channel) {
|
|
821
|
+
return joinVoiceChannel({
|
|
822
|
+
channelId: channel.id,
|
|
823
|
+
guildId: this.id,
|
|
824
|
+
adapterCreator: channel.guild.voiceAdapterCreator,
|
|
825
|
+
group: channel.client.user?.id
|
|
826
|
+
});
|
|
827
|
+
}, "#join");
|
|
828
|
+
|
|
829
|
+
// src/core/manager/BaseManager.ts
|
|
758
830
|
import { Collection } from "discord.js";
|
|
759
831
|
var BaseManager = class extends DisTubeBase {
|
|
760
832
|
constructor() {
|
|
@@ -765,6 +837,7 @@ var BaseManager = class extends DisTubeBase {
|
|
|
765
837
|
return this.collection.size;
|
|
766
838
|
}
|
|
767
839
|
};
|
|
840
|
+
__name(BaseManager, "BaseManager");
|
|
768
841
|
|
|
769
842
|
// src/core/manager/GuildIdManager.ts
|
|
770
843
|
var GuildIdManager = class extends BaseManager {
|
|
@@ -785,6 +858,124 @@ var GuildIdManager = class extends BaseManager {
|
|
|
785
858
|
return this.collection.has(resolveGuildId(idOrInstance));
|
|
786
859
|
}
|
|
787
860
|
};
|
|
861
|
+
__name(GuildIdManager, "GuildIdManager");
|
|
862
|
+
|
|
863
|
+
// src/core/manager/DisTubeVoiceManager.ts
|
|
864
|
+
import { VoiceConnectionStatus as VoiceConnectionStatus2, getVoiceConnection } from "@discordjs/voice";
|
|
865
|
+
var DisTubeVoiceManager = class extends GuildIdManager {
|
|
866
|
+
create(channel) {
|
|
867
|
+
const existing = this.get(channel.guildId);
|
|
868
|
+
if (existing) {
|
|
869
|
+
existing.channel = channel;
|
|
870
|
+
return existing;
|
|
871
|
+
}
|
|
872
|
+
return new DisTubeVoice(this, channel);
|
|
873
|
+
}
|
|
874
|
+
join(channel) {
|
|
875
|
+
const existing = this.get(channel.guildId);
|
|
876
|
+
if (existing)
|
|
877
|
+
return existing.join(channel);
|
|
878
|
+
return this.create(channel).join();
|
|
879
|
+
}
|
|
880
|
+
leave(guild) {
|
|
881
|
+
const voice = this.get(guild);
|
|
882
|
+
if (voice) {
|
|
883
|
+
voice.leave();
|
|
884
|
+
} else {
|
|
885
|
+
const connection = getVoiceConnection(resolveGuildId(guild), this.client.user?.id) ?? getVoiceConnection(resolveGuildId(guild));
|
|
886
|
+
if (connection && connection.state.status !== VoiceConnectionStatus2.Destroyed) {
|
|
887
|
+
connection.destroy();
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
__name(DisTubeVoiceManager, "DisTubeVoiceManager");
|
|
893
|
+
|
|
894
|
+
// src/core/manager/FilterManager.ts
|
|
895
|
+
var _validate, validate_fn, _resolveName, resolveName_fn, _resolveValue, resolveValue_fn, _apply, apply_fn;
|
|
896
|
+
var FilterManager = class extends BaseManager {
|
|
897
|
+
constructor(queue) {
|
|
898
|
+
super(queue.distube);
|
|
899
|
+
__privateAdd(this, _validate);
|
|
900
|
+
__privateAdd(this, _resolveName);
|
|
901
|
+
__privateAdd(this, _resolveValue);
|
|
902
|
+
__privateAdd(this, _apply);
|
|
903
|
+
__publicField(this, "queue");
|
|
904
|
+
this.queue = queue;
|
|
905
|
+
}
|
|
906
|
+
add(filterOrFilters, override = false) {
|
|
907
|
+
if (Array.isArray(filterOrFilters)) {
|
|
908
|
+
const resolvedFilters = filterOrFilters.map((f) => __privateMethod(this, _validate, validate_fn).call(this, f));
|
|
909
|
+
const newFilters = resolvedFilters.reduceRight((unique, o) => {
|
|
910
|
+
if (!unique.some((obj) => obj === o && obj.name === o) && !unique.some((obj) => obj !== o.name && obj.name !== o.name)) {
|
|
911
|
+
if (!this.has(o))
|
|
912
|
+
unique.push(o);
|
|
913
|
+
if (this.has(o) && override) {
|
|
914
|
+
this.remove(o);
|
|
915
|
+
unique.push(o);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
return unique;
|
|
919
|
+
}, []).reverse();
|
|
920
|
+
return this.set([...this.collection.values(), ...newFilters]);
|
|
921
|
+
}
|
|
922
|
+
return this.set([...this.collection.values(), filterOrFilters]);
|
|
923
|
+
}
|
|
924
|
+
clear() {
|
|
925
|
+
return this.set([]);
|
|
926
|
+
}
|
|
927
|
+
set(filters) {
|
|
928
|
+
this.collection.clear();
|
|
929
|
+
for (const filter of filters) {
|
|
930
|
+
const resolved = __privateMethod(this, _validate, validate_fn).call(this, filter);
|
|
931
|
+
this.collection.set(__privateMethod(this, _resolveName, resolveName_fn).call(this, resolved), resolved);
|
|
932
|
+
}
|
|
933
|
+
__privateMethod(this, _apply, apply_fn).call(this);
|
|
934
|
+
return this;
|
|
935
|
+
}
|
|
936
|
+
remove(filterOrFilters) {
|
|
937
|
+
const remove = /* @__PURE__ */ __name((f) => this.collection.delete(__privateMethod(this, _resolveName, resolveName_fn).call(this, __privateMethod(this, _validate, validate_fn).call(this, f))), "remove");
|
|
938
|
+
if (Array.isArray(filterOrFilters))
|
|
939
|
+
filterOrFilters.map(remove);
|
|
940
|
+
else
|
|
941
|
+
remove(filterOrFilters);
|
|
942
|
+
__privateMethod(this, _apply, apply_fn).call(this);
|
|
943
|
+
return this;
|
|
944
|
+
}
|
|
945
|
+
has(filter) {
|
|
946
|
+
return this.collection.has(__privateMethod(this, _resolveName, resolveName_fn).call(this, filter));
|
|
947
|
+
}
|
|
948
|
+
get names() {
|
|
949
|
+
return this.collection.map((f) => __privateMethod(this, _resolveName, resolveName_fn).call(this, f));
|
|
950
|
+
}
|
|
951
|
+
get values() {
|
|
952
|
+
return this.collection.map((f) => __privateMethod(this, _resolveValue, resolveValue_fn).call(this, f));
|
|
953
|
+
}
|
|
954
|
+
toString() {
|
|
955
|
+
return this.names.toString();
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
__name(FilterManager, "FilterManager");
|
|
959
|
+
_validate = new WeakSet();
|
|
960
|
+
validate_fn = /* @__PURE__ */ __name(function(filter) {
|
|
961
|
+
if (typeof filter === "string" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter) || typeof filter === "object" && typeof filter.name === "string" && typeof filter.value === "string") {
|
|
962
|
+
return filter;
|
|
963
|
+
}
|
|
964
|
+
throw new DisTubeError("INVALID_TYPE", "FilterResolvable", filter, "filter");
|
|
965
|
+
}, "#validate");
|
|
966
|
+
_resolveName = new WeakSet();
|
|
967
|
+
resolveName_fn = /* @__PURE__ */ __name(function(filter) {
|
|
968
|
+
return typeof filter === "string" ? filter : filter.name;
|
|
969
|
+
}, "#resolveName");
|
|
970
|
+
_resolveValue = new WeakSet();
|
|
971
|
+
resolveValue_fn = /* @__PURE__ */ __name(function(filter) {
|
|
972
|
+
return typeof filter === "string" ? this.distube.filters[filter] : filter.value;
|
|
973
|
+
}, "#resolveValue");
|
|
974
|
+
_apply = new WeakSet();
|
|
975
|
+
apply_fn = /* @__PURE__ */ __name(function() {
|
|
976
|
+
this.queue.beginTime = this.queue.currentTime;
|
|
977
|
+
this.queues.playSong(this.queue);
|
|
978
|
+
}, "#apply");
|
|
788
979
|
|
|
789
980
|
// src/core/manager/QueueManager.ts
|
|
790
981
|
var _voiceEventHandler, voiceEventHandler_fn, _handleSongFinish, handleSongFinish_fn, _handlePlayingError, handlePlayingError_fn, _emitPlaySong, emitPlaySong_fn;
|
|
@@ -817,7 +1008,7 @@ var QueueManager = class extends GuildIdManager {
|
|
|
817
1008
|
const { duration, formats, isLive, source, streamURL } = queue.songs[0];
|
|
818
1009
|
const ffmpegArgs = queue.filters.size ? ["-af", queue.filters.values.join(",")] : void 0;
|
|
819
1010
|
const seek = duration ? queue.beginTime : void 0;
|
|
820
|
-
const streamOptions = { ffmpegArgs, seek, isLive };
|
|
1011
|
+
const streamOptions = { ffmpegArgs, seek, isLive, type: this.options.streamType };
|
|
821
1012
|
if (source === "youtube")
|
|
822
1013
|
return DisTubeStream.YouTube(formats, streamOptions);
|
|
823
1014
|
return DisTubeStream.DirectLink(streamURL, streamOptions);
|
|
@@ -831,8 +1022,8 @@ var QueueManager = class extends GuildIdManager {
|
|
|
831
1022
|
}
|
|
832
1023
|
if (queue.stopped)
|
|
833
1024
|
return false;
|
|
834
|
-
const song = queue.songs[0];
|
|
835
1025
|
try {
|
|
1026
|
+
const song = queue.songs[0];
|
|
836
1027
|
const { url, source, formats, streamURL } = song;
|
|
837
1028
|
if (source === "youtube" && !formats)
|
|
838
1029
|
song._patchYouTube(await this.handler.getYouTubeInfo(url));
|
|
@@ -861,6 +1052,7 @@ var QueueManager = class extends GuildIdManager {
|
|
|
861
1052
|
}
|
|
862
1053
|
}
|
|
863
1054
|
};
|
|
1055
|
+
__name(QueueManager, "QueueManager");
|
|
864
1056
|
_voiceEventHandler = new WeakSet();
|
|
865
1057
|
voiceEventHandler_fn = /* @__PURE__ */ __name(function(queue) {
|
|
866
1058
|
queue._listeners = {
|
|
@@ -893,377 +1085,69 @@ handleSongFinish_fn = /* @__PURE__ */ __name(async function(queue) {
|
|
|
893
1085
|
queue.songs.unshift(queue.previousSongs.pop());
|
|
894
1086
|
}
|
|
895
1087
|
if (queue.songs.length <= 1 && (queue._next || queue.repeatMode === 0 /* DISABLED */)) {
|
|
896
|
-
if (queue.autoplay) {
|
|
897
|
-
try {
|
|
898
|
-
await queue.addRelatedSong();
|
|
899
|
-
} catch {
|
|
900
|
-
this.emit("noRelated", queue);
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
if (queue.songs.length <= 1) {
|
|
904
|
-
if (this.options.leaveOnFinish)
|
|
905
|
-
queue.voice.leave();
|
|
906
|
-
if (!queue.autoplay)
|
|
907
|
-
this.emit("finish", queue);
|
|
908
|
-
queue.remove();
|
|
909
|
-
return;
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
const emitPlaySong = __privateMethod(this, _emitPlaySong, emitPlaySong_fn).call(this, queue);
|
|
913
|
-
if (!queue._prev && (queue.repeatMode !== 1 /* SONG */ || queue._next)) {
|
|
914
|
-
const prev = queue.songs.shift();
|
|
915
|
-
delete prev.formats;
|
|
916
|
-
delete prev.streamURL;
|
|
917
|
-
if (this.options.savePreviousSongs)
|
|
918
|
-
queue.previousSongs.push(prev);
|
|
919
|
-
else
|
|
920
|
-
queue.previousSongs.push({ id: prev.id });
|
|
921
|
-
}
|
|
922
|
-
queue._next = queue._prev = false;
|
|
923
|
-
queue.beginTime = 0;
|
|
924
|
-
const err = await this.playSong(queue);
|
|
925
|
-
if (!err && emitPlaySong)
|
|
926
|
-
this.emit("playSong", queue, queue.songs[0]);
|
|
927
|
-
} finally {
|
|
928
|
-
queue._taskQueue.resolve();
|
|
929
|
-
}
|
|
930
|
-
}, "#handleSongFinish");
|
|
931
|
-
_handlePlayingError = new WeakSet();
|
|
932
|
-
handlePlayingError_fn = /* @__PURE__ */ __name(function(queue, error) {
|
|
933
|
-
const song = queue.songs.shift();
|
|
934
|
-
try {
|
|
935
|
-
error.name = "PlayingError";
|
|
936
|
-
error.message = `${error.message}
|
|
937
|
-
Id: ${song.id}
|
|
938
|
-
Name: ${song.name}`;
|
|
939
|
-
} catch {
|
|
940
|
-
}
|
|
941
|
-
this.emitError(error, queue.textChannel);
|
|
942
|
-
if (queue.songs.length > 0) {
|
|
943
|
-
this.playSong(queue).then((e) => {
|
|
944
|
-
if (!e)
|
|
945
|
-
this.emit("playSong", queue, queue.songs[0]);
|
|
946
|
-
});
|
|
947
|
-
} else {
|
|
948
|
-
queue.stop();
|
|
949
|
-
}
|
|
950
|
-
}, "#handlePlayingError");
|
|
951
|
-
_emitPlaySong = new WeakSet();
|
|
952
|
-
emitPlaySong_fn = /* @__PURE__ */ __name(function(queue) {
|
|
953
|
-
return !this.options.emitNewSongOnly || queue.repeatMode === 1 /* SONG */ && queue._next || queue.repeatMode !== 1 /* SONG */ && queue.songs[0]?.id !== queue.songs[1]?.id;
|
|
954
|
-
}, "#emitPlaySong");
|
|
955
|
-
|
|
956
|
-
// src/core/manager/FilterManager.ts
|
|
957
|
-
var _validate, validate_fn, _resolveName, resolveName_fn, _resolveValue, resolveValue_fn, _apply, apply_fn;
|
|
958
|
-
var FilterManager = class extends BaseManager {
|
|
959
|
-
constructor(queue) {
|
|
960
|
-
super(queue.distube);
|
|
961
|
-
__privateAdd(this, _validate);
|
|
962
|
-
__privateAdd(this, _resolveName);
|
|
963
|
-
__privateAdd(this, _resolveValue);
|
|
964
|
-
__privateAdd(this, _apply);
|
|
965
|
-
__publicField(this, "queue");
|
|
966
|
-
this.queue = queue;
|
|
967
|
-
}
|
|
968
|
-
add(filterOrFilters, override = false) {
|
|
969
|
-
if (Array.isArray(filterOrFilters)) {
|
|
970
|
-
const resolvedFilters = filterOrFilters.map((f) => __privateMethod(this, _validate, validate_fn).call(this, f));
|
|
971
|
-
const newFilters = resolvedFilters.reduceRight((unique, o) => {
|
|
972
|
-
if (!unique.some((obj) => obj === o && obj.name === o) && !unique.some((obj) => obj !== o.name && obj.name !== o.name)) {
|
|
973
|
-
if (!this.has(o))
|
|
974
|
-
unique.push(o);
|
|
975
|
-
if (this.has(o) && override) {
|
|
976
|
-
this.remove(o);
|
|
977
|
-
unique.push(o);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
return unique;
|
|
981
|
-
}, []).reverse();
|
|
982
|
-
return this.set([...this.collection.values(), ...newFilters]);
|
|
983
|
-
}
|
|
984
|
-
return this.set([...this.collection.values(), filterOrFilters]);
|
|
985
|
-
}
|
|
986
|
-
clear() {
|
|
987
|
-
return this.set([]);
|
|
988
|
-
}
|
|
989
|
-
set(filters) {
|
|
990
|
-
this.collection.clear();
|
|
991
|
-
for (const filter of filters) {
|
|
992
|
-
const resolved = __privateMethod(this, _validate, validate_fn).call(this, filter);
|
|
993
|
-
this.collection.set(__privateMethod(this, _resolveName, resolveName_fn).call(this, resolved), resolved);
|
|
994
|
-
}
|
|
995
|
-
__privateMethod(this, _apply, apply_fn).call(this);
|
|
996
|
-
return this;
|
|
997
|
-
}
|
|
998
|
-
remove(filterOrFilters) {
|
|
999
|
-
const remove = /* @__PURE__ */ __name((f) => this.collection.delete(__privateMethod(this, _resolveName, resolveName_fn).call(this, __privateMethod(this, _validate, validate_fn).call(this, f))), "remove");
|
|
1000
|
-
if (Array.isArray(filterOrFilters))
|
|
1001
|
-
filterOrFilters.map(remove);
|
|
1002
|
-
else
|
|
1003
|
-
remove(filterOrFilters);
|
|
1004
|
-
__privateMethod(this, _apply, apply_fn).call(this);
|
|
1005
|
-
return this;
|
|
1006
|
-
}
|
|
1007
|
-
has(filter) {
|
|
1008
|
-
return this.collection.has(__privateMethod(this, _resolveName, resolveName_fn).call(this, filter));
|
|
1009
|
-
}
|
|
1010
|
-
get names() {
|
|
1011
|
-
return this.collection.map((f) => __privateMethod(this, _resolveName, resolveName_fn).call(this, f));
|
|
1012
|
-
}
|
|
1013
|
-
get values() {
|
|
1014
|
-
return this.collection.map((f) => __privateMethod(this, _resolveValue, resolveValue_fn).call(this, f));
|
|
1015
|
-
}
|
|
1016
|
-
toString() {
|
|
1017
|
-
return this.names.toString();
|
|
1018
|
-
}
|
|
1019
|
-
};
|
|
1020
|
-
_validate = new WeakSet();
|
|
1021
|
-
validate_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1022
|
-
if (typeof filter === "string" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter) || typeof filter === "object" && typeof filter.name === "string" && typeof filter.value === "string") {
|
|
1023
|
-
return filter;
|
|
1024
|
-
}
|
|
1025
|
-
throw new DisTubeError("INVALID_TYPE", "FilterResolvable", filter, "filter");
|
|
1026
|
-
}, "#validate");
|
|
1027
|
-
_resolveName = new WeakSet();
|
|
1028
|
-
resolveName_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1029
|
-
return typeof filter === "string" ? filter : filter.name;
|
|
1030
|
-
}, "#resolveName");
|
|
1031
|
-
_resolveValue = new WeakSet();
|
|
1032
|
-
resolveValue_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1033
|
-
return typeof filter === "string" ? this.distube.filters[filter] : filter.value;
|
|
1034
|
-
}, "#resolveValue");
|
|
1035
|
-
_apply = new WeakSet();
|
|
1036
|
-
apply_fn = /* @__PURE__ */ __name(function() {
|
|
1037
|
-
this.queue.beginTime = this.queue.currentTime;
|
|
1038
|
-
this.queues.playSong(this.queue);
|
|
1039
|
-
}, "#apply");
|
|
1040
|
-
|
|
1041
|
-
// src/core/voice/DisTubeVoice.ts
|
|
1042
|
-
import { TypedEmitter } from "tiny-typed-emitter";
|
|
1043
|
-
import {
|
|
1044
|
-
AudioPlayerStatus,
|
|
1045
|
-
VoiceConnectionDisconnectReason,
|
|
1046
|
-
VoiceConnectionStatus,
|
|
1047
|
-
createAudioPlayer,
|
|
1048
|
-
createAudioResource,
|
|
1049
|
-
joinVoiceChannel
|
|
1050
|
-
} from "@discordjs/voice";
|
|
1051
|
-
var _channel, _volume, _br, br_fn, _join, join_fn;
|
|
1052
|
-
var DisTubeVoice = class extends TypedEmitter {
|
|
1053
|
-
constructor(voiceManager, channel) {
|
|
1054
|
-
super();
|
|
1055
|
-
__privateAdd(this, _br);
|
|
1056
|
-
__privateAdd(this, _join);
|
|
1057
|
-
__publicField(this, "id");
|
|
1058
|
-
__publicField(this, "voices");
|
|
1059
|
-
__publicField(this, "audioPlayer");
|
|
1060
|
-
__publicField(this, "connection");
|
|
1061
|
-
__publicField(this, "audioResource");
|
|
1062
|
-
__publicField(this, "emittedError");
|
|
1063
|
-
__publicField(this, "isDisconnected", false);
|
|
1064
|
-
__privateAdd(this, _channel, void 0);
|
|
1065
|
-
__privateAdd(this, _volume, 100);
|
|
1066
|
-
this.id = channel.guildId;
|
|
1067
|
-
this.channel = channel;
|
|
1068
|
-
this.voices = voiceManager;
|
|
1069
|
-
this.voices.add(this.id, this);
|
|
1070
|
-
this.audioPlayer = createAudioPlayer().on(AudioPlayerStatus.Idle, (oldState) => {
|
|
1071
|
-
if (oldState.status !== AudioPlayerStatus.Idle) {
|
|
1072
|
-
delete this.audioResource;
|
|
1073
|
-
this.emit("finish");
|
|
1074
|
-
}
|
|
1075
|
-
}).on(AudioPlayerStatus.Playing, () => __privateMethod(this, _br, br_fn).call(this)).on("error", (error) => {
|
|
1076
|
-
if (this.emittedError)
|
|
1077
|
-
return;
|
|
1078
|
-
this.emittedError = true;
|
|
1079
|
-
this.emit("error", error);
|
|
1080
|
-
});
|
|
1081
|
-
this.connection.on(VoiceConnectionStatus.Disconnected, (_, newState) => {
|
|
1082
|
-
if (newState.reason === VoiceConnectionDisconnectReason.Manual) {
|
|
1083
|
-
this.leave();
|
|
1084
|
-
} else if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
|
|
1085
|
-
entersState(this.connection, VoiceConnectionStatus.Connecting, 5e3).catch(() => {
|
|
1086
|
-
if (![VoiceConnectionStatus.Ready, VoiceConnectionStatus.Connecting].includes(this.connection.state.status)) {
|
|
1087
|
-
this.leave();
|
|
1088
|
-
}
|
|
1089
|
-
});
|
|
1090
|
-
} else if (this.connection.rejoinAttempts < 5) {
|
|
1091
|
-
setTimeout(() => {
|
|
1092
|
-
this.connection.rejoin();
|
|
1093
|
-
}, (this.connection.rejoinAttempts + 1) * 5e3).unref();
|
|
1094
|
-
} else if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) {
|
|
1095
|
-
this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
|
|
1096
|
-
}
|
|
1097
|
-
}).on(VoiceConnectionStatus.Destroyed, () => {
|
|
1098
|
-
this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
|
|
1099
|
-
}).on("error", () => void 0);
|
|
1100
|
-
this.connection.subscribe(this.audioPlayer);
|
|
1101
|
-
}
|
|
1102
|
-
get channel() {
|
|
1103
|
-
return __privateGet(this, _channel);
|
|
1104
|
-
}
|
|
1105
|
-
set channel(channel) {
|
|
1106
|
-
if (!isSupportedVoiceChannel(channel)) {
|
|
1107
|
-
throw new DisTubeError("INVALID_TYPE", "BaseGuildVoiceChannel", channel, "DisTubeVoice#channel");
|
|
1108
|
-
}
|
|
1109
|
-
if (channel.guildId !== this.id)
|
|
1110
|
-
throw new DisTubeError("VOICE_DIFFERENT_GUILD");
|
|
1111
|
-
if (channel.id === __privateGet(this, _channel)?.id)
|
|
1112
|
-
return;
|
|
1113
|
-
if (!channel.joinable) {
|
|
1114
|
-
if (channel.full)
|
|
1115
|
-
throw new DisTubeError("VOICE_FULL");
|
|
1116
|
-
else
|
|
1117
|
-
throw new DisTubeError("VOICE_MISSING_PERMS");
|
|
1118
|
-
}
|
|
1119
|
-
this.connection = __privateMethod(this, _join, join_fn).call(this, channel);
|
|
1120
|
-
__privateSet(this, _channel, channel);
|
|
1121
|
-
__privateMethod(this, _br, br_fn).call(this);
|
|
1122
|
-
}
|
|
1123
|
-
async join(channel) {
|
|
1124
|
-
const TIMEOUT = 3e4;
|
|
1125
|
-
if (channel)
|
|
1126
|
-
this.channel = channel;
|
|
1127
|
-
try {
|
|
1128
|
-
await entersState(this.connection, VoiceConnectionStatus.Ready, TIMEOUT);
|
|
1129
|
-
} catch {
|
|
1130
|
-
if (this.connection.state.status === VoiceConnectionStatus.Ready)
|
|
1131
|
-
return this;
|
|
1132
|
-
if (this.connection.state.status !== VoiceConnectionStatus.Destroyed)
|
|
1133
|
-
this.connection.destroy();
|
|
1134
|
-
this.voices.remove(this.id);
|
|
1135
|
-
throw new DisTubeError("VOICE_CONNECT_FAILED", TIMEOUT / 1e3);
|
|
1136
|
-
}
|
|
1137
|
-
return this;
|
|
1138
|
-
}
|
|
1139
|
-
leave(error) {
|
|
1140
|
-
this.stop(true);
|
|
1141
|
-
if (!this.isDisconnected) {
|
|
1142
|
-
this.emit("disconnect", error);
|
|
1143
|
-
this.isDisconnected = true;
|
|
1144
|
-
}
|
|
1145
|
-
if (this.connection.state.status !== VoiceConnectionStatus.Destroyed)
|
|
1146
|
-
this.connection.destroy();
|
|
1147
|
-
this.voices.remove(this.id);
|
|
1148
|
-
}
|
|
1149
|
-
stop(force = false) {
|
|
1150
|
-
this.audioPlayer.stop(force);
|
|
1151
|
-
}
|
|
1152
|
-
play(stream) {
|
|
1153
|
-
this.emittedError = false;
|
|
1154
|
-
stream.stream.on("error", (error) => {
|
|
1155
|
-
if (this.emittedError || error.code === "ERR_STREAM_PREMATURE_CLOSE")
|
|
1156
|
-
return;
|
|
1157
|
-
this.emittedError = true;
|
|
1158
|
-
this.emit("error", error);
|
|
1159
|
-
});
|
|
1160
|
-
this.audioResource = createAudioResource(stream.stream, {
|
|
1161
|
-
inputType: stream.type,
|
|
1162
|
-
inlineVolume: true
|
|
1163
|
-
});
|
|
1164
|
-
this.volume = __privateGet(this, _volume);
|
|
1165
|
-
this.audioPlayer.play(this.audioResource);
|
|
1166
|
-
}
|
|
1167
|
-
set volume(volume) {
|
|
1168
|
-
if (typeof volume !== "number" || isNaN(volume)) {
|
|
1169
|
-
throw new DisTubeError("INVALID_TYPE", "number", volume, "volume");
|
|
1170
|
-
}
|
|
1171
|
-
if (volume < 0) {
|
|
1172
|
-
throw new DisTubeError("NUMBER_COMPARE", "Volume", "bigger or equal to", 0);
|
|
1173
|
-
}
|
|
1174
|
-
__privateSet(this, _volume, volume);
|
|
1175
|
-
this.audioResource?.volume?.setVolume(Math.pow(__privateGet(this, _volume) / 100, 0.5 / Math.log10(2)));
|
|
1176
|
-
}
|
|
1177
|
-
get volume() {
|
|
1178
|
-
return __privateGet(this, _volume);
|
|
1179
|
-
}
|
|
1180
|
-
get playbackDuration() {
|
|
1181
|
-
return (this.audioResource?.playbackDuration ?? 0) / 1e3;
|
|
1182
|
-
}
|
|
1183
|
-
pause() {
|
|
1184
|
-
this.audioPlayer.pause();
|
|
1185
|
-
}
|
|
1186
|
-
unpause() {
|
|
1187
|
-
this.audioPlayer.unpause();
|
|
1188
|
-
}
|
|
1189
|
-
get selfDeaf() {
|
|
1190
|
-
return this.connection.joinConfig.selfDeaf;
|
|
1191
|
-
}
|
|
1192
|
-
get selfMute() {
|
|
1193
|
-
return this.connection.joinConfig.selfMute;
|
|
1194
|
-
}
|
|
1195
|
-
setSelfDeaf(selfDeaf) {
|
|
1196
|
-
if (typeof selfDeaf !== "boolean") {
|
|
1197
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", selfDeaf, "selfDeaf");
|
|
1198
|
-
}
|
|
1199
|
-
return this.connection.rejoin({
|
|
1200
|
-
...this.connection.joinConfig,
|
|
1201
|
-
selfDeaf
|
|
1202
|
-
});
|
|
1203
|
-
}
|
|
1204
|
-
setSelfMute(selfMute) {
|
|
1205
|
-
if (typeof selfMute !== "boolean") {
|
|
1206
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", selfMute, "selfMute");
|
|
1207
|
-
}
|
|
1208
|
-
return this.connection.rejoin({
|
|
1209
|
-
...this.connection.joinConfig,
|
|
1210
|
-
selfMute
|
|
1211
|
-
});
|
|
1212
|
-
}
|
|
1213
|
-
get voiceState() {
|
|
1214
|
-
return this.channel?.guild?.me?.voice;
|
|
1215
|
-
}
|
|
1216
|
-
};
|
|
1217
|
-
_channel = new WeakMap();
|
|
1218
|
-
_volume = new WeakMap();
|
|
1219
|
-
_br = new WeakSet();
|
|
1220
|
-
br_fn = /* @__PURE__ */ __name(function() {
|
|
1221
|
-
if (this.audioResource?.encoder?.encoder)
|
|
1222
|
-
this.audioResource.encoder.setBitrate(this.channel.bitrate);
|
|
1223
|
-
}, "#br");
|
|
1224
|
-
_join = new WeakSet();
|
|
1225
|
-
join_fn = /* @__PURE__ */ __name(function(channel) {
|
|
1226
|
-
return joinVoiceChannel({
|
|
1227
|
-
channelId: channel.id,
|
|
1228
|
-
guildId: this.id,
|
|
1229
|
-
adapterCreator: channel.guild.voiceAdapterCreator,
|
|
1230
|
-
group: channel.client.user?.id
|
|
1231
|
-
});
|
|
1232
|
-
}, "#join");
|
|
1233
|
-
|
|
1234
|
-
// src/core/voice/DisTubeVoiceManager.ts
|
|
1235
|
-
import { VoiceConnectionStatus as VoiceConnectionStatus2, getVoiceConnection } from "@discordjs/voice";
|
|
1236
|
-
var DisTubeVoiceManager = class extends GuildIdManager {
|
|
1237
|
-
create(channel) {
|
|
1238
|
-
const existing = this.get(channel.guildId);
|
|
1239
|
-
if (existing) {
|
|
1240
|
-
existing.channel = channel;
|
|
1241
|
-
return existing;
|
|
1088
|
+
if (queue.autoplay) {
|
|
1089
|
+
try {
|
|
1090
|
+
await queue.addRelatedSong();
|
|
1091
|
+
} catch {
|
|
1092
|
+
this.emit("noRelated", queue);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
if (queue.songs.length <= 1) {
|
|
1096
|
+
if (this.options.leaveOnFinish)
|
|
1097
|
+
queue.voice.leave();
|
|
1098
|
+
if (!queue.autoplay)
|
|
1099
|
+
this.emit("finish", queue);
|
|
1100
|
+
queue.remove();
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1242
1103
|
}
|
|
1243
|
-
|
|
1104
|
+
const emitPlaySong = __privateMethod(this, _emitPlaySong, emitPlaySong_fn).call(this, queue);
|
|
1105
|
+
if (!queue._prev && (queue.repeatMode !== 1 /* SONG */ || queue._next)) {
|
|
1106
|
+
const prev = queue.songs.shift();
|
|
1107
|
+
delete prev.formats;
|
|
1108
|
+
delete prev.streamURL;
|
|
1109
|
+
if (this.options.savePreviousSongs)
|
|
1110
|
+
queue.previousSongs.push(prev);
|
|
1111
|
+
else
|
|
1112
|
+
queue.previousSongs.push({ id: prev.id });
|
|
1113
|
+
}
|
|
1114
|
+
queue._next = queue._prev = false;
|
|
1115
|
+
queue.beginTime = 0;
|
|
1116
|
+
const err = await this.playSong(queue);
|
|
1117
|
+
if (!err && emitPlaySong)
|
|
1118
|
+
this.emit("playSong", queue, queue.songs[0]);
|
|
1119
|
+
} finally {
|
|
1120
|
+
queue._taskQueue.resolve();
|
|
1244
1121
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1122
|
+
}, "#handleSongFinish");
|
|
1123
|
+
_handlePlayingError = new WeakSet();
|
|
1124
|
+
handlePlayingError_fn = /* @__PURE__ */ __name(function(queue, error) {
|
|
1125
|
+
const song = queue.songs.shift();
|
|
1126
|
+
try {
|
|
1127
|
+
error.name = "PlayingError";
|
|
1128
|
+
error.message = `${error.message}
|
|
1129
|
+
Id: ${song.id}
|
|
1130
|
+
Name: ${song.name}`;
|
|
1131
|
+
} catch {
|
|
1250
1132
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1133
|
+
this.emitError(error, queue.textChannel);
|
|
1134
|
+
if (queue.songs.length > 0) {
|
|
1135
|
+
this.playSong(queue).then((e) => {
|
|
1136
|
+
if (!e)
|
|
1137
|
+
this.emit("playSong", queue, queue.songs[0]);
|
|
1138
|
+
});
|
|
1139
|
+
} else {
|
|
1140
|
+
queue.stop();
|
|
1261
1141
|
}
|
|
1262
|
-
};
|
|
1142
|
+
}, "#handlePlayingError");
|
|
1143
|
+
_emitPlaySong = new WeakSet();
|
|
1144
|
+
emitPlaySong_fn = /* @__PURE__ */ __name(function(queue) {
|
|
1145
|
+
return !this.options.emitNewSongOnly || queue.repeatMode === 1 /* SONG */ && queue._next || queue.repeatMode !== 1 /* SONG */ && queue.songs[0]?.id !== queue.songs[1]?.id;
|
|
1146
|
+
}, "#emitPlaySong");
|
|
1263
1147
|
|
|
1264
1148
|
// src/core/DisTubeHandler.ts
|
|
1265
|
-
import ytdl from "@distube/ytdl-core";
|
|
1266
1149
|
import ytpl from "@distube/ytpl";
|
|
1150
|
+
import ytdl from "@distube/ytdl-core";
|
|
1267
1151
|
var DisTubeHandler = class extends DisTubeBase {
|
|
1268
1152
|
constructor(distube) {
|
|
1269
1153
|
super(distube);
|
|
@@ -1327,11 +1211,10 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1327
1211
|
song.member = options.member;
|
|
1328
1212
|
return song;
|
|
1329
1213
|
}
|
|
1330
|
-
if (song instanceof
|
|
1331
|
-
|
|
1332
|
-
|
|
1214
|
+
if (song instanceof SearchResultVideo)
|
|
1215
|
+
return new Song(song, options);
|
|
1216
|
+
if (song instanceof SearchResultPlaylist)
|
|
1333
1217
|
return this.resolvePlaylist(song.url, options);
|
|
1334
|
-
}
|
|
1335
1218
|
if (isObject(song))
|
|
1336
1219
|
return new Song(song, options);
|
|
1337
1220
|
if (ytpl.validateID(song))
|
|
@@ -1356,14 +1239,19 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1356
1239
|
playlist.member = member;
|
|
1357
1240
|
return playlist;
|
|
1358
1241
|
}
|
|
1359
|
-
let solvablePlaylist;
|
|
1360
1242
|
if (typeof playlist === "string") {
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1243
|
+
const info = await ytpl(playlist, { limit: Infinity });
|
|
1244
|
+
const songs = info.items.filter((v) => !v.thumbnail.includes("no_thumbnail")).map((v) => new Song(v, { member, metadata }));
|
|
1245
|
+
return new Playlist({
|
|
1246
|
+
source,
|
|
1247
|
+
songs,
|
|
1248
|
+
member,
|
|
1249
|
+
name: info.title,
|
|
1250
|
+
url: info.url,
|
|
1251
|
+
thumbnail: songs[0].thumbnail
|
|
1252
|
+
}, { metadata });
|
|
1253
|
+
}
|
|
1254
|
+
return new Playlist(playlist, { member, properties: { source }, metadata });
|
|
1367
1255
|
}
|
|
1368
1256
|
async searchSong(message, query) {
|
|
1369
1257
|
if (!isMessageInstance(message))
|
|
@@ -1495,6 +1383,187 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1495
1383
|
}
|
|
1496
1384
|
}
|
|
1497
1385
|
};
|
|
1386
|
+
__name(DisTubeHandler, "DisTubeHandler");
|
|
1387
|
+
|
|
1388
|
+
// src/core/DisTubeOptions.ts
|
|
1389
|
+
var _validateOptions, validateOptions_fn;
|
|
1390
|
+
var Options = class {
|
|
1391
|
+
constructor(options) {
|
|
1392
|
+
__privateAdd(this, _validateOptions);
|
|
1393
|
+
__publicField(this, "plugins");
|
|
1394
|
+
__publicField(this, "emitNewSongOnly");
|
|
1395
|
+
__publicField(this, "leaveOnFinish");
|
|
1396
|
+
__publicField(this, "leaveOnStop");
|
|
1397
|
+
__publicField(this, "leaveOnEmpty");
|
|
1398
|
+
__publicField(this, "emptyCooldown");
|
|
1399
|
+
__publicField(this, "savePreviousSongs");
|
|
1400
|
+
__publicField(this, "searchSongs");
|
|
1401
|
+
__publicField(this, "searchCooldown");
|
|
1402
|
+
__publicField(this, "youtubeCookie");
|
|
1403
|
+
__publicField(this, "youtubeIdentityToken");
|
|
1404
|
+
__publicField(this, "customFilters");
|
|
1405
|
+
__publicField(this, "ytdlOptions");
|
|
1406
|
+
__publicField(this, "nsfw");
|
|
1407
|
+
__publicField(this, "emitAddSongWhenCreatingQueue");
|
|
1408
|
+
__publicField(this, "emitAddListWhenCreatingQueue");
|
|
1409
|
+
__publicField(this, "joinNewVoiceChannel");
|
|
1410
|
+
__publicField(this, "streamType");
|
|
1411
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
1412
|
+
throw new DisTubeError("INVALID_TYPE", "object", options, "DisTubeOptions");
|
|
1413
|
+
}
|
|
1414
|
+
const opts = { ...defaultOptions, ...options };
|
|
1415
|
+
this.plugins = opts.plugins;
|
|
1416
|
+
this.emitNewSongOnly = opts.emitNewSongOnly;
|
|
1417
|
+
this.leaveOnEmpty = opts.leaveOnEmpty;
|
|
1418
|
+
this.leaveOnFinish = opts.leaveOnFinish;
|
|
1419
|
+
this.leaveOnStop = opts.leaveOnStop;
|
|
1420
|
+
this.savePreviousSongs = opts.savePreviousSongs;
|
|
1421
|
+
this.searchSongs = opts.searchSongs;
|
|
1422
|
+
this.youtubeCookie = opts.youtubeCookie;
|
|
1423
|
+
this.youtubeIdentityToken = opts.youtubeIdentityToken;
|
|
1424
|
+
this.customFilters = opts.customFilters;
|
|
1425
|
+
this.ytdlOptions = opts.ytdlOptions;
|
|
1426
|
+
this.searchCooldown = opts.searchCooldown;
|
|
1427
|
+
this.emptyCooldown = opts.emptyCooldown;
|
|
1428
|
+
this.nsfw = opts.nsfw;
|
|
1429
|
+
this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;
|
|
1430
|
+
this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;
|
|
1431
|
+
this.joinNewVoiceChannel = opts.joinNewVoiceChannel;
|
|
1432
|
+
this.streamType = opts.streamType;
|
|
1433
|
+
checkInvalidKey(opts, this, "DisTubeOptions");
|
|
1434
|
+
__privateMethod(this, _validateOptions, validateOptions_fn).call(this);
|
|
1435
|
+
}
|
|
1436
|
+
};
|
|
1437
|
+
__name(Options, "Options");
|
|
1438
|
+
_validateOptions = new WeakSet();
|
|
1439
|
+
validateOptions_fn = /* @__PURE__ */ __name(function(options = this) {
|
|
1440
|
+
if (typeof options.emitNewSongOnly !== "boolean") {
|
|
1441
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitNewSongOnly, "DisTubeOptions.emitNewSongOnly");
|
|
1442
|
+
}
|
|
1443
|
+
if (typeof options.leaveOnEmpty !== "boolean") {
|
|
1444
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnEmpty, "DisTubeOptions.leaveOnEmpty");
|
|
1445
|
+
}
|
|
1446
|
+
if (typeof options.leaveOnFinish !== "boolean") {
|
|
1447
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnFinish, "DisTubeOptions.leaveOnFinish");
|
|
1448
|
+
}
|
|
1449
|
+
if (typeof options.leaveOnStop !== "boolean") {
|
|
1450
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnStop, "DisTubeOptions.leaveOnStop");
|
|
1451
|
+
}
|
|
1452
|
+
if (typeof options.savePreviousSongs !== "boolean") {
|
|
1453
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.savePreviousSongs, "DisTubeOptions.savePreviousSongs");
|
|
1454
|
+
}
|
|
1455
|
+
if (typeof options.joinNewVoiceChannel !== "boolean") {
|
|
1456
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.joinNewVoiceChannel, "DisTubeOptions.joinNewVoiceChannel");
|
|
1457
|
+
}
|
|
1458
|
+
if (typeof options.youtubeCookie !== "undefined" && typeof options.youtubeCookie !== "string") {
|
|
1459
|
+
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeCookie, "DisTubeOptions.youtubeCookie");
|
|
1460
|
+
}
|
|
1461
|
+
if (typeof options.youtubeIdentityToken !== "undefined" && typeof options.youtubeIdentityToken !== "string") {
|
|
1462
|
+
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeIdentityToken, "DisTubeOptions.youtubeIdentityToken");
|
|
1463
|
+
}
|
|
1464
|
+
if (typeof options.customFilters !== "undefined" && typeof options.customFilters !== "object" || Array.isArray(options.customFilters)) {
|
|
1465
|
+
throw new DisTubeError("INVALID_TYPE", "object", options.customFilters, "DisTubeOptions.customFilters");
|
|
1466
|
+
}
|
|
1467
|
+
if (typeof options.ytdlOptions !== "object" || Array.isArray(options.ytdlOptions)) {
|
|
1468
|
+
throw new DisTubeError("INVALID_TYPE", "object", options.ytdlOptions, "DisTubeOptions.ytdlOptions");
|
|
1469
|
+
}
|
|
1470
|
+
if (typeof options.searchCooldown !== "number" || isNaN(options.searchCooldown)) {
|
|
1471
|
+
throw new DisTubeError("INVALID_TYPE", "number", options.searchCooldown, "DisTubeOptions.searchCooldown");
|
|
1472
|
+
}
|
|
1473
|
+
if (typeof options.emptyCooldown !== "number" || isNaN(options.emptyCooldown)) {
|
|
1474
|
+
throw new DisTubeError("INVALID_TYPE", "number", options.emptyCooldown, "DisTubeOptions.emptyCooldown");
|
|
1475
|
+
}
|
|
1476
|
+
if (typeof options.searchSongs !== "number" || isNaN(options.searchSongs)) {
|
|
1477
|
+
throw new DisTubeError("INVALID_TYPE", "number", options.searchSongs, "DisTubeOptions.searchSongs");
|
|
1478
|
+
}
|
|
1479
|
+
if (!Array.isArray(options.plugins)) {
|
|
1480
|
+
throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", options.plugins, "DisTubeOptions.plugins");
|
|
1481
|
+
}
|
|
1482
|
+
if (typeof options.nsfw !== "boolean") {
|
|
1483
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.nsfw, "DisTubeOptions.nsfw");
|
|
1484
|
+
}
|
|
1485
|
+
if (typeof options.emitAddSongWhenCreatingQueue !== "boolean") {
|
|
1486
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddSongWhenCreatingQueue, "DisTubeOptions.emitAddSongWhenCreatingQueue");
|
|
1487
|
+
}
|
|
1488
|
+
if (typeof options.emitAddListWhenCreatingQueue !== "boolean") {
|
|
1489
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddListWhenCreatingQueue, "DisTubeOptions.emitAddListWhenCreatingQueue");
|
|
1490
|
+
}
|
|
1491
|
+
if (typeof options.streamType !== "number" || isNaN(options.streamType) || !StreamType[options.streamType]) {
|
|
1492
|
+
throw new DisTubeError("INVALID_TYPE", "StreamType", options.streamType, "DisTubeOptions.streamType");
|
|
1493
|
+
}
|
|
1494
|
+
}, "#validateOptions");
|
|
1495
|
+
|
|
1496
|
+
// src/core/DisTubeStream.ts
|
|
1497
|
+
import { FFmpeg } from "prism-media";
|
|
1498
|
+
import { StreamType as DiscordVoiceStreamType } from "@discordjs/voice";
|
|
1499
|
+
var chooseBestVideoFormat = /* @__PURE__ */ __name((formats, isLive = false) => {
|
|
1500
|
+
let filter = /* @__PURE__ */ __name((format) => format.hasAudio, "filter");
|
|
1501
|
+
if (isLive)
|
|
1502
|
+
filter = /* @__PURE__ */ __name((format) => format.hasAudio && format.isHLS, "filter");
|
|
1503
|
+
formats = formats.filter(filter).sort((a, b) => Number(b.audioBitrate) - Number(a.audioBitrate) || Number(a.bitrate) - Number(b.bitrate));
|
|
1504
|
+
return formats.find((format) => !format.hasVideo) || formats.sort((a, b) => Number(a.bitrate) - Number(b.bitrate))[0];
|
|
1505
|
+
}, "chooseBestVideoFormat");
|
|
1506
|
+
var DisTubeStream = class {
|
|
1507
|
+
constructor(url, options) {
|
|
1508
|
+
__publicField(this, "type");
|
|
1509
|
+
__publicField(this, "stream");
|
|
1510
|
+
__publicField(this, "url");
|
|
1511
|
+
this.url = url;
|
|
1512
|
+
this.type = !options.type ? DiscordVoiceStreamType.OggOpus : DiscordVoiceStreamType.Raw;
|
|
1513
|
+
const args = [
|
|
1514
|
+
"-reconnect",
|
|
1515
|
+
"1",
|
|
1516
|
+
"-reconnect_streamed",
|
|
1517
|
+
"1",
|
|
1518
|
+
"-reconnect_delay_max",
|
|
1519
|
+
"5",
|
|
1520
|
+
"-i",
|
|
1521
|
+
url,
|
|
1522
|
+
"-analyzeduration",
|
|
1523
|
+
"0",
|
|
1524
|
+
"-loglevel",
|
|
1525
|
+
"0",
|
|
1526
|
+
"-ar",
|
|
1527
|
+
"48000",
|
|
1528
|
+
"-ac",
|
|
1529
|
+
"2",
|
|
1530
|
+
"-f"
|
|
1531
|
+
];
|
|
1532
|
+
if (!options.type) {
|
|
1533
|
+
args.push("opus", "-acodec", "libopus");
|
|
1534
|
+
} else {
|
|
1535
|
+
args.push("s16le");
|
|
1536
|
+
}
|
|
1537
|
+
if (typeof options.seek === "number" && options.seek > 0) {
|
|
1538
|
+
args.unshift("-ss", options.seek.toString());
|
|
1539
|
+
}
|
|
1540
|
+
if (Array.isArray(options.ffmpegArgs)) {
|
|
1541
|
+
args.push(...options.ffmpegArgs);
|
|
1542
|
+
}
|
|
1543
|
+
this.stream = new FFmpeg({ args, shell: false });
|
|
1544
|
+
}
|
|
1545
|
+
static YouTube(formats, options = {}) {
|
|
1546
|
+
if (!formats || !formats.length)
|
|
1547
|
+
throw new DisTubeError("UNAVAILABLE_VIDEO");
|
|
1548
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
1549
|
+
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
1550
|
+
}
|
|
1551
|
+
const bestFormat = chooseBestVideoFormat(formats, options.isLive);
|
|
1552
|
+
if (!bestFormat)
|
|
1553
|
+
throw new DisTubeError("UNPLAYABLE_FORMATS");
|
|
1554
|
+
return new DisTubeStream(bestFormat.url, options);
|
|
1555
|
+
}
|
|
1556
|
+
static DirectLink(url, options = {}) {
|
|
1557
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
1558
|
+
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
1559
|
+
}
|
|
1560
|
+
if (typeof url !== "string" || !isURL(url)) {
|
|
1561
|
+
throw new DisTubeError("INVALID_TYPE", "an URL", url);
|
|
1562
|
+
}
|
|
1563
|
+
return new DisTubeStream(url, options);
|
|
1564
|
+
}
|
|
1565
|
+
};
|
|
1566
|
+
__name(DisTubeStream, "DisTubeStream");
|
|
1498
1567
|
|
|
1499
1568
|
// src/struct/Queue.ts
|
|
1500
1569
|
var _filters;
|
|
@@ -1516,12 +1585,8 @@ var Queue = class extends DisTubeBase {
|
|
|
1516
1585
|
__publicField(this, "beginTime");
|
|
1517
1586
|
__publicField(this, "textChannel");
|
|
1518
1587
|
__publicField(this, "_emptyTimeout");
|
|
1519
|
-
__publicField(this, "clientMember");
|
|
1520
1588
|
__publicField(this, "_taskQueue");
|
|
1521
1589
|
__publicField(this, "_listeners");
|
|
1522
|
-
this.clientMember = voice.channel.guild?.me ?? (() => {
|
|
1523
|
-
throw new DisTubeError("INVALID_TYPE", "GuildMember", null, "<VoiceChannel>.guild.me");
|
|
1524
|
-
})();
|
|
1525
1590
|
this.voice = voice;
|
|
1526
1591
|
this.id = voice.id;
|
|
1527
1592
|
this.volume = 50;
|
|
@@ -1541,6 +1606,9 @@ var Queue = class extends DisTubeBase {
|
|
|
1541
1606
|
this._taskQueue = new TaskQueue();
|
|
1542
1607
|
this._listeners = void 0;
|
|
1543
1608
|
}
|
|
1609
|
+
get clientMember() {
|
|
1610
|
+
return this.voice.channel.guild.members.me ?? void 0;
|
|
1611
|
+
}
|
|
1544
1612
|
get filters() {
|
|
1545
1613
|
return __privateGet(this, _filters);
|
|
1546
1614
|
}
|
|
@@ -1557,7 +1625,7 @@ var Queue = class extends DisTubeBase {
|
|
|
1557
1625
|
return formatDuration(this.currentTime);
|
|
1558
1626
|
}
|
|
1559
1627
|
get voiceChannel() {
|
|
1560
|
-
return this.clientMember
|
|
1628
|
+
return this.clientMember?.voice?.channel ?? null;
|
|
1561
1629
|
}
|
|
1562
1630
|
get volume() {
|
|
1563
1631
|
return this.voice.volume;
|
|
@@ -1755,6 +1823,7 @@ var Queue = class extends DisTubeBase {
|
|
|
1755
1823
|
return this.autoplay;
|
|
1756
1824
|
}
|
|
1757
1825
|
};
|
|
1826
|
+
__name(Queue, "Queue");
|
|
1758
1827
|
_filters = new WeakMap();
|
|
1759
1828
|
|
|
1760
1829
|
// src/struct/Plugin.ts
|
|
@@ -1796,6 +1865,7 @@ var Plugin = class {
|
|
|
1796
1865
|
return [];
|
|
1797
1866
|
}
|
|
1798
1867
|
};
|
|
1868
|
+
__name(Plugin, "Plugin");
|
|
1799
1869
|
|
|
1800
1870
|
// src/struct/CustomPlugin.ts
|
|
1801
1871
|
var CustomPlugin = class extends Plugin {
|
|
@@ -1804,6 +1874,7 @@ var CustomPlugin = class extends Plugin {
|
|
|
1804
1874
|
__publicField(this, "type", "custom" /* CUSTOM */);
|
|
1805
1875
|
}
|
|
1806
1876
|
};
|
|
1877
|
+
__name(CustomPlugin, "CustomPlugin");
|
|
1807
1878
|
|
|
1808
1879
|
// src/struct/ExtractorPlugin.ts
|
|
1809
1880
|
var ExtractorPlugin = class extends Plugin {
|
|
@@ -1812,6 +1883,7 @@ var ExtractorPlugin = class extends Plugin {
|
|
|
1812
1883
|
__publicField(this, "type", "extractor" /* EXTRACTOR */);
|
|
1813
1884
|
}
|
|
1814
1885
|
};
|
|
1886
|
+
__name(ExtractorPlugin, "ExtractorPlugin");
|
|
1815
1887
|
|
|
1816
1888
|
// src/util.ts
|
|
1817
1889
|
import { URL } from "url";
|
|
@@ -1829,6 +1901,7 @@ function formatDuration(sec) {
|
|
|
1829
1901
|
return `${formatInt(minutes)}:${formatInt(seconds)}`;
|
|
1830
1902
|
return `00:${formatInt(seconds)}`;
|
|
1831
1903
|
}
|
|
1904
|
+
__name(formatDuration, "formatDuration");
|
|
1832
1905
|
function toSecond(input) {
|
|
1833
1906
|
if (!input)
|
|
1834
1907
|
return 0;
|
|
@@ -1847,11 +1920,13 @@ function toSecond(input) {
|
|
|
1847
1920
|
return Number(input.replace(/[^\d.]+/g, "")) || 0;
|
|
1848
1921
|
}
|
|
1849
1922
|
}
|
|
1923
|
+
__name(toSecond, "toSecond");
|
|
1850
1924
|
function parseNumber(input) {
|
|
1851
1925
|
if (typeof input === "string")
|
|
1852
1926
|
return Number(input.replace(/[^\d.]+/g, "")) || 0;
|
|
1853
1927
|
return Number(input) || 0;
|
|
1854
1928
|
}
|
|
1929
|
+
__name(parseNumber, "parseNumber");
|
|
1855
1930
|
function isURL(input) {
|
|
1856
1931
|
if (typeof input !== "string" || input.includes(" "))
|
|
1857
1932
|
return false;
|
|
@@ -1864,18 +1939,25 @@ function isURL(input) {
|
|
|
1864
1939
|
}
|
|
1865
1940
|
return true;
|
|
1866
1941
|
}
|
|
1942
|
+
__name(isURL, "isURL");
|
|
1867
1943
|
function checkIntents(options) {
|
|
1868
1944
|
const intents = new IntentsBitField(options.intents);
|
|
1869
1945
|
if (!intents.has(GatewayIntentBits.GuildVoiceStates))
|
|
1870
1946
|
throw new DisTubeError("MISSING_INTENTS", "GuildVoiceStates");
|
|
1871
1947
|
}
|
|
1948
|
+
__name(checkIntents, "checkIntents");
|
|
1872
1949
|
function isVoiceChannelEmpty(voiceState) {
|
|
1873
|
-
const
|
|
1950
|
+
const guild = voiceState.guild;
|
|
1951
|
+
const clientId = voiceState.client.user?.id;
|
|
1952
|
+
if (!guild || !clientId)
|
|
1953
|
+
return false;
|
|
1954
|
+
const voiceChannel = guild.members.me?.voice?.channel;
|
|
1874
1955
|
if (!voiceChannel)
|
|
1875
1956
|
return false;
|
|
1876
1957
|
const members = voiceChannel.members.filter((m) => !m.user.bot);
|
|
1877
1958
|
return !members.size;
|
|
1878
1959
|
}
|
|
1960
|
+
__name(isVoiceChannelEmpty, "isVoiceChannelEmpty");
|
|
1879
1961
|
function isSnowflake(id) {
|
|
1880
1962
|
try {
|
|
1881
1963
|
return SnowflakeUtil.deconstruct(id).timestamp > SnowflakeUtil.epoch;
|
|
@@ -1883,21 +1965,27 @@ function isSnowflake(id) {
|
|
|
1883
1965
|
return false;
|
|
1884
1966
|
}
|
|
1885
1967
|
}
|
|
1968
|
+
__name(isSnowflake, "isSnowflake");
|
|
1886
1969
|
function isMemberInstance(member) {
|
|
1887
1970
|
return !!member && isSnowflake(member.id) && isSnowflake(member.guild?.id) && isSnowflake(member.user?.id) && member.id === member.user.id;
|
|
1888
1971
|
}
|
|
1972
|
+
__name(isMemberInstance, "isMemberInstance");
|
|
1889
1973
|
function isTextChannelInstance(channel) {
|
|
1890
|
-
return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && typeof channel.name === "string" && Constants.TextBasedChannelTypes.includes(channel.type);
|
|
1974
|
+
return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && typeof channel.name === "string" && Constants.TextBasedChannelTypes.includes(channel.type) && typeof channel.nsfw === "boolean" && typeof channel.messages?.cache === "object" && typeof channel.send === "function";
|
|
1891
1975
|
}
|
|
1976
|
+
__name(isTextChannelInstance, "isTextChannelInstance");
|
|
1892
1977
|
function isMessageInstance(message) {
|
|
1893
1978
|
return !!message && isSnowflake(message.id) && isSnowflake(message.guildId) && isMemberInstance(message.member) && isTextChannelInstance(message.channel) && Constants.NonSystemMessageTypes.includes(message.type) && message.member.id === message.author?.id;
|
|
1894
1979
|
}
|
|
1980
|
+
__name(isMessageInstance, "isMessageInstance");
|
|
1895
1981
|
function isSupportedVoiceChannel(channel) {
|
|
1896
1982
|
return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && Constants.VoiceBasedChannelTypes.includes(channel.type);
|
|
1897
1983
|
}
|
|
1984
|
+
__name(isSupportedVoiceChannel, "isSupportedVoiceChannel");
|
|
1898
1985
|
function isGuildInstance(guild) {
|
|
1899
1986
|
return !!guild && isSnowflake(guild.id) && isSnowflake(guild.ownerId) && typeof guild.name === "string";
|
|
1900
1987
|
}
|
|
1988
|
+
__name(isGuildInstance, "isGuildInstance");
|
|
1901
1989
|
function resolveGuildId(resolvable) {
|
|
1902
1990
|
let guildId;
|
|
1903
1991
|
if (typeof resolvable === "string") {
|
|
@@ -1915,9 +2003,11 @@ function resolveGuildId(resolvable) {
|
|
|
1915
2003
|
throw new DisTubeError("INVALID_TYPE", "GuildIdResolvable", resolvable);
|
|
1916
2004
|
return guildId;
|
|
1917
2005
|
}
|
|
2006
|
+
__name(resolveGuildId, "resolveGuildId");
|
|
1918
2007
|
function isClientInstance(client) {
|
|
1919
2008
|
return !!client && typeof client.login === "function";
|
|
1920
2009
|
}
|
|
2010
|
+
__name(isClientInstance, "isClientInstance");
|
|
1921
2011
|
function checkInvalidKey(target, source, sourceName) {
|
|
1922
2012
|
if (!isObject(target))
|
|
1923
2013
|
throw new DisTubeError("INVALID_TYPE", "object", target, sourceName);
|
|
@@ -1926,38 +2016,15 @@ function checkInvalidKey(target, source, sourceName) {
|
|
|
1926
2016
|
if (invalidKey)
|
|
1927
2017
|
throw new DisTubeError("INVALID_KEY", sourceName, invalidKey);
|
|
1928
2018
|
}
|
|
1929
|
-
|
|
1930
|
-
let cleanup = /* @__PURE__ */ __name(() => {
|
|
1931
|
-
}, "cleanup");
|
|
1932
|
-
try {
|
|
1933
|
-
await new Promise((resolve, reject) => {
|
|
1934
|
-
const timeout = setTimeout(() => reject(new Error(`Didn't trigger ${status} within ${maxTime}ms`)), maxTime);
|
|
1935
|
-
target.once(status, resolve);
|
|
1936
|
-
target.once("error", reject);
|
|
1937
|
-
cleanup = /* @__PURE__ */ __name(() => {
|
|
1938
|
-
clearTimeout(timeout);
|
|
1939
|
-
target.off(status, resolve);
|
|
1940
|
-
target.off("error", reject);
|
|
1941
|
-
}, "cleanup");
|
|
1942
|
-
if (target?.state?.status === status)
|
|
1943
|
-
resolve(0);
|
|
1944
|
-
});
|
|
1945
|
-
return target;
|
|
1946
|
-
} finally {
|
|
1947
|
-
cleanup();
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
async function entersState(target, status, maxTime) {
|
|
1951
|
-
if (target.state.status === status)
|
|
1952
|
-
return target;
|
|
1953
|
-
return waitEvent(target, status, maxTime);
|
|
1954
|
-
}
|
|
2019
|
+
__name(checkInvalidKey, "checkInvalidKey");
|
|
1955
2020
|
function isObject(obj) {
|
|
1956
2021
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
1957
2022
|
}
|
|
2023
|
+
__name(isObject, "isObject");
|
|
1958
2024
|
function isRecord(obj) {
|
|
1959
2025
|
return isObject(obj);
|
|
1960
2026
|
}
|
|
2027
|
+
__name(isRecord, "isRecord");
|
|
1961
2028
|
|
|
1962
2029
|
// src/plugin/http.ts
|
|
1963
2030
|
import http from "http";
|
|
@@ -1969,6 +2036,7 @@ var HTTPPlugin = class extends ExtractorPlugin {
|
|
|
1969
2036
|
return resolveHttpSong(url, { ...options, source: "http" });
|
|
1970
2037
|
}
|
|
1971
2038
|
};
|
|
2039
|
+
__name(HTTPPlugin, "HTTPPlugin");
|
|
1972
2040
|
|
|
1973
2041
|
// src/plugin/https.ts
|
|
1974
2042
|
import https from "https";
|
|
@@ -2003,6 +2071,7 @@ var HTTPSPlugin = class extends ExtractorPlugin {
|
|
|
2003
2071
|
return resolveHttpSong(url, { ...options, source: "https" });
|
|
2004
2072
|
}
|
|
2005
2073
|
};
|
|
2074
|
+
__name(HTTPSPlugin, "HTTPSPlugin");
|
|
2006
2075
|
|
|
2007
2076
|
// src/DisTube.ts
|
|
2008
2077
|
import ytsr from "@distube/ytsr";
|
|
@@ -2047,7 +2116,7 @@ var DisTube = class extends TypedEmitter2 {
|
|
|
2047
2116
|
if (!isObject(options))
|
|
2048
2117
|
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
2049
2118
|
const { textChannel, member, skip, message, metadata } = {
|
|
2050
|
-
member: voiceChannel.guild.me ?? void 0,
|
|
2119
|
+
member: voiceChannel.guild.members.me ?? void 0,
|
|
2051
2120
|
textChannel: options?.message?.channel,
|
|
2052
2121
|
skip: false,
|
|
2053
2122
|
...options
|
|
@@ -2095,12 +2164,12 @@ var DisTube = class extends TypedEmitter2 {
|
|
|
2095
2164
|
if (!(e instanceof DisTubeError)) {
|
|
2096
2165
|
try {
|
|
2097
2166
|
e.name = "PlayError";
|
|
2098
|
-
e.message = `${song
|
|
2167
|
+
e.message = `${typeof song === "string" ? song : song.url}
|
|
2099
2168
|
${e.message}`;
|
|
2100
2169
|
} catch {
|
|
2101
2170
|
}
|
|
2102
2171
|
}
|
|
2103
|
-
|
|
2172
|
+
throw e;
|
|
2104
2173
|
} finally {
|
|
2105
2174
|
if (queuing)
|
|
2106
2175
|
queue?._taskQueue.resolve();
|
|
@@ -2112,7 +2181,7 @@ ${e.message}`;
|
|
|
2112
2181
|
throw new DisTubeError("INVALID_TYPE", "Array", songs, "songs");
|
|
2113
2182
|
if (!songs.length)
|
|
2114
2183
|
throw new DisTubeError("EMPTY_ARRAY", "songs");
|
|
2115
|
-
const filteredSongs = songs.filter((song) => song instanceof Song || song
|
|
2184
|
+
const filteredSongs = songs.filter((song) => song instanceof Song || isURL(song) || typeof song !== "string" && song.type === "video" /* VIDEO */);
|
|
2116
2185
|
if (!filteredSongs.length)
|
|
2117
2186
|
throw new DisTubeError("NO_VALID_SONG");
|
|
2118
2187
|
if (member && !isMemberInstance(member)) {
|
|
@@ -2134,7 +2203,7 @@ ${e.message}`;
|
|
|
2134
2203
|
return new Playlist(resolvedSongs, { member, properties, metadata });
|
|
2135
2204
|
}
|
|
2136
2205
|
async search(string, options = {}) {
|
|
2137
|
-
const opts = { type: "video"
|
|
2206
|
+
const opts = { type: "video" /* VIDEO */, limit: 10, safeSearch: false, ...options };
|
|
2138
2207
|
if (typeof opts.type !== "string" || !["video", "playlist"].includes(opts.type)) {
|
|
2139
2208
|
throw new DisTubeError("INVALID_TYPE", ["video", "playlist"], opts.type, "options.type");
|
|
2140
2209
|
}
|
|
@@ -2147,7 +2216,11 @@ ${e.message}`;
|
|
|
2147
2216
|
}
|
|
2148
2217
|
try {
|
|
2149
2218
|
const search = await ytsr(string, opts);
|
|
2150
|
-
const results = search.items.map((i) =>
|
|
2219
|
+
const results = search.items.map((i) => {
|
|
2220
|
+
if (i.type === "video")
|
|
2221
|
+
return new SearchResultVideo(i);
|
|
2222
|
+
return new SearchResultPlaylist(i);
|
|
2223
|
+
});
|
|
2151
2224
|
if (results.length === 0)
|
|
2152
2225
|
throw new DisTubeError("NO_RESULT");
|
|
2153
2226
|
return results;
|
|
@@ -2244,6 +2317,7 @@ ${e.message}`;
|
|
|
2244
2317
|
}
|
|
2245
2318
|
}
|
|
2246
2319
|
};
|
|
2320
|
+
__name(DisTube, "DisTube");
|
|
2247
2321
|
export {
|
|
2248
2322
|
BaseManager,
|
|
2249
2323
|
CustomPlugin,
|
|
@@ -2266,9 +2340,11 @@ export {
|
|
|
2266
2340
|
Queue,
|
|
2267
2341
|
QueueManager,
|
|
2268
2342
|
RepeatMode,
|
|
2269
|
-
|
|
2343
|
+
SearchResultPlaylist,
|
|
2270
2344
|
SearchResultType,
|
|
2345
|
+
SearchResultVideo,
|
|
2271
2346
|
Song,
|
|
2347
|
+
StreamType,
|
|
2272
2348
|
TaskQueue,
|
|
2273
2349
|
checkIntents,
|
|
2274
2350
|
checkInvalidKey,
|
|
@@ -2276,7 +2352,6 @@ export {
|
|
|
2276
2352
|
DisTube as default,
|
|
2277
2353
|
defaultFilters,
|
|
2278
2354
|
defaultOptions,
|
|
2279
|
-
entersState,
|
|
2280
2355
|
formatDuration,
|
|
2281
2356
|
getResponseHeaders,
|
|
2282
2357
|
isClientInstance,
|