distube 4.0.0-dev.5 → 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 +110 -91
- package/dist/index.js +643 -644
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +646 -646
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -21
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",
|
|
@@ -110,41 +110,41 @@ var require_package = __commonJS({
|
|
|
110
110
|
dependencies: {
|
|
111
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
116
|
tslib: "^2.4.0"
|
|
117
117
|
},
|
|
118
118
|
devDependencies: {
|
|
119
|
-
"@babel/core": "^7.18.
|
|
120
|
-
"@babel/plugin-proposal-class-properties": "^7.
|
|
121
|
-
"@babel/plugin-proposal-object-rest-spread": "^7.18.
|
|
122
|
-
"@babel/preset-env": "^7.18.
|
|
123
|
-
"@babel/preset-typescript": "^7.
|
|
124
|
-
"@commitlint/cli": "^17.0.
|
|
125
|
-
"@commitlint/config-conventional": "^17.0.
|
|
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": "^28.1.
|
|
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": "^39.3.
|
|
138
|
+
"eslint-plugin-jsdoc": "^39.3.3",
|
|
139
139
|
husky: "^8.0.1",
|
|
140
|
-
jest: "^28.1.
|
|
140
|
+
jest: "^28.1.3",
|
|
141
141
|
"jsdoc-babel": "^0.5.0",
|
|
142
142
|
"nano-staged": "^0.8.0",
|
|
143
|
-
"npm-check-updates": "^
|
|
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": "*",
|
|
@@ -236,7 +236,7 @@ var defaultOptions = {
|
|
|
236
236
|
// src/struct/DisTubeError.ts
|
|
237
237
|
import { inspect } from "node:util";
|
|
238
238
|
var ERROR_MESSAGES = {
|
|
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)}`,
|
|
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})`,
|
|
240
240
|
NUMBER_COMPARE: (name, expected, value) => `'${name}' must be ${expected} ${value}`,
|
|
241
241
|
EMPTY_ARRAY: (name) => `'${name}' is an empty array`,
|
|
242
242
|
EMPTY_FILTERED_ARRAY: (name, type) => `There is no valid '${type}' in the '${name}' array`,
|
|
@@ -342,26 +342,33 @@ var Playlist = class {
|
|
|
342
342
|
__publicField(this, "url");
|
|
343
343
|
__publicField(this, "thumbnail");
|
|
344
344
|
const { member, properties, metadata } = options;
|
|
345
|
-
if (typeof playlist !== "object") {
|
|
346
|
-
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");
|
|
347
347
|
}
|
|
348
348
|
if (typeof properties !== "undefined" && !isRecord(properties)) {
|
|
349
349
|
throw new DisTubeError("INVALID_TYPE", "object", properties, "properties");
|
|
350
350
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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;
|
|
356
366
|
}
|
|
357
367
|
this.songs.map((s) => s.constructor.name === "Song" && (s.playlist = this));
|
|
358
|
-
this.member = member || info.member || void 0;
|
|
359
|
-
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`);
|
|
360
|
-
this.url = info.url || info.webpage_url;
|
|
361
|
-
this.thumbnail = info.thumbnail?.url || info.thumbnail || this.songs[0].thumbnail;
|
|
362
368
|
if (properties)
|
|
363
369
|
for (const [key, value] of Object.entries(properties))
|
|
364
370
|
this[key] = value;
|
|
371
|
+
this.member = member;
|
|
365
372
|
this.metadata = metadata;
|
|
366
373
|
}
|
|
367
374
|
get duration() {
|
|
@@ -395,41 +402,64 @@ _metadata = new WeakMap();
|
|
|
395
402
|
_member = new WeakMap();
|
|
396
403
|
|
|
397
404
|
// src/struct/SearchResult.ts
|
|
398
|
-
var
|
|
405
|
+
var ISearchResult = class {
|
|
399
406
|
constructor(info) {
|
|
400
407
|
__publicField(this, "source");
|
|
401
|
-
__publicField(this, "type");
|
|
402
408
|
__publicField(this, "id");
|
|
403
409
|
__publicField(this, "name");
|
|
404
410
|
__publicField(this, "url");
|
|
405
|
-
__publicField(this, "views");
|
|
406
|
-
__publicField(this, "isLive");
|
|
407
|
-
__publicField(this, "duration");
|
|
408
|
-
__publicField(this, "formattedDuration");
|
|
409
|
-
__publicField(this, "thumbnail");
|
|
410
411
|
__publicField(this, "uploader");
|
|
411
412
|
this.source = "youtube";
|
|
412
|
-
this.type = info.type === "video" ? "video" /* VIDEO */ : "playlist" /* PLAYLIST */;
|
|
413
413
|
this.id = info.id;
|
|
414
414
|
this.name = info.name;
|
|
415
415
|
this.url = info.url;
|
|
416
|
-
if (this.type === "video" /* VIDEO */) {
|
|
417
|
-
info = info;
|
|
418
|
-
this.views = info.views;
|
|
419
|
-
this.isLive = info.isLive;
|
|
420
|
-
this.duration = this.isLive ? 0 : toSecond(info.duration);
|
|
421
|
-
this.formattedDuration = this.isLive ? "Live" : formatDuration(this.duration);
|
|
422
|
-
this.thumbnail = info.thumbnail;
|
|
423
|
-
} else if (this.type !== "playlist") {
|
|
424
|
-
throw new DisTubeError("INVALID_TYPE", ["video", "playlist"], this.type, "SearchResult.type");
|
|
425
|
-
}
|
|
426
416
|
this.uploader = {
|
|
427
|
-
name:
|
|
428
|
-
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
|
|
429
459
|
};
|
|
430
460
|
}
|
|
431
461
|
};
|
|
432
|
-
__name(
|
|
462
|
+
__name(SearchResultPlaylist, "SearchResultPlaylist");
|
|
433
463
|
|
|
434
464
|
// src/struct/Song.ts
|
|
435
465
|
var _metadata2, _member2, _playlist;
|
|
@@ -569,114 +599,6 @@ _metadata2 = new WeakMap();
|
|
|
569
599
|
_member2 = new WeakMap();
|
|
570
600
|
_playlist = new WeakMap();
|
|
571
601
|
|
|
572
|
-
// src/core/DisTubeOptions.ts
|
|
573
|
-
var _validateOptions, validateOptions_fn;
|
|
574
|
-
var Options = class {
|
|
575
|
-
constructor(options) {
|
|
576
|
-
__privateAdd(this, _validateOptions);
|
|
577
|
-
__publicField(this, "plugins");
|
|
578
|
-
__publicField(this, "emitNewSongOnly");
|
|
579
|
-
__publicField(this, "leaveOnFinish");
|
|
580
|
-
__publicField(this, "leaveOnStop");
|
|
581
|
-
__publicField(this, "leaveOnEmpty");
|
|
582
|
-
__publicField(this, "emptyCooldown");
|
|
583
|
-
__publicField(this, "savePreviousSongs");
|
|
584
|
-
__publicField(this, "searchSongs");
|
|
585
|
-
__publicField(this, "searchCooldown");
|
|
586
|
-
__publicField(this, "youtubeCookie");
|
|
587
|
-
__publicField(this, "youtubeIdentityToken");
|
|
588
|
-
__publicField(this, "customFilters");
|
|
589
|
-
__publicField(this, "ytdlOptions");
|
|
590
|
-
__publicField(this, "nsfw");
|
|
591
|
-
__publicField(this, "emitAddSongWhenCreatingQueue");
|
|
592
|
-
__publicField(this, "emitAddListWhenCreatingQueue");
|
|
593
|
-
__publicField(this, "joinNewVoiceChannel");
|
|
594
|
-
__publicField(this, "streamType");
|
|
595
|
-
if (typeof options !== "object" || Array.isArray(options)) {
|
|
596
|
-
throw new DisTubeError("INVALID_TYPE", "object", options, "DisTubeOptions");
|
|
597
|
-
}
|
|
598
|
-
const opts = { ...defaultOptions, ...options };
|
|
599
|
-
this.plugins = opts.plugins;
|
|
600
|
-
this.emitNewSongOnly = opts.emitNewSongOnly;
|
|
601
|
-
this.leaveOnEmpty = opts.leaveOnEmpty;
|
|
602
|
-
this.leaveOnFinish = opts.leaveOnFinish;
|
|
603
|
-
this.leaveOnStop = opts.leaveOnStop;
|
|
604
|
-
this.savePreviousSongs = opts.savePreviousSongs;
|
|
605
|
-
this.searchSongs = opts.searchSongs;
|
|
606
|
-
this.youtubeCookie = opts.youtubeCookie;
|
|
607
|
-
this.youtubeIdentityToken = opts.youtubeIdentityToken;
|
|
608
|
-
this.customFilters = opts.customFilters;
|
|
609
|
-
this.ytdlOptions = opts.ytdlOptions;
|
|
610
|
-
this.searchCooldown = opts.searchCooldown;
|
|
611
|
-
this.emptyCooldown = opts.emptyCooldown;
|
|
612
|
-
this.nsfw = opts.nsfw;
|
|
613
|
-
this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;
|
|
614
|
-
this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;
|
|
615
|
-
this.joinNewVoiceChannel = opts.joinNewVoiceChannel;
|
|
616
|
-
this.streamType = opts.streamType;
|
|
617
|
-
checkInvalidKey(opts, this, "DisTubeOptions");
|
|
618
|
-
__privateMethod(this, _validateOptions, validateOptions_fn).call(this);
|
|
619
|
-
}
|
|
620
|
-
};
|
|
621
|
-
__name(Options, "Options");
|
|
622
|
-
_validateOptions = new WeakSet();
|
|
623
|
-
validateOptions_fn = /* @__PURE__ */ __name(function(options = this) {
|
|
624
|
-
if (typeof options.emitNewSongOnly !== "boolean") {
|
|
625
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitNewSongOnly, "DisTubeOptions.emitNewSongOnly");
|
|
626
|
-
}
|
|
627
|
-
if (typeof options.leaveOnEmpty !== "boolean") {
|
|
628
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnEmpty, "DisTubeOptions.leaveOnEmpty");
|
|
629
|
-
}
|
|
630
|
-
if (typeof options.leaveOnFinish !== "boolean") {
|
|
631
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnFinish, "DisTubeOptions.leaveOnFinish");
|
|
632
|
-
}
|
|
633
|
-
if (typeof options.leaveOnStop !== "boolean") {
|
|
634
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnStop, "DisTubeOptions.leaveOnStop");
|
|
635
|
-
}
|
|
636
|
-
if (typeof options.savePreviousSongs !== "boolean") {
|
|
637
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.savePreviousSongs, "DisTubeOptions.savePreviousSongs");
|
|
638
|
-
}
|
|
639
|
-
if (typeof options.joinNewVoiceChannel !== "boolean") {
|
|
640
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.joinNewVoiceChannel, "DisTubeOptions.joinNewVoiceChannel");
|
|
641
|
-
}
|
|
642
|
-
if (typeof options.youtubeCookie !== "undefined" && typeof options.youtubeCookie !== "string") {
|
|
643
|
-
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeCookie, "DisTubeOptions.youtubeCookie");
|
|
644
|
-
}
|
|
645
|
-
if (typeof options.youtubeIdentityToken !== "undefined" && typeof options.youtubeIdentityToken !== "string") {
|
|
646
|
-
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeIdentityToken, "DisTubeOptions.youtubeIdentityToken");
|
|
647
|
-
}
|
|
648
|
-
if (typeof options.customFilters !== "undefined" && typeof options.customFilters !== "object" || Array.isArray(options.customFilters)) {
|
|
649
|
-
throw new DisTubeError("INVALID_TYPE", "object", options.customFilters, "DisTubeOptions.customFilters");
|
|
650
|
-
}
|
|
651
|
-
if (typeof options.ytdlOptions !== "object" || Array.isArray(options.ytdlOptions)) {
|
|
652
|
-
throw new DisTubeError("INVALID_TYPE", "object", options.ytdlOptions, "DisTubeOptions.ytdlOptions");
|
|
653
|
-
}
|
|
654
|
-
if (typeof options.searchCooldown !== "number" || isNaN(options.searchCooldown)) {
|
|
655
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.searchCooldown, "DisTubeOptions.searchCooldown");
|
|
656
|
-
}
|
|
657
|
-
if (typeof options.emptyCooldown !== "number" || isNaN(options.emptyCooldown)) {
|
|
658
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.emptyCooldown, "DisTubeOptions.emptyCooldown");
|
|
659
|
-
}
|
|
660
|
-
if (typeof options.searchSongs !== "number" || isNaN(options.searchSongs)) {
|
|
661
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.searchSongs, "DisTubeOptions.searchSongs");
|
|
662
|
-
}
|
|
663
|
-
if (!Array.isArray(options.plugins)) {
|
|
664
|
-
throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", options.plugins, "DisTubeOptions.plugins");
|
|
665
|
-
}
|
|
666
|
-
if (typeof options.nsfw !== "boolean") {
|
|
667
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.nsfw, "DisTubeOptions.nsfw");
|
|
668
|
-
}
|
|
669
|
-
if (typeof options.emitAddSongWhenCreatingQueue !== "boolean") {
|
|
670
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddSongWhenCreatingQueue, "DisTubeOptions.emitAddSongWhenCreatingQueue");
|
|
671
|
-
}
|
|
672
|
-
if (typeof options.emitAddListWhenCreatingQueue !== "boolean") {
|
|
673
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddListWhenCreatingQueue, "DisTubeOptions.emitAddListWhenCreatingQueue");
|
|
674
|
-
}
|
|
675
|
-
if (typeof options.streamType !== "number" || isNaN(options.streamType) || !StreamType[options.streamType]) {
|
|
676
|
-
throw new DisTubeError("INVALID_TYPE", "StreamType", options.streamType, "DisTubeOptions.streamType");
|
|
677
|
-
}
|
|
678
|
-
}, "#validateOptions");
|
|
679
|
-
|
|
680
602
|
// src/core/DisTubeBase.ts
|
|
681
603
|
var DisTubeBase = class {
|
|
682
604
|
constructor(distube) {
|
|
@@ -707,77 +629,202 @@ var DisTubeBase = class {
|
|
|
707
629
|
};
|
|
708
630
|
__name(DisTubeBase, "DisTubeBase");
|
|
709
631
|
|
|
710
|
-
// src/core/
|
|
711
|
-
import {
|
|
712
|
-
import {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
this
|
|
726
|
-
this
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
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);
|
|
758
693
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
throw new DisTubeError("UNAVAILABLE_VIDEO");
|
|
762
|
-
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
763
|
-
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
764
|
-
}
|
|
765
|
-
const bestFormat = chooseBestVideoFormat(formats, options.isLive);
|
|
766
|
-
if (!bestFormat)
|
|
767
|
-
throw new DisTubeError("UNPLAYABLE_FORMATS");
|
|
768
|
-
return new DisTubeStream(bestFormat.url, options);
|
|
694
|
+
get channel() {
|
|
695
|
+
return __privateGet(this, _channel);
|
|
769
696
|
}
|
|
770
|
-
|
|
771
|
-
if (!
|
|
772
|
-
throw new DisTubeError("INVALID_TYPE", "
|
|
697
|
+
set channel(channel) {
|
|
698
|
+
if (!isSupportedVoiceChannel(channel)) {
|
|
699
|
+
throw new DisTubeError("INVALID_TYPE", "BaseGuildVoiceChannel", channel, "DisTubeVoice#channel");
|
|
773
700
|
}
|
|
774
|
-
if (
|
|
775
|
-
throw new DisTubeError("
|
|
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");
|
|
776
712
|
}
|
|
777
|
-
|
|
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;
|
|
778
809
|
}
|
|
779
810
|
};
|
|
780
|
-
__name(
|
|
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");
|
|
781
828
|
|
|
782
829
|
// src/core/manager/BaseManager.ts
|
|
783
830
|
import { Collection } from "discord.js";
|
|
@@ -813,6 +860,123 @@ var GuildIdManager = class extends BaseManager {
|
|
|
813
860
|
};
|
|
814
861
|
__name(GuildIdManager, "GuildIdManager");
|
|
815
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");
|
|
979
|
+
|
|
816
980
|
// src/core/manager/QueueManager.ts
|
|
817
981
|
var _voiceEventHandler, voiceEventHandler_fn, _handleSongFinish, handleSongFinish_fn, _handlePlayingError, handlePlayingError_fn, _emitPlaySong, emitPlaySong_fn;
|
|
818
982
|
var QueueManager = class extends GuildIdManager {
|
|
@@ -932,371 +1096,58 @@ handleSongFinish_fn = /* @__PURE__ */ __name(async function(queue) {
|
|
|
932
1096
|
if (this.options.leaveOnFinish)
|
|
933
1097
|
queue.voice.leave();
|
|
934
1098
|
if (!queue.autoplay)
|
|
935
|
-
this.emit("finish", queue);
|
|
936
|
-
queue.remove();
|
|
937
|
-
return;
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
const emitPlaySong = __privateMethod(this, _emitPlaySong, emitPlaySong_fn).call(this, queue);
|
|
941
|
-
if (!queue._prev && (queue.repeatMode !== 1 /* SONG */ || queue._next)) {
|
|
942
|
-
const prev = queue.songs.shift();
|
|
943
|
-
delete prev.formats;
|
|
944
|
-
delete prev.streamURL;
|
|
945
|
-
if (this.options.savePreviousSongs)
|
|
946
|
-
queue.previousSongs.push(prev);
|
|
947
|
-
else
|
|
948
|
-
queue.previousSongs.push({ id: prev.id });
|
|
949
|
-
}
|
|
950
|
-
queue._next = queue._prev = false;
|
|
951
|
-
queue.beginTime = 0;
|
|
952
|
-
const err = await this.playSong(queue);
|
|
953
|
-
if (!err && emitPlaySong)
|
|
954
|
-
this.emit("playSong", queue, queue.songs[0]);
|
|
955
|
-
} finally {
|
|
956
|
-
queue._taskQueue.resolve();
|
|
957
|
-
}
|
|
958
|
-
}, "#handleSongFinish");
|
|
959
|
-
_handlePlayingError = new WeakSet();
|
|
960
|
-
handlePlayingError_fn = /* @__PURE__ */ __name(function(queue, error) {
|
|
961
|
-
const song = queue.songs.shift();
|
|
962
|
-
try {
|
|
963
|
-
error.name = "PlayingError";
|
|
964
|
-
error.message = `${error.message}
|
|
965
|
-
Id: ${song.id}
|
|
966
|
-
Name: ${song.name}`;
|
|
967
|
-
} catch {
|
|
968
|
-
}
|
|
969
|
-
this.emitError(error, queue.textChannel);
|
|
970
|
-
if (queue.songs.length > 0) {
|
|
971
|
-
this.playSong(queue).then((e) => {
|
|
972
|
-
if (!e)
|
|
973
|
-
this.emit("playSong", queue, queue.songs[0]);
|
|
974
|
-
});
|
|
975
|
-
} else {
|
|
976
|
-
queue.stop();
|
|
977
|
-
}
|
|
978
|
-
}, "#handlePlayingError");
|
|
979
|
-
_emitPlaySong = new WeakSet();
|
|
980
|
-
emitPlaySong_fn = /* @__PURE__ */ __name(function(queue) {
|
|
981
|
-
return !this.options.emitNewSongOnly || queue.repeatMode === 1 /* SONG */ && queue._next || queue.repeatMode !== 1 /* SONG */ && queue.songs[0]?.id !== queue.songs[1]?.id;
|
|
982
|
-
}, "#emitPlaySong");
|
|
983
|
-
|
|
984
|
-
// src/core/manager/FilterManager.ts
|
|
985
|
-
var _validate, validate_fn, _resolveName, resolveName_fn, _resolveValue, resolveValue_fn, _apply, apply_fn;
|
|
986
|
-
var FilterManager = class extends BaseManager {
|
|
987
|
-
constructor(queue) {
|
|
988
|
-
super(queue.distube);
|
|
989
|
-
__privateAdd(this, _validate);
|
|
990
|
-
__privateAdd(this, _resolveName);
|
|
991
|
-
__privateAdd(this, _resolveValue);
|
|
992
|
-
__privateAdd(this, _apply);
|
|
993
|
-
__publicField(this, "queue");
|
|
994
|
-
this.queue = queue;
|
|
995
|
-
}
|
|
996
|
-
add(filterOrFilters, override = false) {
|
|
997
|
-
if (Array.isArray(filterOrFilters)) {
|
|
998
|
-
const resolvedFilters = filterOrFilters.map((f) => __privateMethod(this, _validate, validate_fn).call(this, f));
|
|
999
|
-
const newFilters = resolvedFilters.reduceRight((unique, o) => {
|
|
1000
|
-
if (!unique.some((obj) => obj === o && obj.name === o) && !unique.some((obj) => obj !== o.name && obj.name !== o.name)) {
|
|
1001
|
-
if (!this.has(o))
|
|
1002
|
-
unique.push(o);
|
|
1003
|
-
if (this.has(o) && override) {
|
|
1004
|
-
this.remove(o);
|
|
1005
|
-
unique.push(o);
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
return unique;
|
|
1009
|
-
}, []).reverse();
|
|
1010
|
-
return this.set([...this.collection.values(), ...newFilters]);
|
|
1011
|
-
}
|
|
1012
|
-
return this.set([...this.collection.values(), filterOrFilters]);
|
|
1013
|
-
}
|
|
1014
|
-
clear() {
|
|
1015
|
-
return this.set([]);
|
|
1016
|
-
}
|
|
1017
|
-
set(filters) {
|
|
1018
|
-
this.collection.clear();
|
|
1019
|
-
for (const filter of filters) {
|
|
1020
|
-
const resolved = __privateMethod(this, _validate, validate_fn).call(this, filter);
|
|
1021
|
-
this.collection.set(__privateMethod(this, _resolveName, resolveName_fn).call(this, resolved), resolved);
|
|
1022
|
-
}
|
|
1023
|
-
__privateMethod(this, _apply, apply_fn).call(this);
|
|
1024
|
-
return this;
|
|
1025
|
-
}
|
|
1026
|
-
remove(filterOrFilters) {
|
|
1027
|
-
const remove = /* @__PURE__ */ __name((f) => this.collection.delete(__privateMethod(this, _resolveName, resolveName_fn).call(this, __privateMethod(this, _validate, validate_fn).call(this, f))), "remove");
|
|
1028
|
-
if (Array.isArray(filterOrFilters))
|
|
1029
|
-
filterOrFilters.map(remove);
|
|
1030
|
-
else
|
|
1031
|
-
remove(filterOrFilters);
|
|
1032
|
-
__privateMethod(this, _apply, apply_fn).call(this);
|
|
1033
|
-
return this;
|
|
1034
|
-
}
|
|
1035
|
-
has(filter) {
|
|
1036
|
-
return this.collection.has(__privateMethod(this, _resolveName, resolveName_fn).call(this, filter));
|
|
1037
|
-
}
|
|
1038
|
-
get names() {
|
|
1039
|
-
return this.collection.map((f) => __privateMethod(this, _resolveName, resolveName_fn).call(this, f));
|
|
1040
|
-
}
|
|
1041
|
-
get values() {
|
|
1042
|
-
return this.collection.map((f) => __privateMethod(this, _resolveValue, resolveValue_fn).call(this, f));
|
|
1043
|
-
}
|
|
1044
|
-
toString() {
|
|
1045
|
-
return this.names.toString();
|
|
1046
|
-
}
|
|
1047
|
-
};
|
|
1048
|
-
__name(FilterManager, "FilterManager");
|
|
1049
|
-
_validate = new WeakSet();
|
|
1050
|
-
validate_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1051
|
-
if (typeof filter === "string" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter) || typeof filter === "object" && typeof filter.name === "string" && typeof filter.value === "string") {
|
|
1052
|
-
return filter;
|
|
1053
|
-
}
|
|
1054
|
-
throw new DisTubeError("INVALID_TYPE", "FilterResolvable", filter, "filter");
|
|
1055
|
-
}, "#validate");
|
|
1056
|
-
_resolveName = new WeakSet();
|
|
1057
|
-
resolveName_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1058
|
-
return typeof filter === "string" ? filter : filter.name;
|
|
1059
|
-
}, "#resolveName");
|
|
1060
|
-
_resolveValue = new WeakSet();
|
|
1061
|
-
resolveValue_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1062
|
-
return typeof filter === "string" ? this.distube.filters[filter] : filter.value;
|
|
1063
|
-
}, "#resolveValue");
|
|
1064
|
-
_apply = new WeakSet();
|
|
1065
|
-
apply_fn = /* @__PURE__ */ __name(function() {
|
|
1066
|
-
this.queue.beginTime = this.queue.currentTime;
|
|
1067
|
-
this.queues.playSong(this.queue);
|
|
1068
|
-
}, "#apply");
|
|
1069
|
-
|
|
1070
|
-
// src/core/voice/DisTubeVoice.ts
|
|
1071
|
-
import { TypedEmitter } from "tiny-typed-emitter";
|
|
1072
|
-
import {
|
|
1073
|
-
AudioPlayerStatus,
|
|
1074
|
-
VoiceConnectionDisconnectReason,
|
|
1075
|
-
VoiceConnectionStatus,
|
|
1076
|
-
createAudioPlayer,
|
|
1077
|
-
createAudioResource,
|
|
1078
|
-
joinVoiceChannel
|
|
1079
|
-
} from "@discordjs/voice";
|
|
1080
|
-
var _channel, _volume, _br, br_fn, _join, join_fn;
|
|
1081
|
-
var DisTubeVoice = class extends TypedEmitter {
|
|
1082
|
-
constructor(voiceManager, channel) {
|
|
1083
|
-
super();
|
|
1084
|
-
__privateAdd(this, _br);
|
|
1085
|
-
__privateAdd(this, _join);
|
|
1086
|
-
__publicField(this, "id");
|
|
1087
|
-
__publicField(this, "voices");
|
|
1088
|
-
__publicField(this, "audioPlayer");
|
|
1089
|
-
__publicField(this, "connection");
|
|
1090
|
-
__publicField(this, "audioResource");
|
|
1091
|
-
__publicField(this, "emittedError");
|
|
1092
|
-
__publicField(this, "isDisconnected", false);
|
|
1093
|
-
__privateAdd(this, _channel, void 0);
|
|
1094
|
-
__privateAdd(this, _volume, 100);
|
|
1095
|
-
this.voices = voiceManager;
|
|
1096
|
-
this.id = channel.guildId;
|
|
1097
|
-
this.channel = channel;
|
|
1098
|
-
this.voices.add(this.id, this);
|
|
1099
|
-
this.audioPlayer = createAudioPlayer().on(AudioPlayerStatus.Idle, (oldState) => {
|
|
1100
|
-
if (oldState.status !== AudioPlayerStatus.Idle) {
|
|
1101
|
-
delete this.audioResource;
|
|
1102
|
-
this.emit("finish");
|
|
1103
|
-
}
|
|
1104
|
-
}).on(AudioPlayerStatus.Playing, () => __privateMethod(this, _br, br_fn).call(this)).on("error", (error) => {
|
|
1105
|
-
if (this.emittedError)
|
|
1106
|
-
return;
|
|
1107
|
-
this.emittedError = true;
|
|
1108
|
-
this.emit("error", error);
|
|
1109
|
-
});
|
|
1110
|
-
this.connection.on(VoiceConnectionStatus.Disconnected, (_, newState) => {
|
|
1111
|
-
if (newState.reason === VoiceConnectionDisconnectReason.Manual) {
|
|
1112
|
-
this.leave();
|
|
1113
|
-
} else if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
|
|
1114
|
-
entersState(this.connection, VoiceConnectionStatus.Connecting, 5e3).catch(() => {
|
|
1115
|
-
if (![VoiceConnectionStatus.Ready, VoiceConnectionStatus.Connecting].includes(this.connection.state.status)) {
|
|
1116
|
-
this.leave();
|
|
1117
|
-
}
|
|
1118
|
-
});
|
|
1119
|
-
} else if (this.connection.rejoinAttempts < 5) {
|
|
1120
|
-
setTimeout(() => {
|
|
1121
|
-
this.connection.rejoin();
|
|
1122
|
-
}, (this.connection.rejoinAttempts + 1) * 5e3).unref();
|
|
1123
|
-
} else if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) {
|
|
1124
|
-
this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
|
|
1125
|
-
}
|
|
1126
|
-
}).on(VoiceConnectionStatus.Destroyed, () => {
|
|
1127
|
-
this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
|
|
1128
|
-
}).on("error", () => void 0);
|
|
1129
|
-
this.connection.subscribe(this.audioPlayer);
|
|
1130
|
-
}
|
|
1131
|
-
get channel() {
|
|
1132
|
-
return __privateGet(this, _channel);
|
|
1133
|
-
}
|
|
1134
|
-
set channel(channel) {
|
|
1135
|
-
if (!isSupportedVoiceChannel(channel)) {
|
|
1136
|
-
throw new DisTubeError("INVALID_TYPE", "BaseGuildVoiceChannel", channel, "DisTubeVoice#channel");
|
|
1137
|
-
}
|
|
1138
|
-
if (channel.guildId !== this.id)
|
|
1139
|
-
throw new DisTubeError("VOICE_DIFFERENT_GUILD");
|
|
1140
|
-
if (channel.client.user?.id !== this.voices.client.user?.id)
|
|
1141
|
-
throw new DisTubeError("VOICE_DIFFERENT_CLIENT");
|
|
1142
|
-
if (channel.id === __privateGet(this, _channel)?.id)
|
|
1143
|
-
return;
|
|
1144
|
-
if (!channel.joinable) {
|
|
1145
|
-
if (channel.full)
|
|
1146
|
-
throw new DisTubeError("VOICE_FULL");
|
|
1147
|
-
else
|
|
1148
|
-
throw new DisTubeError("VOICE_MISSING_PERMS");
|
|
1149
|
-
}
|
|
1150
|
-
this.connection = __privateMethod(this, _join, join_fn).call(this, channel);
|
|
1151
|
-
__privateSet(this, _channel, channel);
|
|
1152
|
-
__privateMethod(this, _br, br_fn).call(this);
|
|
1153
|
-
}
|
|
1154
|
-
async join(channel) {
|
|
1155
|
-
const TIMEOUT = 3e4;
|
|
1156
|
-
if (channel)
|
|
1157
|
-
this.channel = channel;
|
|
1158
|
-
try {
|
|
1159
|
-
await entersState(this.connection, VoiceConnectionStatus.Ready, TIMEOUT);
|
|
1160
|
-
} catch {
|
|
1161
|
-
if (this.connection.state.status === VoiceConnectionStatus.Ready)
|
|
1162
|
-
return this;
|
|
1163
|
-
if (this.connection.state.status !== VoiceConnectionStatus.Destroyed)
|
|
1164
|
-
this.connection.destroy();
|
|
1165
|
-
this.voices.remove(this.id);
|
|
1166
|
-
throw new DisTubeError("VOICE_CONNECT_FAILED", TIMEOUT / 1e3);
|
|
1167
|
-
}
|
|
1168
|
-
return this;
|
|
1169
|
-
}
|
|
1170
|
-
leave(error) {
|
|
1171
|
-
this.stop(true);
|
|
1172
|
-
if (!this.isDisconnected) {
|
|
1173
|
-
this.emit("disconnect", error);
|
|
1174
|
-
this.isDisconnected = true;
|
|
1175
|
-
}
|
|
1176
|
-
if (this.connection.state.status !== VoiceConnectionStatus.Destroyed)
|
|
1177
|
-
this.connection.destroy();
|
|
1178
|
-
this.voices.remove(this.id);
|
|
1179
|
-
}
|
|
1180
|
-
stop(force = false) {
|
|
1181
|
-
this.audioPlayer.stop(force);
|
|
1182
|
-
}
|
|
1183
|
-
play(stream) {
|
|
1184
|
-
this.emittedError = false;
|
|
1185
|
-
stream.stream.on("error", (error) => {
|
|
1186
|
-
if (this.emittedError || error.code === "ERR_STREAM_PREMATURE_CLOSE")
|
|
1187
|
-
return;
|
|
1188
|
-
this.emittedError = true;
|
|
1189
|
-
this.emit("error", error);
|
|
1190
|
-
});
|
|
1191
|
-
this.audioResource = createAudioResource(stream.stream, {
|
|
1192
|
-
inputType: stream.type,
|
|
1193
|
-
inlineVolume: true
|
|
1194
|
-
});
|
|
1195
|
-
this.volume = __privateGet(this, _volume);
|
|
1196
|
-
this.audioPlayer.play(this.audioResource);
|
|
1197
|
-
}
|
|
1198
|
-
set volume(volume) {
|
|
1199
|
-
if (typeof volume !== "number" || isNaN(volume)) {
|
|
1200
|
-
throw new DisTubeError("INVALID_TYPE", "number", volume, "volume");
|
|
1201
|
-
}
|
|
1202
|
-
if (volume < 0) {
|
|
1203
|
-
throw new DisTubeError("NUMBER_COMPARE", "Volume", "bigger or equal to", 0);
|
|
1204
|
-
}
|
|
1205
|
-
__privateSet(this, _volume, volume);
|
|
1206
|
-
this.audioResource?.volume?.setVolume(Math.pow(__privateGet(this, _volume) / 100, 0.5 / Math.log10(2)));
|
|
1207
|
-
}
|
|
1208
|
-
get volume() {
|
|
1209
|
-
return __privateGet(this, _volume);
|
|
1210
|
-
}
|
|
1211
|
-
get playbackDuration() {
|
|
1212
|
-
return (this.audioResource?.playbackDuration ?? 0) / 1e3;
|
|
1213
|
-
}
|
|
1214
|
-
pause() {
|
|
1215
|
-
this.audioPlayer.pause();
|
|
1216
|
-
}
|
|
1217
|
-
unpause() {
|
|
1218
|
-
this.audioPlayer.unpause();
|
|
1219
|
-
}
|
|
1220
|
-
get selfDeaf() {
|
|
1221
|
-
return this.connection.joinConfig.selfDeaf;
|
|
1222
|
-
}
|
|
1223
|
-
get selfMute() {
|
|
1224
|
-
return this.connection.joinConfig.selfMute;
|
|
1225
|
-
}
|
|
1226
|
-
setSelfDeaf(selfDeaf) {
|
|
1227
|
-
if (typeof selfDeaf !== "boolean") {
|
|
1228
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", selfDeaf, "selfDeaf");
|
|
1229
|
-
}
|
|
1230
|
-
return this.connection.rejoin({
|
|
1231
|
-
...this.connection.joinConfig,
|
|
1232
|
-
selfDeaf
|
|
1233
|
-
});
|
|
1234
|
-
}
|
|
1235
|
-
setSelfMute(selfMute) {
|
|
1236
|
-
if (typeof selfMute !== "boolean") {
|
|
1237
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", selfMute, "selfMute");
|
|
1238
|
-
}
|
|
1239
|
-
return this.connection.rejoin({
|
|
1240
|
-
...this.connection.joinConfig,
|
|
1241
|
-
selfMute
|
|
1242
|
-
});
|
|
1243
|
-
}
|
|
1244
|
-
get voiceState() {
|
|
1245
|
-
return getClientMember(this.channel?.guild)?.voice;
|
|
1246
|
-
}
|
|
1247
|
-
};
|
|
1248
|
-
__name(DisTubeVoice, "DisTubeVoice");
|
|
1249
|
-
_channel = new WeakMap();
|
|
1250
|
-
_volume = new WeakMap();
|
|
1251
|
-
_br = new WeakSet();
|
|
1252
|
-
br_fn = /* @__PURE__ */ __name(function() {
|
|
1253
|
-
if (this.audioResource?.encoder?.encoder)
|
|
1254
|
-
this.audioResource.encoder.setBitrate(this.channel.bitrate);
|
|
1255
|
-
}, "#br");
|
|
1256
|
-
_join = new WeakSet();
|
|
1257
|
-
join_fn = /* @__PURE__ */ __name(function(channel) {
|
|
1258
|
-
return joinVoiceChannel({
|
|
1259
|
-
channelId: channel.id,
|
|
1260
|
-
guildId: this.id,
|
|
1261
|
-
adapterCreator: channel.guild.voiceAdapterCreator,
|
|
1262
|
-
group: channel.client.user?.id
|
|
1263
|
-
});
|
|
1264
|
-
}, "#join");
|
|
1265
|
-
|
|
1266
|
-
// src/core/voice/DisTubeVoiceManager.ts
|
|
1267
|
-
import { VoiceConnectionStatus as VoiceConnectionStatus2, getVoiceConnection } from "@discordjs/voice";
|
|
1268
|
-
var DisTubeVoiceManager = class extends GuildIdManager {
|
|
1269
|
-
create(channel) {
|
|
1270
|
-
const existing = this.get(channel.guildId);
|
|
1271
|
-
if (existing) {
|
|
1272
|
-
existing.channel = channel;
|
|
1273
|
-
return existing;
|
|
1099
|
+
this.emit("finish", queue);
|
|
1100
|
+
queue.remove();
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1274
1103
|
}
|
|
1275
|
-
|
|
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();
|
|
1276
1121
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
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 {
|
|
1282
1132
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
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();
|
|
1293
1141
|
}
|
|
1294
|
-
};
|
|
1295
|
-
|
|
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");
|
|
1296
1147
|
|
|
1297
1148
|
// src/core/DisTubeHandler.ts
|
|
1298
|
-
import ytdl from "@distube/ytdl-core";
|
|
1299
1149
|
import ytpl from "@distube/ytpl";
|
|
1150
|
+
import ytdl from "@distube/ytdl-core";
|
|
1300
1151
|
var DisTubeHandler = class extends DisTubeBase {
|
|
1301
1152
|
constructor(distube) {
|
|
1302
1153
|
super(distube);
|
|
@@ -1360,11 +1211,10 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1360
1211
|
song.member = options.member;
|
|
1361
1212
|
return song;
|
|
1362
1213
|
}
|
|
1363
|
-
if (song instanceof
|
|
1364
|
-
|
|
1365
|
-
|
|
1214
|
+
if (song instanceof SearchResultVideo)
|
|
1215
|
+
return new Song(song, options);
|
|
1216
|
+
if (song instanceof SearchResultPlaylist)
|
|
1366
1217
|
return this.resolvePlaylist(song.url, options);
|
|
1367
|
-
}
|
|
1368
1218
|
if (isObject(song))
|
|
1369
1219
|
return new Song(song, options);
|
|
1370
1220
|
if (ytpl.validateID(song))
|
|
@@ -1389,14 +1239,19 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1389
1239
|
playlist.member = member;
|
|
1390
1240
|
return playlist;
|
|
1391
1241
|
}
|
|
1392
|
-
let solvablePlaylist;
|
|
1393
1242
|
if (typeof playlist === "string") {
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
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 });
|
|
1400
1255
|
}
|
|
1401
1256
|
async searchSong(message, query) {
|
|
1402
1257
|
if (!isMessageInstance(message))
|
|
@@ -1530,6 +1385,186 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1530
1385
|
};
|
|
1531
1386
|
__name(DisTubeHandler, "DisTubeHandler");
|
|
1532
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");
|
|
1567
|
+
|
|
1533
1568
|
// src/struct/Queue.ts
|
|
1534
1569
|
var _filters;
|
|
1535
1570
|
var Queue = class extends DisTubeBase {
|
|
@@ -1572,7 +1607,7 @@ var Queue = class extends DisTubeBase {
|
|
|
1572
1607
|
this._listeners = void 0;
|
|
1573
1608
|
}
|
|
1574
1609
|
get clientMember() {
|
|
1575
|
-
return
|
|
1610
|
+
return this.voice.channel.guild.members.me ?? void 0;
|
|
1576
1611
|
}
|
|
1577
1612
|
get filters() {
|
|
1578
1613
|
return __privateGet(this, _filters);
|
|
@@ -1916,7 +1951,7 @@ function isVoiceChannelEmpty(voiceState) {
|
|
|
1916
1951
|
const clientId = voiceState.client.user?.id;
|
|
1917
1952
|
if (!guild || !clientId)
|
|
1918
1953
|
return false;
|
|
1919
|
-
const voiceChannel = guild.members.
|
|
1954
|
+
const voiceChannel = guild.members.me?.voice?.channel;
|
|
1920
1955
|
if (!voiceChannel)
|
|
1921
1956
|
return false;
|
|
1922
1957
|
const members = voiceChannel.members.filter((m) => !m.user.bot);
|
|
@@ -1936,7 +1971,7 @@ function isMemberInstance(member) {
|
|
|
1936
1971
|
}
|
|
1937
1972
|
__name(isMemberInstance, "isMemberInstance");
|
|
1938
1973
|
function isTextChannelInstance(channel) {
|
|
1939
|
-
return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && typeof channel.name === "string" && Constants.TextBasedChannelTypes.includes(channel.type) && typeof channel.messages?.cache === "object";
|
|
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";
|
|
1940
1975
|
}
|
|
1941
1976
|
__name(isTextChannelInstance, "isTextChannelInstance");
|
|
1942
1977
|
function isMessageInstance(message) {
|
|
@@ -1982,34 +2017,6 @@ function checkInvalidKey(target, source, sourceName) {
|
|
|
1982
2017
|
throw new DisTubeError("INVALID_KEY", sourceName, invalidKey);
|
|
1983
2018
|
}
|
|
1984
2019
|
__name(checkInvalidKey, "checkInvalidKey");
|
|
1985
|
-
async function waitEvent(target, status, maxTime) {
|
|
1986
|
-
let cleanup = /* @__PURE__ */ __name(() => {
|
|
1987
|
-
}, "cleanup");
|
|
1988
|
-
try {
|
|
1989
|
-
await new Promise((resolve, reject) => {
|
|
1990
|
-
const timeout = setTimeout(() => reject(new Error(`Didn't trigger ${status} within ${maxTime}ms`)), maxTime);
|
|
1991
|
-
target.once(status, resolve);
|
|
1992
|
-
target.once("error", reject);
|
|
1993
|
-
cleanup = /* @__PURE__ */ __name(() => {
|
|
1994
|
-
clearTimeout(timeout);
|
|
1995
|
-
target.off(status, resolve);
|
|
1996
|
-
target.off("error", reject);
|
|
1997
|
-
}, "cleanup");
|
|
1998
|
-
if (target?.state?.status === status)
|
|
1999
|
-
resolve(0);
|
|
2000
|
-
});
|
|
2001
|
-
return target;
|
|
2002
|
-
} finally {
|
|
2003
|
-
cleanup();
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
__name(waitEvent, "waitEvent");
|
|
2007
|
-
async function entersState(target, status, maxTime) {
|
|
2008
|
-
if (target.state.status === status)
|
|
2009
|
-
return target;
|
|
2010
|
-
return waitEvent(target, status, maxTime);
|
|
2011
|
-
}
|
|
2012
|
-
__name(entersState, "entersState");
|
|
2013
2020
|
function isObject(obj) {
|
|
2014
2021
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
2015
2022
|
}
|
|
@@ -2018,16 +2025,6 @@ function isRecord(obj) {
|
|
|
2018
2025
|
return isObject(obj);
|
|
2019
2026
|
}
|
|
2020
2027
|
__name(isRecord, "isRecord");
|
|
2021
|
-
function getClientMember(guild) {
|
|
2022
|
-
const clientUser = guild.client.user;
|
|
2023
|
-
if (!clientUser)
|
|
2024
|
-
return void 0;
|
|
2025
|
-
const clientMember = guild.members.resolve(clientUser);
|
|
2026
|
-
if (!clientMember)
|
|
2027
|
-
return void 0;
|
|
2028
|
-
return clientMember;
|
|
2029
|
-
}
|
|
2030
|
-
__name(getClientMember, "getClientMember");
|
|
2031
2028
|
|
|
2032
2029
|
// src/plugin/http.ts
|
|
2033
2030
|
import http from "http";
|
|
@@ -2119,7 +2116,7 @@ var DisTube = class extends TypedEmitter2 {
|
|
|
2119
2116
|
if (!isObject(options))
|
|
2120
2117
|
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
2121
2118
|
const { textChannel, member, skip, message, metadata } = {
|
|
2122
|
-
member:
|
|
2119
|
+
member: voiceChannel.guild.members.me ?? void 0,
|
|
2123
2120
|
textChannel: options?.message?.channel,
|
|
2124
2121
|
skip: false,
|
|
2125
2122
|
...options
|
|
@@ -2167,12 +2164,12 @@ var DisTube = class extends TypedEmitter2 {
|
|
|
2167
2164
|
if (!(e instanceof DisTubeError)) {
|
|
2168
2165
|
try {
|
|
2169
2166
|
e.name = "PlayError";
|
|
2170
|
-
e.message = `${song
|
|
2167
|
+
e.message = `${typeof song === "string" ? song : song.url}
|
|
2171
2168
|
${e.message}`;
|
|
2172
2169
|
} catch {
|
|
2173
2170
|
}
|
|
2174
2171
|
}
|
|
2175
|
-
|
|
2172
|
+
throw e;
|
|
2176
2173
|
} finally {
|
|
2177
2174
|
if (queuing)
|
|
2178
2175
|
queue?._taskQueue.resolve();
|
|
@@ -2184,7 +2181,7 @@ ${e.message}`;
|
|
|
2184
2181
|
throw new DisTubeError("INVALID_TYPE", "Array", songs, "songs");
|
|
2185
2182
|
if (!songs.length)
|
|
2186
2183
|
throw new DisTubeError("EMPTY_ARRAY", "songs");
|
|
2187
|
-
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 */);
|
|
2188
2185
|
if (!filteredSongs.length)
|
|
2189
2186
|
throw new DisTubeError("NO_VALID_SONG");
|
|
2190
2187
|
if (member && !isMemberInstance(member)) {
|
|
@@ -2206,7 +2203,7 @@ ${e.message}`;
|
|
|
2206
2203
|
return new Playlist(resolvedSongs, { member, properties, metadata });
|
|
2207
2204
|
}
|
|
2208
2205
|
async search(string, options = {}) {
|
|
2209
|
-
const opts = { type: "video"
|
|
2206
|
+
const opts = { type: "video" /* VIDEO */, limit: 10, safeSearch: false, ...options };
|
|
2210
2207
|
if (typeof opts.type !== "string" || !["video", "playlist"].includes(opts.type)) {
|
|
2211
2208
|
throw new DisTubeError("INVALID_TYPE", ["video", "playlist"], opts.type, "options.type");
|
|
2212
2209
|
}
|
|
@@ -2219,7 +2216,11 @@ ${e.message}`;
|
|
|
2219
2216
|
}
|
|
2220
2217
|
try {
|
|
2221
2218
|
const search = await ytsr(string, opts);
|
|
2222
|
-
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
|
+
});
|
|
2223
2224
|
if (results.length === 0)
|
|
2224
2225
|
throw new DisTubeError("NO_RESULT");
|
|
2225
2226
|
return results;
|
|
@@ -2339,8 +2340,9 @@ export {
|
|
|
2339
2340
|
Queue,
|
|
2340
2341
|
QueueManager,
|
|
2341
2342
|
RepeatMode,
|
|
2342
|
-
|
|
2343
|
+
SearchResultPlaylist,
|
|
2343
2344
|
SearchResultType,
|
|
2345
|
+
SearchResultVideo,
|
|
2344
2346
|
Song,
|
|
2345
2347
|
StreamType,
|
|
2346
2348
|
TaskQueue,
|
|
@@ -2350,9 +2352,7 @@ export {
|
|
|
2350
2352
|
DisTube as default,
|
|
2351
2353
|
defaultFilters,
|
|
2352
2354
|
defaultOptions,
|
|
2353
|
-
entersState,
|
|
2354
2355
|
formatDuration,
|
|
2355
|
-
getClientMember,
|
|
2356
2356
|
getResponseHeaders,
|
|
2357
2357
|
isClientInstance,
|
|
2358
2358
|
isGuildInstance,
|