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.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
"use strict";
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -56,7 +57,7 @@ var require_package = __commonJS({
|
|
|
56
57
|
"package.json"(exports, module2) {
|
|
57
58
|
module2.exports = {
|
|
58
59
|
name: "distube",
|
|
59
|
-
version: "4.0.0-dev.
|
|
60
|
+
version: "4.0.0-dev.6",
|
|
60
61
|
description: "A Discord.js module to simplify your music commands and play songs with audio filters on Discord without any API key.",
|
|
61
62
|
main: "./dist/index.js",
|
|
62
63
|
module: "./dist/index.mjs",
|
|
@@ -122,41 +123,41 @@ var require_package = __commonJS({
|
|
|
122
123
|
dependencies: {
|
|
123
124
|
"@distube/ytdl-core": "^4.11.3",
|
|
124
125
|
"@distube/ytpl": "^1.1.1",
|
|
125
|
-
"@distube/ytsr": "^1.1.
|
|
126
|
+
"@distube/ytsr": "^1.1.7",
|
|
126
127
|
"prism-media": "https://codeload.github.com/distubejs/prism-media/tar.gz/main#workaround.tar.gz",
|
|
127
128
|
"tiny-typed-emitter": "^2.1.0",
|
|
128
129
|
tslib: "^2.4.0"
|
|
129
130
|
},
|
|
130
131
|
devDependencies: {
|
|
131
|
-
"@babel/core": "^7.18.
|
|
132
|
-
"@babel/plugin-proposal-class-properties": "^7.
|
|
133
|
-
"@babel/plugin-proposal-object-rest-spread": "^7.18.
|
|
134
|
-
"@babel/preset-env": "^7.18.
|
|
135
|
-
"@babel/preset-typescript": "^7.
|
|
136
|
-
"@commitlint/cli": "^17.0.
|
|
137
|
-
"@commitlint/config-conventional": "^17.0.
|
|
132
|
+
"@babel/core": "^7.18.6",
|
|
133
|
+
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
134
|
+
"@babel/plugin-proposal-object-rest-spread": "^7.18.6",
|
|
135
|
+
"@babel/preset-env": "^7.18.6",
|
|
136
|
+
"@babel/preset-typescript": "^7.18.6",
|
|
137
|
+
"@commitlint/cli": "^17.0.3",
|
|
138
|
+
"@commitlint/config-conventional": "^17.0.3",
|
|
138
139
|
"@discordjs/voice": "dev",
|
|
139
140
|
"@distube/docgen": "distubejs/docgen",
|
|
140
|
-
"@types/jest": "^
|
|
141
|
-
"@types/node": "^
|
|
142
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
143
|
-
"@typescript-eslint/parser": "^5.
|
|
144
|
-
"babel-jest": "^28.1.
|
|
141
|
+
"@types/jest": "^28.1.5",
|
|
142
|
+
"@types/node": "^18.0.4",
|
|
143
|
+
"@typescript-eslint/eslint-plugin": "^5.30.6",
|
|
144
|
+
"@typescript-eslint/parser": "^5.30.6",
|
|
145
|
+
"babel-jest": "^28.1.3",
|
|
145
146
|
"discord.js": "dev",
|
|
146
|
-
eslint: "^8.
|
|
147
|
+
eslint: "^8.19.0",
|
|
147
148
|
"eslint-config-distube": "^1.6.4",
|
|
148
149
|
"eslint-config-prettier": "^8.5.0",
|
|
149
150
|
"eslint-plugin-deprecation": "^1.3.2",
|
|
150
|
-
"eslint-plugin-jsdoc": "^39.3.
|
|
151
|
+
"eslint-plugin-jsdoc": "^39.3.3",
|
|
151
152
|
husky: "^8.0.1",
|
|
152
|
-
jest: "^28.1.
|
|
153
|
+
jest: "^28.1.3",
|
|
153
154
|
"jsdoc-babel": "^0.5.0",
|
|
154
155
|
"nano-staged": "^0.8.0",
|
|
155
|
-
"npm-check-updates": "^
|
|
156
|
+
"npm-check-updates": "^15.3.0",
|
|
156
157
|
pinst: "^3.0.0",
|
|
157
|
-
prettier: "^2.
|
|
158
|
-
tsup: "^
|
|
159
|
-
typescript: "^4.
|
|
158
|
+
prettier: "^2.7.1",
|
|
159
|
+
tsup: "^6.1.3",
|
|
160
|
+
typescript: "^4.7.4"
|
|
160
161
|
},
|
|
161
162
|
peerDependencies: {
|
|
162
163
|
"@discordjs/opus": "*",
|
|
@@ -210,8 +211,9 @@ __export(src_exports, {
|
|
|
210
211
|
Queue: () => Queue,
|
|
211
212
|
QueueManager: () => QueueManager,
|
|
212
213
|
RepeatMode: () => RepeatMode,
|
|
213
|
-
|
|
214
|
+
SearchResultPlaylist: () => SearchResultPlaylist,
|
|
214
215
|
SearchResultType: () => SearchResultType,
|
|
216
|
+
SearchResultVideo: () => SearchResultVideo,
|
|
215
217
|
Song: () => Song,
|
|
216
218
|
StreamType: () => StreamType,
|
|
217
219
|
TaskQueue: () => TaskQueue,
|
|
@@ -221,9 +223,7 @@ __export(src_exports, {
|
|
|
221
223
|
default: () => DisTube,
|
|
222
224
|
defaultFilters: () => defaultFilters,
|
|
223
225
|
defaultOptions: () => defaultOptions,
|
|
224
|
-
entersState: () => entersState,
|
|
225
226
|
formatDuration: () => formatDuration,
|
|
226
|
-
getClientMember: () => getClientMember,
|
|
227
227
|
getResponseHeaders: () => getResponseHeaders,
|
|
228
228
|
isClientInstance: () => isClientInstance,
|
|
229
229
|
isGuildInstance: () => isGuildInstance,
|
|
@@ -307,7 +307,7 @@ var defaultOptions = {
|
|
|
307
307
|
// src/struct/DisTubeError.ts
|
|
308
308
|
var import_node_util = require("util");
|
|
309
309
|
var ERROR_MESSAGES = {
|
|
310
|
-
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 ${(0, import_node_util.inspect)(got)}`,
|
|
310
|
+
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 ${(0, import_node_util.inspect)(got)} (${typeof got})`,
|
|
311
311
|
NUMBER_COMPARE: (name, expected, value) => `'${name}' must be ${expected} ${value}`,
|
|
312
312
|
EMPTY_ARRAY: (name) => `'${name}' is an empty array`,
|
|
313
313
|
EMPTY_FILTERED_ARRAY: (name, type) => `There is no valid '${type}' in the '${name}' array`,
|
|
@@ -413,26 +413,33 @@ var Playlist = class {
|
|
|
413
413
|
__publicField(this, "url");
|
|
414
414
|
__publicField(this, "thumbnail");
|
|
415
415
|
const { member, properties, metadata } = options;
|
|
416
|
-
if (typeof playlist !== "object") {
|
|
417
|
-
throw new DisTubeError("INVALID_TYPE", ["Array<Song>", "
|
|
416
|
+
if (typeof playlist !== "object" || !Array.isArray(playlist) && ["source", "songs"].some((key) => !(key in playlist))) {
|
|
417
|
+
throw new DisTubeError("INVALID_TYPE", ["Array<Song>", "PlaylistInfo"], playlist, "playlist");
|
|
418
418
|
}
|
|
419
419
|
if (typeof properties !== "undefined" && !isRecord(properties)) {
|
|
420
420
|
throw new DisTubeError("INVALID_TYPE", "object", properties, "properties");
|
|
421
421
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
422
|
+
if (Array.isArray(playlist)) {
|
|
423
|
+
this.source = "youtube";
|
|
424
|
+
if (!playlist.length)
|
|
425
|
+
throw new DisTubeError("EMPTY_PLAYLIST");
|
|
426
|
+
this.songs = playlist;
|
|
427
|
+
this.name = this.songs[0].name ? `${this.songs[0].name} and ${this.songs.length - 1} more songs.` : `${this.songs.length} songs playlist`;
|
|
428
|
+
this.thumbnail = this.songs[0].thumbnail;
|
|
429
|
+
} else {
|
|
430
|
+
this.source = (playlist.source || "youtube").toLowerCase();
|
|
431
|
+
if (!Array.isArray(playlist.songs) || !playlist.songs.length)
|
|
432
|
+
throw new DisTubeError("EMPTY_PLAYLIST");
|
|
433
|
+
this.songs = playlist.songs;
|
|
434
|
+
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`);
|
|
435
|
+
this.url = playlist.url || playlist.webpage_url;
|
|
436
|
+
this.thumbnail = playlist.thumbnail || this.songs[0].thumbnail;
|
|
427
437
|
}
|
|
428
438
|
this.songs.map((s) => s.constructor.name === "Song" && (s.playlist = this));
|
|
429
|
-
this.member = member || info.member || void 0;
|
|
430
|
-
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`);
|
|
431
|
-
this.url = info.url || info.webpage_url;
|
|
432
|
-
this.thumbnail = info.thumbnail?.url || info.thumbnail || this.songs[0].thumbnail;
|
|
433
439
|
if (properties)
|
|
434
440
|
for (const [key, value] of Object.entries(properties))
|
|
435
441
|
this[key] = value;
|
|
442
|
+
this.member = member;
|
|
436
443
|
this.metadata = metadata;
|
|
437
444
|
}
|
|
438
445
|
get duration() {
|
|
@@ -466,41 +473,64 @@ _metadata = new WeakMap();
|
|
|
466
473
|
_member = new WeakMap();
|
|
467
474
|
|
|
468
475
|
// src/struct/SearchResult.ts
|
|
469
|
-
var
|
|
476
|
+
var ISearchResult = class {
|
|
470
477
|
constructor(info) {
|
|
471
478
|
__publicField(this, "source");
|
|
472
|
-
__publicField(this, "type");
|
|
473
479
|
__publicField(this, "id");
|
|
474
480
|
__publicField(this, "name");
|
|
475
481
|
__publicField(this, "url");
|
|
476
|
-
__publicField(this, "views");
|
|
477
|
-
__publicField(this, "isLive");
|
|
478
|
-
__publicField(this, "duration");
|
|
479
|
-
__publicField(this, "formattedDuration");
|
|
480
|
-
__publicField(this, "thumbnail");
|
|
481
482
|
__publicField(this, "uploader");
|
|
482
483
|
this.source = "youtube";
|
|
483
|
-
this.type = info.type === "video" ? "video" /* VIDEO */ : "playlist" /* PLAYLIST */;
|
|
484
484
|
this.id = info.id;
|
|
485
485
|
this.name = info.name;
|
|
486
486
|
this.url = info.url;
|
|
487
|
-
if (this.type === "video" /* VIDEO */) {
|
|
488
|
-
info = info;
|
|
489
|
-
this.views = info.views;
|
|
490
|
-
this.isLive = info.isLive;
|
|
491
|
-
this.duration = this.isLive ? 0 : toSecond(info.duration);
|
|
492
|
-
this.formattedDuration = this.isLive ? "Live" : formatDuration(this.duration);
|
|
493
|
-
this.thumbnail = info.thumbnail;
|
|
494
|
-
} else if (this.type !== "playlist") {
|
|
495
|
-
throw new DisTubeError("INVALID_TYPE", ["video", "playlist"], this.type, "SearchResult.type");
|
|
496
|
-
}
|
|
497
487
|
this.uploader = {
|
|
498
|
-
name:
|
|
499
|
-
url:
|
|
488
|
+
name: void 0,
|
|
489
|
+
url: void 0
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
__name(ISearchResult, "ISearchResult");
|
|
494
|
+
var SearchResultVideo = class extends ISearchResult {
|
|
495
|
+
constructor(info) {
|
|
496
|
+
super(info);
|
|
497
|
+
__publicField(this, "type");
|
|
498
|
+
__publicField(this, "views");
|
|
499
|
+
__publicField(this, "isLive");
|
|
500
|
+
__publicField(this, "duration");
|
|
501
|
+
__publicField(this, "formattedDuration");
|
|
502
|
+
__publicField(this, "thumbnail");
|
|
503
|
+
if (info.type !== "video")
|
|
504
|
+
throw new DisTubeError("INVALID_TYPE", "video", info.type, "type");
|
|
505
|
+
this.type = "video" /* VIDEO */;
|
|
506
|
+
this.views = info.views;
|
|
507
|
+
this.isLive = info.isLive;
|
|
508
|
+
this.duration = this.isLive ? 0 : toSecond(info.duration);
|
|
509
|
+
this.formattedDuration = this.isLive ? "Live" : formatDuration(this.duration);
|
|
510
|
+
this.thumbnail = info.thumbnail;
|
|
511
|
+
this.uploader = {
|
|
512
|
+
name: info.author?.name,
|
|
513
|
+
url: info.author?.url
|
|
500
514
|
};
|
|
501
515
|
}
|
|
502
516
|
};
|
|
503
|
-
__name(
|
|
517
|
+
__name(SearchResultVideo, "SearchResultVideo");
|
|
518
|
+
var SearchResultPlaylist = class extends ISearchResult {
|
|
519
|
+
constructor(info) {
|
|
520
|
+
super(info);
|
|
521
|
+
__publicField(this, "type");
|
|
522
|
+
__publicField(this, "length");
|
|
523
|
+
if (info.type !== "playlist")
|
|
524
|
+
throw new DisTubeError("INVALID_TYPE", "playlist", info.type, "type");
|
|
525
|
+
this.type = "playlist" /* PLAYLIST */;
|
|
526
|
+
this.length = info.length;
|
|
527
|
+
this.uploader = {
|
|
528
|
+
name: info.owner?.name,
|
|
529
|
+
url: info.owner?.url
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
__name(SearchResultPlaylist, "SearchResultPlaylist");
|
|
504
534
|
|
|
505
535
|
// src/struct/Song.ts
|
|
506
536
|
var _metadata2, _member2, _playlist;
|
|
@@ -640,114 +670,6 @@ _metadata2 = new WeakMap();
|
|
|
640
670
|
_member2 = new WeakMap();
|
|
641
671
|
_playlist = new WeakMap();
|
|
642
672
|
|
|
643
|
-
// src/core/DisTubeOptions.ts
|
|
644
|
-
var _validateOptions, validateOptions_fn;
|
|
645
|
-
var Options = class {
|
|
646
|
-
constructor(options) {
|
|
647
|
-
__privateAdd(this, _validateOptions);
|
|
648
|
-
__publicField(this, "plugins");
|
|
649
|
-
__publicField(this, "emitNewSongOnly");
|
|
650
|
-
__publicField(this, "leaveOnFinish");
|
|
651
|
-
__publicField(this, "leaveOnStop");
|
|
652
|
-
__publicField(this, "leaveOnEmpty");
|
|
653
|
-
__publicField(this, "emptyCooldown");
|
|
654
|
-
__publicField(this, "savePreviousSongs");
|
|
655
|
-
__publicField(this, "searchSongs");
|
|
656
|
-
__publicField(this, "searchCooldown");
|
|
657
|
-
__publicField(this, "youtubeCookie");
|
|
658
|
-
__publicField(this, "youtubeIdentityToken");
|
|
659
|
-
__publicField(this, "customFilters");
|
|
660
|
-
__publicField(this, "ytdlOptions");
|
|
661
|
-
__publicField(this, "nsfw");
|
|
662
|
-
__publicField(this, "emitAddSongWhenCreatingQueue");
|
|
663
|
-
__publicField(this, "emitAddListWhenCreatingQueue");
|
|
664
|
-
__publicField(this, "joinNewVoiceChannel");
|
|
665
|
-
__publicField(this, "streamType");
|
|
666
|
-
if (typeof options !== "object" || Array.isArray(options)) {
|
|
667
|
-
throw new DisTubeError("INVALID_TYPE", "object", options, "DisTubeOptions");
|
|
668
|
-
}
|
|
669
|
-
const opts = { ...defaultOptions, ...options };
|
|
670
|
-
this.plugins = opts.plugins;
|
|
671
|
-
this.emitNewSongOnly = opts.emitNewSongOnly;
|
|
672
|
-
this.leaveOnEmpty = opts.leaveOnEmpty;
|
|
673
|
-
this.leaveOnFinish = opts.leaveOnFinish;
|
|
674
|
-
this.leaveOnStop = opts.leaveOnStop;
|
|
675
|
-
this.savePreviousSongs = opts.savePreviousSongs;
|
|
676
|
-
this.searchSongs = opts.searchSongs;
|
|
677
|
-
this.youtubeCookie = opts.youtubeCookie;
|
|
678
|
-
this.youtubeIdentityToken = opts.youtubeIdentityToken;
|
|
679
|
-
this.customFilters = opts.customFilters;
|
|
680
|
-
this.ytdlOptions = opts.ytdlOptions;
|
|
681
|
-
this.searchCooldown = opts.searchCooldown;
|
|
682
|
-
this.emptyCooldown = opts.emptyCooldown;
|
|
683
|
-
this.nsfw = opts.nsfw;
|
|
684
|
-
this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;
|
|
685
|
-
this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;
|
|
686
|
-
this.joinNewVoiceChannel = opts.joinNewVoiceChannel;
|
|
687
|
-
this.streamType = opts.streamType;
|
|
688
|
-
checkInvalidKey(opts, this, "DisTubeOptions");
|
|
689
|
-
__privateMethod(this, _validateOptions, validateOptions_fn).call(this);
|
|
690
|
-
}
|
|
691
|
-
};
|
|
692
|
-
__name(Options, "Options");
|
|
693
|
-
_validateOptions = new WeakSet();
|
|
694
|
-
validateOptions_fn = /* @__PURE__ */ __name(function(options = this) {
|
|
695
|
-
if (typeof options.emitNewSongOnly !== "boolean") {
|
|
696
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitNewSongOnly, "DisTubeOptions.emitNewSongOnly");
|
|
697
|
-
}
|
|
698
|
-
if (typeof options.leaveOnEmpty !== "boolean") {
|
|
699
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnEmpty, "DisTubeOptions.leaveOnEmpty");
|
|
700
|
-
}
|
|
701
|
-
if (typeof options.leaveOnFinish !== "boolean") {
|
|
702
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnFinish, "DisTubeOptions.leaveOnFinish");
|
|
703
|
-
}
|
|
704
|
-
if (typeof options.leaveOnStop !== "boolean") {
|
|
705
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnStop, "DisTubeOptions.leaveOnStop");
|
|
706
|
-
}
|
|
707
|
-
if (typeof options.savePreviousSongs !== "boolean") {
|
|
708
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.savePreviousSongs, "DisTubeOptions.savePreviousSongs");
|
|
709
|
-
}
|
|
710
|
-
if (typeof options.joinNewVoiceChannel !== "boolean") {
|
|
711
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.joinNewVoiceChannel, "DisTubeOptions.joinNewVoiceChannel");
|
|
712
|
-
}
|
|
713
|
-
if (typeof options.youtubeCookie !== "undefined" && typeof options.youtubeCookie !== "string") {
|
|
714
|
-
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeCookie, "DisTubeOptions.youtubeCookie");
|
|
715
|
-
}
|
|
716
|
-
if (typeof options.youtubeIdentityToken !== "undefined" && typeof options.youtubeIdentityToken !== "string") {
|
|
717
|
-
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeIdentityToken, "DisTubeOptions.youtubeIdentityToken");
|
|
718
|
-
}
|
|
719
|
-
if (typeof options.customFilters !== "undefined" && typeof options.customFilters !== "object" || Array.isArray(options.customFilters)) {
|
|
720
|
-
throw new DisTubeError("INVALID_TYPE", "object", options.customFilters, "DisTubeOptions.customFilters");
|
|
721
|
-
}
|
|
722
|
-
if (typeof options.ytdlOptions !== "object" || Array.isArray(options.ytdlOptions)) {
|
|
723
|
-
throw new DisTubeError("INVALID_TYPE", "object", options.ytdlOptions, "DisTubeOptions.ytdlOptions");
|
|
724
|
-
}
|
|
725
|
-
if (typeof options.searchCooldown !== "number" || isNaN(options.searchCooldown)) {
|
|
726
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.searchCooldown, "DisTubeOptions.searchCooldown");
|
|
727
|
-
}
|
|
728
|
-
if (typeof options.emptyCooldown !== "number" || isNaN(options.emptyCooldown)) {
|
|
729
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.emptyCooldown, "DisTubeOptions.emptyCooldown");
|
|
730
|
-
}
|
|
731
|
-
if (typeof options.searchSongs !== "number" || isNaN(options.searchSongs)) {
|
|
732
|
-
throw new DisTubeError("INVALID_TYPE", "number", options.searchSongs, "DisTubeOptions.searchSongs");
|
|
733
|
-
}
|
|
734
|
-
if (!Array.isArray(options.plugins)) {
|
|
735
|
-
throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", options.plugins, "DisTubeOptions.plugins");
|
|
736
|
-
}
|
|
737
|
-
if (typeof options.nsfw !== "boolean") {
|
|
738
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.nsfw, "DisTubeOptions.nsfw");
|
|
739
|
-
}
|
|
740
|
-
if (typeof options.emitAddSongWhenCreatingQueue !== "boolean") {
|
|
741
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddSongWhenCreatingQueue, "DisTubeOptions.emitAddSongWhenCreatingQueue");
|
|
742
|
-
}
|
|
743
|
-
if (typeof options.emitAddListWhenCreatingQueue !== "boolean") {
|
|
744
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddListWhenCreatingQueue, "DisTubeOptions.emitAddListWhenCreatingQueue");
|
|
745
|
-
}
|
|
746
|
-
if (typeof options.streamType !== "number" || isNaN(options.streamType) || !StreamType[options.streamType]) {
|
|
747
|
-
throw new DisTubeError("INVALID_TYPE", "StreamType", options.streamType, "DisTubeOptions.streamType");
|
|
748
|
-
}
|
|
749
|
-
}, "#validateOptions");
|
|
750
|
-
|
|
751
673
|
// src/core/DisTubeBase.ts
|
|
752
674
|
var DisTubeBase = class {
|
|
753
675
|
constructor(distube) {
|
|
@@ -778,77 +700,194 @@ var DisTubeBase = class {
|
|
|
778
700
|
};
|
|
779
701
|
__name(DisTubeBase, "DisTubeBase");
|
|
780
702
|
|
|
781
|
-
// src/core/
|
|
782
|
-
var
|
|
703
|
+
// src/core/DisTubeVoice.ts
|
|
704
|
+
var import_tiny_typed_emitter = require("tiny-typed-emitter");
|
|
783
705
|
var import_voice = require("@discordjs/voice");
|
|
784
|
-
var
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
__publicField(this, "
|
|
794
|
-
__publicField(this, "
|
|
795
|
-
__publicField(this, "
|
|
796
|
-
this
|
|
797
|
-
this
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
"
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
706
|
+
var _channel, _volume, _br, br_fn, _join, join_fn;
|
|
707
|
+
var DisTubeVoice = class extends import_tiny_typed_emitter.TypedEmitter {
|
|
708
|
+
constructor(voiceManager, channel) {
|
|
709
|
+
super();
|
|
710
|
+
__privateAdd(this, _br);
|
|
711
|
+
__privateAdd(this, _join);
|
|
712
|
+
__publicField(this, "id");
|
|
713
|
+
__publicField(this, "voices");
|
|
714
|
+
__publicField(this, "audioPlayer");
|
|
715
|
+
__publicField(this, "connection");
|
|
716
|
+
__publicField(this, "audioResource");
|
|
717
|
+
__publicField(this, "emittedError");
|
|
718
|
+
__publicField(this, "isDisconnected", false);
|
|
719
|
+
__privateAdd(this, _channel, void 0);
|
|
720
|
+
__privateAdd(this, _volume, 100);
|
|
721
|
+
this.voices = voiceManager;
|
|
722
|
+
this.id = channel.guildId;
|
|
723
|
+
this.channel = channel;
|
|
724
|
+
this.voices.add(this.id, this);
|
|
725
|
+
this.audioPlayer = (0, import_voice.createAudioPlayer)().on(import_voice.AudioPlayerStatus.Idle, (oldState) => {
|
|
726
|
+
if (oldState.status !== import_voice.AudioPlayerStatus.Idle) {
|
|
727
|
+
delete this.audioResource;
|
|
728
|
+
this.emit("finish");
|
|
729
|
+
}
|
|
730
|
+
}).on(import_voice.AudioPlayerStatus.Playing, () => __privateMethod(this, _br, br_fn).call(this)).on("error", (error) => {
|
|
731
|
+
if (this.emittedError)
|
|
732
|
+
return;
|
|
733
|
+
this.emittedError = true;
|
|
734
|
+
this.emit("error", error);
|
|
735
|
+
});
|
|
736
|
+
this.connection.on(import_voice.VoiceConnectionStatus.Disconnected, (_, newState) => {
|
|
737
|
+
if (newState.reason === import_voice.VoiceConnectionDisconnectReason.Manual) {
|
|
738
|
+
this.leave();
|
|
739
|
+
} else if (newState.reason === import_voice.VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
|
|
740
|
+
(0, import_voice.entersState)(this.connection, import_voice.VoiceConnectionStatus.Connecting, 5e3).catch(() => {
|
|
741
|
+
if (![import_voice.VoiceConnectionStatus.Ready, import_voice.VoiceConnectionStatus.Connecting].includes(this.connection.state.status)) {
|
|
742
|
+
this.leave();
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
} else if (this.connection.rejoinAttempts < 5) {
|
|
746
|
+
setTimeout(() => {
|
|
747
|
+
this.connection.rejoin();
|
|
748
|
+
}, (this.connection.rejoinAttempts + 1) * 5e3).unref();
|
|
749
|
+
} else if (this.connection.state.status !== import_voice.VoiceConnectionStatus.Destroyed) {
|
|
750
|
+
this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
|
|
751
|
+
}
|
|
752
|
+
}).on(import_voice.VoiceConnectionStatus.Destroyed, () => {
|
|
753
|
+
this.leave();
|
|
754
|
+
}).on("error", () => void 0);
|
|
755
|
+
this.connection.subscribe(this.audioPlayer);
|
|
829
756
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
throw new DisTubeError("UNAVAILABLE_VIDEO");
|
|
833
|
-
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
834
|
-
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
835
|
-
}
|
|
836
|
-
const bestFormat = chooseBestVideoFormat(formats, options.isLive);
|
|
837
|
-
if (!bestFormat)
|
|
838
|
-
throw new DisTubeError("UNPLAYABLE_FORMATS");
|
|
839
|
-
return new DisTubeStream(bestFormat.url, options);
|
|
757
|
+
get channel() {
|
|
758
|
+
return __privateGet(this, _channel);
|
|
840
759
|
}
|
|
841
|
-
|
|
842
|
-
if (!
|
|
843
|
-
throw new DisTubeError("INVALID_TYPE", "
|
|
760
|
+
set channel(channel) {
|
|
761
|
+
if (!isSupportedVoiceChannel(channel)) {
|
|
762
|
+
throw new DisTubeError("INVALID_TYPE", "BaseGuildVoiceChannel", channel, "DisTubeVoice#channel");
|
|
844
763
|
}
|
|
845
|
-
if (
|
|
846
|
-
throw new DisTubeError("
|
|
764
|
+
if (channel.guildId !== this.id)
|
|
765
|
+
throw new DisTubeError("VOICE_DIFFERENT_GUILD");
|
|
766
|
+
if (channel.client.user?.id !== this.voices.client.user?.id)
|
|
767
|
+
throw new DisTubeError("VOICE_DIFFERENT_CLIENT");
|
|
768
|
+
if (channel.id === __privateGet(this, _channel)?.id)
|
|
769
|
+
return;
|
|
770
|
+
if (!channel.joinable) {
|
|
771
|
+
if (channel.full)
|
|
772
|
+
throw new DisTubeError("VOICE_FULL");
|
|
773
|
+
else
|
|
774
|
+
throw new DisTubeError("VOICE_MISSING_PERMS");
|
|
847
775
|
}
|
|
848
|
-
|
|
776
|
+
this.connection = __privateMethod(this, _join, join_fn).call(this, channel);
|
|
777
|
+
__privateSet(this, _channel, channel);
|
|
778
|
+
__privateMethod(this, _br, br_fn).call(this);
|
|
779
|
+
}
|
|
780
|
+
async join(channel) {
|
|
781
|
+
const TIMEOUT = 3e4;
|
|
782
|
+
if (channel)
|
|
783
|
+
this.channel = channel;
|
|
784
|
+
try {
|
|
785
|
+
await (0, import_voice.entersState)(this.connection, import_voice.VoiceConnectionStatus.Ready, TIMEOUT);
|
|
786
|
+
} catch {
|
|
787
|
+
if (this.connection.state.status === import_voice.VoiceConnectionStatus.Ready)
|
|
788
|
+
return this;
|
|
789
|
+
if (this.connection.state.status !== import_voice.VoiceConnectionStatus.Destroyed)
|
|
790
|
+
this.connection.destroy();
|
|
791
|
+
this.voices.remove(this.id);
|
|
792
|
+
throw new DisTubeError("VOICE_CONNECT_FAILED", TIMEOUT / 1e3);
|
|
793
|
+
}
|
|
794
|
+
return this;
|
|
795
|
+
}
|
|
796
|
+
leave(error) {
|
|
797
|
+
this.stop(true);
|
|
798
|
+
if (!this.isDisconnected) {
|
|
799
|
+
this.emit("disconnect", error);
|
|
800
|
+
this.isDisconnected = true;
|
|
801
|
+
}
|
|
802
|
+
if (this.connection.state.status !== import_voice.VoiceConnectionStatus.Destroyed)
|
|
803
|
+
this.connection.destroy();
|
|
804
|
+
this.voices.remove(this.id);
|
|
805
|
+
}
|
|
806
|
+
stop(force = false) {
|
|
807
|
+
this.audioPlayer.stop(force);
|
|
808
|
+
}
|
|
809
|
+
play(stream) {
|
|
810
|
+
this.emittedError = false;
|
|
811
|
+
stream.stream.on("error", (error) => {
|
|
812
|
+
if (this.emittedError || error.code === "ERR_STREAM_PREMATURE_CLOSE")
|
|
813
|
+
return;
|
|
814
|
+
this.emittedError = true;
|
|
815
|
+
this.emit("error", error);
|
|
816
|
+
});
|
|
817
|
+
this.audioResource = (0, import_voice.createAudioResource)(stream.stream, {
|
|
818
|
+
inputType: stream.type,
|
|
819
|
+
inlineVolume: true
|
|
820
|
+
});
|
|
821
|
+
this.volume = __privateGet(this, _volume);
|
|
822
|
+
this.audioPlayer.play(this.audioResource);
|
|
823
|
+
}
|
|
824
|
+
set volume(volume) {
|
|
825
|
+
if (typeof volume !== "number" || isNaN(volume)) {
|
|
826
|
+
throw new DisTubeError("INVALID_TYPE", "number", volume, "volume");
|
|
827
|
+
}
|
|
828
|
+
if (volume < 0) {
|
|
829
|
+
throw new DisTubeError("NUMBER_COMPARE", "Volume", "bigger or equal to", 0);
|
|
830
|
+
}
|
|
831
|
+
__privateSet(this, _volume, volume);
|
|
832
|
+
this.audioResource?.volume?.setVolume(Math.pow(__privateGet(this, _volume) / 100, 0.5 / Math.log10(2)));
|
|
833
|
+
}
|
|
834
|
+
get volume() {
|
|
835
|
+
return __privateGet(this, _volume);
|
|
836
|
+
}
|
|
837
|
+
get playbackDuration() {
|
|
838
|
+
return (this.audioResource?.playbackDuration ?? 0) / 1e3;
|
|
839
|
+
}
|
|
840
|
+
pause() {
|
|
841
|
+
this.audioPlayer.pause();
|
|
842
|
+
}
|
|
843
|
+
unpause() {
|
|
844
|
+
this.audioPlayer.unpause();
|
|
845
|
+
}
|
|
846
|
+
get selfDeaf() {
|
|
847
|
+
return this.connection.joinConfig.selfDeaf;
|
|
848
|
+
}
|
|
849
|
+
get selfMute() {
|
|
850
|
+
return this.connection.joinConfig.selfMute;
|
|
851
|
+
}
|
|
852
|
+
setSelfDeaf(selfDeaf) {
|
|
853
|
+
if (typeof selfDeaf !== "boolean") {
|
|
854
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", selfDeaf, "selfDeaf");
|
|
855
|
+
}
|
|
856
|
+
return this.connection.rejoin({
|
|
857
|
+
...this.connection.joinConfig,
|
|
858
|
+
selfDeaf
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
setSelfMute(selfMute) {
|
|
862
|
+
if (typeof selfMute !== "boolean") {
|
|
863
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", selfMute, "selfMute");
|
|
864
|
+
}
|
|
865
|
+
return this.connection.rejoin({
|
|
866
|
+
...this.connection.joinConfig,
|
|
867
|
+
selfMute
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
get voiceState() {
|
|
871
|
+
return this.channel?.guild?.members?.me?.voice;
|
|
849
872
|
}
|
|
850
873
|
};
|
|
851
|
-
__name(
|
|
874
|
+
__name(DisTubeVoice, "DisTubeVoice");
|
|
875
|
+
_channel = new WeakMap();
|
|
876
|
+
_volume = new WeakMap();
|
|
877
|
+
_br = new WeakSet();
|
|
878
|
+
br_fn = /* @__PURE__ */ __name(function() {
|
|
879
|
+
if (this.audioResource?.encoder?.encoder)
|
|
880
|
+
this.audioResource.encoder.setBitrate(this.channel.bitrate);
|
|
881
|
+
}, "#br");
|
|
882
|
+
_join = new WeakSet();
|
|
883
|
+
join_fn = /* @__PURE__ */ __name(function(channel) {
|
|
884
|
+
return (0, import_voice.joinVoiceChannel)({
|
|
885
|
+
channelId: channel.id,
|
|
886
|
+
guildId: this.id,
|
|
887
|
+
adapterCreator: channel.guild.voiceAdapterCreator,
|
|
888
|
+
group: channel.client.user?.id
|
|
889
|
+
});
|
|
890
|
+
}, "#join");
|
|
852
891
|
|
|
853
892
|
// src/core/manager/BaseManager.ts
|
|
854
893
|
var import_discord = require("discord.js");
|
|
@@ -884,6 +923,123 @@ var GuildIdManager = class extends BaseManager {
|
|
|
884
923
|
};
|
|
885
924
|
__name(GuildIdManager, "GuildIdManager");
|
|
886
925
|
|
|
926
|
+
// src/core/manager/DisTubeVoiceManager.ts
|
|
927
|
+
var import_voice2 = require("@discordjs/voice");
|
|
928
|
+
var DisTubeVoiceManager = class extends GuildIdManager {
|
|
929
|
+
create(channel) {
|
|
930
|
+
const existing = this.get(channel.guildId);
|
|
931
|
+
if (existing) {
|
|
932
|
+
existing.channel = channel;
|
|
933
|
+
return existing;
|
|
934
|
+
}
|
|
935
|
+
return new DisTubeVoice(this, channel);
|
|
936
|
+
}
|
|
937
|
+
join(channel) {
|
|
938
|
+
const existing = this.get(channel.guildId);
|
|
939
|
+
if (existing)
|
|
940
|
+
return existing.join(channel);
|
|
941
|
+
return this.create(channel).join();
|
|
942
|
+
}
|
|
943
|
+
leave(guild) {
|
|
944
|
+
const voice = this.get(guild);
|
|
945
|
+
if (voice) {
|
|
946
|
+
voice.leave();
|
|
947
|
+
} else {
|
|
948
|
+
const connection = (0, import_voice2.getVoiceConnection)(resolveGuildId(guild), this.client.user?.id) ?? (0, import_voice2.getVoiceConnection)(resolveGuildId(guild));
|
|
949
|
+
if (connection && connection.state.status !== import_voice2.VoiceConnectionStatus.Destroyed) {
|
|
950
|
+
connection.destroy();
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
__name(DisTubeVoiceManager, "DisTubeVoiceManager");
|
|
956
|
+
|
|
957
|
+
// src/core/manager/FilterManager.ts
|
|
958
|
+
var _validate, validate_fn, _resolveName, resolveName_fn, _resolveValue, resolveValue_fn, _apply, apply_fn;
|
|
959
|
+
var FilterManager = class extends BaseManager {
|
|
960
|
+
constructor(queue) {
|
|
961
|
+
super(queue.distube);
|
|
962
|
+
__privateAdd(this, _validate);
|
|
963
|
+
__privateAdd(this, _resolveName);
|
|
964
|
+
__privateAdd(this, _resolveValue);
|
|
965
|
+
__privateAdd(this, _apply);
|
|
966
|
+
__publicField(this, "queue");
|
|
967
|
+
this.queue = queue;
|
|
968
|
+
}
|
|
969
|
+
add(filterOrFilters, override = false) {
|
|
970
|
+
if (Array.isArray(filterOrFilters)) {
|
|
971
|
+
const resolvedFilters = filterOrFilters.map((f) => __privateMethod(this, _validate, validate_fn).call(this, f));
|
|
972
|
+
const newFilters = resolvedFilters.reduceRight((unique, o) => {
|
|
973
|
+
if (!unique.some((obj) => obj === o && obj.name === o) && !unique.some((obj) => obj !== o.name && obj.name !== o.name)) {
|
|
974
|
+
if (!this.has(o))
|
|
975
|
+
unique.push(o);
|
|
976
|
+
if (this.has(o) && override) {
|
|
977
|
+
this.remove(o);
|
|
978
|
+
unique.push(o);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
return unique;
|
|
982
|
+
}, []).reverse();
|
|
983
|
+
return this.set([...this.collection.values(), ...newFilters]);
|
|
984
|
+
}
|
|
985
|
+
return this.set([...this.collection.values(), filterOrFilters]);
|
|
986
|
+
}
|
|
987
|
+
clear() {
|
|
988
|
+
return this.set([]);
|
|
989
|
+
}
|
|
990
|
+
set(filters) {
|
|
991
|
+
this.collection.clear();
|
|
992
|
+
for (const filter of filters) {
|
|
993
|
+
const resolved = __privateMethod(this, _validate, validate_fn).call(this, filter);
|
|
994
|
+
this.collection.set(__privateMethod(this, _resolveName, resolveName_fn).call(this, resolved), resolved);
|
|
995
|
+
}
|
|
996
|
+
__privateMethod(this, _apply, apply_fn).call(this);
|
|
997
|
+
return this;
|
|
998
|
+
}
|
|
999
|
+
remove(filterOrFilters) {
|
|
1000
|
+
const remove = /* @__PURE__ */ __name((f) => this.collection.delete(__privateMethod(this, _resolveName, resolveName_fn).call(this, __privateMethod(this, _validate, validate_fn).call(this, f))), "remove");
|
|
1001
|
+
if (Array.isArray(filterOrFilters))
|
|
1002
|
+
filterOrFilters.map(remove);
|
|
1003
|
+
else
|
|
1004
|
+
remove(filterOrFilters);
|
|
1005
|
+
__privateMethod(this, _apply, apply_fn).call(this);
|
|
1006
|
+
return this;
|
|
1007
|
+
}
|
|
1008
|
+
has(filter) {
|
|
1009
|
+
return this.collection.has(__privateMethod(this, _resolveName, resolveName_fn).call(this, filter));
|
|
1010
|
+
}
|
|
1011
|
+
get names() {
|
|
1012
|
+
return this.collection.map((f) => __privateMethod(this, _resolveName, resolveName_fn).call(this, f));
|
|
1013
|
+
}
|
|
1014
|
+
get values() {
|
|
1015
|
+
return this.collection.map((f) => __privateMethod(this, _resolveValue, resolveValue_fn).call(this, f));
|
|
1016
|
+
}
|
|
1017
|
+
toString() {
|
|
1018
|
+
return this.names.toString();
|
|
1019
|
+
}
|
|
1020
|
+
};
|
|
1021
|
+
__name(FilterManager, "FilterManager");
|
|
1022
|
+
_validate = new WeakSet();
|
|
1023
|
+
validate_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1024
|
+
if (typeof filter === "string" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter) || typeof filter === "object" && typeof filter.name === "string" && typeof filter.value === "string") {
|
|
1025
|
+
return filter;
|
|
1026
|
+
}
|
|
1027
|
+
throw new DisTubeError("INVALID_TYPE", "FilterResolvable", filter, "filter");
|
|
1028
|
+
}, "#validate");
|
|
1029
|
+
_resolveName = new WeakSet();
|
|
1030
|
+
resolveName_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1031
|
+
return typeof filter === "string" ? filter : filter.name;
|
|
1032
|
+
}, "#resolveName");
|
|
1033
|
+
_resolveValue = new WeakSet();
|
|
1034
|
+
resolveValue_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1035
|
+
return typeof filter === "string" ? this.distube.filters[filter] : filter.value;
|
|
1036
|
+
}, "#resolveValue");
|
|
1037
|
+
_apply = new WeakSet();
|
|
1038
|
+
apply_fn = /* @__PURE__ */ __name(function() {
|
|
1039
|
+
this.queue.beginTime = this.queue.currentTime;
|
|
1040
|
+
this.queues.playSong(this.queue);
|
|
1041
|
+
}, "#apply");
|
|
1042
|
+
|
|
887
1043
|
// src/core/manager/QueueManager.ts
|
|
888
1044
|
var _voiceEventHandler, voiceEventHandler_fn, _handleSongFinish, handleSongFinish_fn, _handlePlayingError, handlePlayingError_fn, _emitPlaySong, emitPlaySong_fn;
|
|
889
1045
|
var QueueManager = class extends GuildIdManager {
|
|
@@ -1000,367 +1156,61 @@ handleSongFinish_fn = /* @__PURE__ */ __name(async function(queue) {
|
|
|
1000
1156
|
}
|
|
1001
1157
|
}
|
|
1002
1158
|
if (queue.songs.length <= 1) {
|
|
1003
|
-
if (this.options.leaveOnFinish)
|
|
1004
|
-
queue.voice.leave();
|
|
1005
|
-
if (!queue.autoplay)
|
|
1006
|
-
this.emit("finish", queue);
|
|
1007
|
-
queue.remove();
|
|
1008
|
-
return;
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
const emitPlaySong = __privateMethod(this, _emitPlaySong, emitPlaySong_fn).call(this, queue);
|
|
1012
|
-
if (!queue._prev && (queue.repeatMode !== 1 /* SONG */ || queue._next)) {
|
|
1013
|
-
const prev = queue.songs.shift();
|
|
1014
|
-
delete prev.formats;
|
|
1015
|
-
delete prev.streamURL;
|
|
1016
|
-
if (this.options.savePreviousSongs)
|
|
1017
|
-
queue.previousSongs.push(prev);
|
|
1018
|
-
else
|
|
1019
|
-
queue.previousSongs.push({ id: prev.id });
|
|
1020
|
-
}
|
|
1021
|
-
queue._next = queue._prev = false;
|
|
1022
|
-
queue.beginTime = 0;
|
|
1023
|
-
const err = await this.playSong(queue);
|
|
1024
|
-
if (!err && emitPlaySong)
|
|
1025
|
-
this.emit("playSong", queue, queue.songs[0]);
|
|
1026
|
-
} finally {
|
|
1027
|
-
queue._taskQueue.resolve();
|
|
1028
|
-
}
|
|
1029
|
-
}, "#handleSongFinish");
|
|
1030
|
-
_handlePlayingError = new WeakSet();
|
|
1031
|
-
handlePlayingError_fn = /* @__PURE__ */ __name(function(queue, error) {
|
|
1032
|
-
const song = queue.songs.shift();
|
|
1033
|
-
try {
|
|
1034
|
-
error.name = "PlayingError";
|
|
1035
|
-
error.message = `${error.message}
|
|
1036
|
-
Id: ${song.id}
|
|
1037
|
-
Name: ${song.name}`;
|
|
1038
|
-
} catch {
|
|
1039
|
-
}
|
|
1040
|
-
this.emitError(error, queue.textChannel);
|
|
1041
|
-
if (queue.songs.length > 0) {
|
|
1042
|
-
this.playSong(queue).then((e) => {
|
|
1043
|
-
if (!e)
|
|
1044
|
-
this.emit("playSong", queue, queue.songs[0]);
|
|
1045
|
-
});
|
|
1046
|
-
} else {
|
|
1047
|
-
queue.stop();
|
|
1048
|
-
}
|
|
1049
|
-
}, "#handlePlayingError");
|
|
1050
|
-
_emitPlaySong = new WeakSet();
|
|
1051
|
-
emitPlaySong_fn = /* @__PURE__ */ __name(function(queue) {
|
|
1052
|
-
return !this.options.emitNewSongOnly || queue.repeatMode === 1 /* SONG */ && queue._next || queue.repeatMode !== 1 /* SONG */ && queue.songs[0]?.id !== queue.songs[1]?.id;
|
|
1053
|
-
}, "#emitPlaySong");
|
|
1054
|
-
|
|
1055
|
-
// src/core/manager/FilterManager.ts
|
|
1056
|
-
var _validate, validate_fn, _resolveName, resolveName_fn, _resolveValue, resolveValue_fn, _apply, apply_fn;
|
|
1057
|
-
var FilterManager = class extends BaseManager {
|
|
1058
|
-
constructor(queue) {
|
|
1059
|
-
super(queue.distube);
|
|
1060
|
-
__privateAdd(this, _validate);
|
|
1061
|
-
__privateAdd(this, _resolveName);
|
|
1062
|
-
__privateAdd(this, _resolveValue);
|
|
1063
|
-
__privateAdd(this, _apply);
|
|
1064
|
-
__publicField(this, "queue");
|
|
1065
|
-
this.queue = queue;
|
|
1066
|
-
}
|
|
1067
|
-
add(filterOrFilters, override = false) {
|
|
1068
|
-
if (Array.isArray(filterOrFilters)) {
|
|
1069
|
-
const resolvedFilters = filterOrFilters.map((f) => __privateMethod(this, _validate, validate_fn).call(this, f));
|
|
1070
|
-
const newFilters = resolvedFilters.reduceRight((unique, o) => {
|
|
1071
|
-
if (!unique.some((obj) => obj === o && obj.name === o) && !unique.some((obj) => obj !== o.name && obj.name !== o.name)) {
|
|
1072
|
-
if (!this.has(o))
|
|
1073
|
-
unique.push(o);
|
|
1074
|
-
if (this.has(o) && override) {
|
|
1075
|
-
this.remove(o);
|
|
1076
|
-
unique.push(o);
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
return unique;
|
|
1080
|
-
}, []).reverse();
|
|
1081
|
-
return this.set([...this.collection.values(), ...newFilters]);
|
|
1082
|
-
}
|
|
1083
|
-
return this.set([...this.collection.values(), filterOrFilters]);
|
|
1084
|
-
}
|
|
1085
|
-
clear() {
|
|
1086
|
-
return this.set([]);
|
|
1087
|
-
}
|
|
1088
|
-
set(filters) {
|
|
1089
|
-
this.collection.clear();
|
|
1090
|
-
for (const filter of filters) {
|
|
1091
|
-
const resolved = __privateMethod(this, _validate, validate_fn).call(this, filter);
|
|
1092
|
-
this.collection.set(__privateMethod(this, _resolveName, resolveName_fn).call(this, resolved), resolved);
|
|
1093
|
-
}
|
|
1094
|
-
__privateMethod(this, _apply, apply_fn).call(this);
|
|
1095
|
-
return this;
|
|
1096
|
-
}
|
|
1097
|
-
remove(filterOrFilters) {
|
|
1098
|
-
const remove = /* @__PURE__ */ __name((f) => this.collection.delete(__privateMethod(this, _resolveName, resolveName_fn).call(this, __privateMethod(this, _validate, validate_fn).call(this, f))), "remove");
|
|
1099
|
-
if (Array.isArray(filterOrFilters))
|
|
1100
|
-
filterOrFilters.map(remove);
|
|
1101
|
-
else
|
|
1102
|
-
remove(filterOrFilters);
|
|
1103
|
-
__privateMethod(this, _apply, apply_fn).call(this);
|
|
1104
|
-
return this;
|
|
1105
|
-
}
|
|
1106
|
-
has(filter) {
|
|
1107
|
-
return this.collection.has(__privateMethod(this, _resolveName, resolveName_fn).call(this, filter));
|
|
1108
|
-
}
|
|
1109
|
-
get names() {
|
|
1110
|
-
return this.collection.map((f) => __privateMethod(this, _resolveName, resolveName_fn).call(this, f));
|
|
1111
|
-
}
|
|
1112
|
-
get values() {
|
|
1113
|
-
return this.collection.map((f) => __privateMethod(this, _resolveValue, resolveValue_fn).call(this, f));
|
|
1114
|
-
}
|
|
1115
|
-
toString() {
|
|
1116
|
-
return this.names.toString();
|
|
1117
|
-
}
|
|
1118
|
-
};
|
|
1119
|
-
__name(FilterManager, "FilterManager");
|
|
1120
|
-
_validate = new WeakSet();
|
|
1121
|
-
validate_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1122
|
-
if (typeof filter === "string" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter) || typeof filter === "object" && typeof filter.name === "string" && typeof filter.value === "string") {
|
|
1123
|
-
return filter;
|
|
1124
|
-
}
|
|
1125
|
-
throw new DisTubeError("INVALID_TYPE", "FilterResolvable", filter, "filter");
|
|
1126
|
-
}, "#validate");
|
|
1127
|
-
_resolveName = new WeakSet();
|
|
1128
|
-
resolveName_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1129
|
-
return typeof filter === "string" ? filter : filter.name;
|
|
1130
|
-
}, "#resolveName");
|
|
1131
|
-
_resolveValue = new WeakSet();
|
|
1132
|
-
resolveValue_fn = /* @__PURE__ */ __name(function(filter) {
|
|
1133
|
-
return typeof filter === "string" ? this.distube.filters[filter] : filter.value;
|
|
1134
|
-
}, "#resolveValue");
|
|
1135
|
-
_apply = new WeakSet();
|
|
1136
|
-
apply_fn = /* @__PURE__ */ __name(function() {
|
|
1137
|
-
this.queue.beginTime = this.queue.currentTime;
|
|
1138
|
-
this.queues.playSong(this.queue);
|
|
1139
|
-
}, "#apply");
|
|
1140
|
-
|
|
1141
|
-
// src/core/voice/DisTubeVoice.ts
|
|
1142
|
-
var import_tiny_typed_emitter = require("tiny-typed-emitter");
|
|
1143
|
-
var import_voice2 = require("@discordjs/voice");
|
|
1144
|
-
var _channel, _volume, _br, br_fn, _join, join_fn;
|
|
1145
|
-
var DisTubeVoice = class extends import_tiny_typed_emitter.TypedEmitter {
|
|
1146
|
-
constructor(voiceManager, channel) {
|
|
1147
|
-
super();
|
|
1148
|
-
__privateAdd(this, _br);
|
|
1149
|
-
__privateAdd(this, _join);
|
|
1150
|
-
__publicField(this, "id");
|
|
1151
|
-
__publicField(this, "voices");
|
|
1152
|
-
__publicField(this, "audioPlayer");
|
|
1153
|
-
__publicField(this, "connection");
|
|
1154
|
-
__publicField(this, "audioResource");
|
|
1155
|
-
__publicField(this, "emittedError");
|
|
1156
|
-
__publicField(this, "isDisconnected", false);
|
|
1157
|
-
__privateAdd(this, _channel, void 0);
|
|
1158
|
-
__privateAdd(this, _volume, 100);
|
|
1159
|
-
this.voices = voiceManager;
|
|
1160
|
-
this.id = channel.guildId;
|
|
1161
|
-
this.channel = channel;
|
|
1162
|
-
this.voices.add(this.id, this);
|
|
1163
|
-
this.audioPlayer = (0, import_voice2.createAudioPlayer)().on(import_voice2.AudioPlayerStatus.Idle, (oldState) => {
|
|
1164
|
-
if (oldState.status !== import_voice2.AudioPlayerStatus.Idle) {
|
|
1165
|
-
delete this.audioResource;
|
|
1166
|
-
this.emit("finish");
|
|
1167
|
-
}
|
|
1168
|
-
}).on(import_voice2.AudioPlayerStatus.Playing, () => __privateMethod(this, _br, br_fn).call(this)).on("error", (error) => {
|
|
1169
|
-
if (this.emittedError)
|
|
1170
|
-
return;
|
|
1171
|
-
this.emittedError = true;
|
|
1172
|
-
this.emit("error", error);
|
|
1173
|
-
});
|
|
1174
|
-
this.connection.on(import_voice2.VoiceConnectionStatus.Disconnected, (_, newState) => {
|
|
1175
|
-
if (newState.reason === import_voice2.VoiceConnectionDisconnectReason.Manual) {
|
|
1176
|
-
this.leave();
|
|
1177
|
-
} else if (newState.reason === import_voice2.VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
|
|
1178
|
-
entersState(this.connection, import_voice2.VoiceConnectionStatus.Connecting, 5e3).catch(() => {
|
|
1179
|
-
if (![import_voice2.VoiceConnectionStatus.Ready, import_voice2.VoiceConnectionStatus.Connecting].includes(this.connection.state.status)) {
|
|
1180
|
-
this.leave();
|
|
1181
|
-
}
|
|
1182
|
-
});
|
|
1183
|
-
} else if (this.connection.rejoinAttempts < 5) {
|
|
1184
|
-
setTimeout(() => {
|
|
1185
|
-
this.connection.rejoin();
|
|
1186
|
-
}, (this.connection.rejoinAttempts + 1) * 5e3).unref();
|
|
1187
|
-
} else if (this.connection.state.status !== import_voice2.VoiceConnectionStatus.Destroyed) {
|
|
1188
|
-
this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
|
|
1189
|
-
}
|
|
1190
|
-
}).on(import_voice2.VoiceConnectionStatus.Destroyed, () => {
|
|
1191
|
-
this.leave(new DisTubeError("VOICE_RECONNECT_FAILED"));
|
|
1192
|
-
}).on("error", () => void 0);
|
|
1193
|
-
this.connection.subscribe(this.audioPlayer);
|
|
1194
|
-
}
|
|
1195
|
-
get channel() {
|
|
1196
|
-
return __privateGet(this, _channel);
|
|
1197
|
-
}
|
|
1198
|
-
set channel(channel) {
|
|
1199
|
-
if (!isSupportedVoiceChannel(channel)) {
|
|
1200
|
-
throw new DisTubeError("INVALID_TYPE", "BaseGuildVoiceChannel", channel, "DisTubeVoice#channel");
|
|
1201
|
-
}
|
|
1202
|
-
if (channel.guildId !== this.id)
|
|
1203
|
-
throw new DisTubeError("VOICE_DIFFERENT_GUILD");
|
|
1204
|
-
if (channel.client.user?.id !== this.voices.client.user?.id)
|
|
1205
|
-
throw new DisTubeError("VOICE_DIFFERENT_CLIENT");
|
|
1206
|
-
if (channel.id === __privateGet(this, _channel)?.id)
|
|
1207
|
-
return;
|
|
1208
|
-
if (!channel.joinable) {
|
|
1209
|
-
if (channel.full)
|
|
1210
|
-
throw new DisTubeError("VOICE_FULL");
|
|
1211
|
-
else
|
|
1212
|
-
throw new DisTubeError("VOICE_MISSING_PERMS");
|
|
1213
|
-
}
|
|
1214
|
-
this.connection = __privateMethod(this, _join, join_fn).call(this, channel);
|
|
1215
|
-
__privateSet(this, _channel, channel);
|
|
1216
|
-
__privateMethod(this, _br, br_fn).call(this);
|
|
1217
|
-
}
|
|
1218
|
-
async join(channel) {
|
|
1219
|
-
const TIMEOUT = 3e4;
|
|
1220
|
-
if (channel)
|
|
1221
|
-
this.channel = channel;
|
|
1222
|
-
try {
|
|
1223
|
-
await entersState(this.connection, import_voice2.VoiceConnectionStatus.Ready, TIMEOUT);
|
|
1224
|
-
} catch {
|
|
1225
|
-
if (this.connection.state.status === import_voice2.VoiceConnectionStatus.Ready)
|
|
1226
|
-
return this;
|
|
1227
|
-
if (this.connection.state.status !== import_voice2.VoiceConnectionStatus.Destroyed)
|
|
1228
|
-
this.connection.destroy();
|
|
1229
|
-
this.voices.remove(this.id);
|
|
1230
|
-
throw new DisTubeError("VOICE_CONNECT_FAILED", TIMEOUT / 1e3);
|
|
1231
|
-
}
|
|
1232
|
-
return this;
|
|
1233
|
-
}
|
|
1234
|
-
leave(error) {
|
|
1235
|
-
this.stop(true);
|
|
1236
|
-
if (!this.isDisconnected) {
|
|
1237
|
-
this.emit("disconnect", error);
|
|
1238
|
-
this.isDisconnected = true;
|
|
1239
|
-
}
|
|
1240
|
-
if (this.connection.state.status !== import_voice2.VoiceConnectionStatus.Destroyed)
|
|
1241
|
-
this.connection.destroy();
|
|
1242
|
-
this.voices.remove(this.id);
|
|
1243
|
-
}
|
|
1244
|
-
stop(force = false) {
|
|
1245
|
-
this.audioPlayer.stop(force);
|
|
1246
|
-
}
|
|
1247
|
-
play(stream) {
|
|
1248
|
-
this.emittedError = false;
|
|
1249
|
-
stream.stream.on("error", (error) => {
|
|
1250
|
-
if (this.emittedError || error.code === "ERR_STREAM_PREMATURE_CLOSE")
|
|
1251
|
-
return;
|
|
1252
|
-
this.emittedError = true;
|
|
1253
|
-
this.emit("error", error);
|
|
1254
|
-
});
|
|
1255
|
-
this.audioResource = (0, import_voice2.createAudioResource)(stream.stream, {
|
|
1256
|
-
inputType: stream.type,
|
|
1257
|
-
inlineVolume: true
|
|
1258
|
-
});
|
|
1259
|
-
this.volume = __privateGet(this, _volume);
|
|
1260
|
-
this.audioPlayer.play(this.audioResource);
|
|
1261
|
-
}
|
|
1262
|
-
set volume(volume) {
|
|
1263
|
-
if (typeof volume !== "number" || isNaN(volume)) {
|
|
1264
|
-
throw new DisTubeError("INVALID_TYPE", "number", volume, "volume");
|
|
1265
|
-
}
|
|
1266
|
-
if (volume < 0) {
|
|
1267
|
-
throw new DisTubeError("NUMBER_COMPARE", "Volume", "bigger or equal to", 0);
|
|
1268
|
-
}
|
|
1269
|
-
__privateSet(this, _volume, volume);
|
|
1270
|
-
this.audioResource?.volume?.setVolume(Math.pow(__privateGet(this, _volume) / 100, 0.5 / Math.log10(2)));
|
|
1271
|
-
}
|
|
1272
|
-
get volume() {
|
|
1273
|
-
return __privateGet(this, _volume);
|
|
1274
|
-
}
|
|
1275
|
-
get playbackDuration() {
|
|
1276
|
-
return (this.audioResource?.playbackDuration ?? 0) / 1e3;
|
|
1277
|
-
}
|
|
1278
|
-
pause() {
|
|
1279
|
-
this.audioPlayer.pause();
|
|
1280
|
-
}
|
|
1281
|
-
unpause() {
|
|
1282
|
-
this.audioPlayer.unpause();
|
|
1283
|
-
}
|
|
1284
|
-
get selfDeaf() {
|
|
1285
|
-
return this.connection.joinConfig.selfDeaf;
|
|
1286
|
-
}
|
|
1287
|
-
get selfMute() {
|
|
1288
|
-
return this.connection.joinConfig.selfMute;
|
|
1289
|
-
}
|
|
1290
|
-
setSelfDeaf(selfDeaf) {
|
|
1291
|
-
if (typeof selfDeaf !== "boolean") {
|
|
1292
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", selfDeaf, "selfDeaf");
|
|
1293
|
-
}
|
|
1294
|
-
return this.connection.rejoin({
|
|
1295
|
-
...this.connection.joinConfig,
|
|
1296
|
-
selfDeaf
|
|
1297
|
-
});
|
|
1298
|
-
}
|
|
1299
|
-
setSelfMute(selfMute) {
|
|
1300
|
-
if (typeof selfMute !== "boolean") {
|
|
1301
|
-
throw new DisTubeError("INVALID_TYPE", "boolean", selfMute, "selfMute");
|
|
1302
|
-
}
|
|
1303
|
-
return this.connection.rejoin({
|
|
1304
|
-
...this.connection.joinConfig,
|
|
1305
|
-
selfMute
|
|
1306
|
-
});
|
|
1307
|
-
}
|
|
1308
|
-
get voiceState() {
|
|
1309
|
-
return getClientMember(this.channel?.guild)?.voice;
|
|
1310
|
-
}
|
|
1311
|
-
};
|
|
1312
|
-
__name(DisTubeVoice, "DisTubeVoice");
|
|
1313
|
-
_channel = new WeakMap();
|
|
1314
|
-
_volume = new WeakMap();
|
|
1315
|
-
_br = new WeakSet();
|
|
1316
|
-
br_fn = /* @__PURE__ */ __name(function() {
|
|
1317
|
-
if (this.audioResource?.encoder?.encoder)
|
|
1318
|
-
this.audioResource.encoder.setBitrate(this.channel.bitrate);
|
|
1319
|
-
}, "#br");
|
|
1320
|
-
_join = new WeakSet();
|
|
1321
|
-
join_fn = /* @__PURE__ */ __name(function(channel) {
|
|
1322
|
-
return (0, import_voice2.joinVoiceChannel)({
|
|
1323
|
-
channelId: channel.id,
|
|
1324
|
-
guildId: this.id,
|
|
1325
|
-
adapterCreator: channel.guild.voiceAdapterCreator,
|
|
1326
|
-
group: channel.client.user?.id
|
|
1327
|
-
});
|
|
1328
|
-
}, "#join");
|
|
1329
|
-
|
|
1330
|
-
// src/core/voice/DisTubeVoiceManager.ts
|
|
1331
|
-
var import_voice3 = require("@discordjs/voice");
|
|
1332
|
-
var DisTubeVoiceManager = class extends GuildIdManager {
|
|
1333
|
-
create(channel) {
|
|
1334
|
-
const existing = this.get(channel.guildId);
|
|
1335
|
-
if (existing) {
|
|
1336
|
-
existing.channel = channel;
|
|
1337
|
-
return existing;
|
|
1159
|
+
if (this.options.leaveOnFinish)
|
|
1160
|
+
queue.voice.leave();
|
|
1161
|
+
if (!queue.autoplay)
|
|
1162
|
+
this.emit("finish", queue);
|
|
1163
|
+
queue.remove();
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1338
1166
|
}
|
|
1339
|
-
|
|
1167
|
+
const emitPlaySong = __privateMethod(this, _emitPlaySong, emitPlaySong_fn).call(this, queue);
|
|
1168
|
+
if (!queue._prev && (queue.repeatMode !== 1 /* SONG */ || queue._next)) {
|
|
1169
|
+
const prev = queue.songs.shift();
|
|
1170
|
+
delete prev.formats;
|
|
1171
|
+
delete prev.streamURL;
|
|
1172
|
+
if (this.options.savePreviousSongs)
|
|
1173
|
+
queue.previousSongs.push(prev);
|
|
1174
|
+
else
|
|
1175
|
+
queue.previousSongs.push({ id: prev.id });
|
|
1176
|
+
}
|
|
1177
|
+
queue._next = queue._prev = false;
|
|
1178
|
+
queue.beginTime = 0;
|
|
1179
|
+
const err = await this.playSong(queue);
|
|
1180
|
+
if (!err && emitPlaySong)
|
|
1181
|
+
this.emit("playSong", queue, queue.songs[0]);
|
|
1182
|
+
} finally {
|
|
1183
|
+
queue._taskQueue.resolve();
|
|
1340
1184
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1185
|
+
}, "#handleSongFinish");
|
|
1186
|
+
_handlePlayingError = new WeakSet();
|
|
1187
|
+
handlePlayingError_fn = /* @__PURE__ */ __name(function(queue, error) {
|
|
1188
|
+
const song = queue.songs.shift();
|
|
1189
|
+
try {
|
|
1190
|
+
error.name = "PlayingError";
|
|
1191
|
+
error.message = `${error.message}
|
|
1192
|
+
Id: ${song.id}
|
|
1193
|
+
Name: ${song.name}`;
|
|
1194
|
+
} catch {
|
|
1346
1195
|
}
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1196
|
+
this.emitError(error, queue.textChannel);
|
|
1197
|
+
if (queue.songs.length > 0) {
|
|
1198
|
+
this.playSong(queue).then((e) => {
|
|
1199
|
+
if (!e)
|
|
1200
|
+
this.emit("playSong", queue, queue.songs[0]);
|
|
1201
|
+
});
|
|
1202
|
+
} else {
|
|
1203
|
+
queue.stop();
|
|
1357
1204
|
}
|
|
1358
|
-
};
|
|
1359
|
-
|
|
1205
|
+
}, "#handlePlayingError");
|
|
1206
|
+
_emitPlaySong = new WeakSet();
|
|
1207
|
+
emitPlaySong_fn = /* @__PURE__ */ __name(function(queue) {
|
|
1208
|
+
return !this.options.emitNewSongOnly || queue.repeatMode === 1 /* SONG */ && queue._next || queue.repeatMode !== 1 /* SONG */ && queue.songs[0]?.id !== queue.songs[1]?.id;
|
|
1209
|
+
}, "#emitPlaySong");
|
|
1360
1210
|
|
|
1361
1211
|
// src/core/DisTubeHandler.ts
|
|
1362
|
-
var import_ytdl_core = __toESM(require("@distube/ytdl-core"));
|
|
1363
1212
|
var import_ytpl = __toESM(require("@distube/ytpl"));
|
|
1213
|
+
var import_ytdl_core = __toESM(require("@distube/ytdl-core"));
|
|
1364
1214
|
var DisTubeHandler = class extends DisTubeBase {
|
|
1365
1215
|
constructor(distube) {
|
|
1366
1216
|
super(distube);
|
|
@@ -1424,11 +1274,10 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1424
1274
|
song.member = options.member;
|
|
1425
1275
|
return song;
|
|
1426
1276
|
}
|
|
1427
|
-
if (song instanceof
|
|
1428
|
-
|
|
1429
|
-
|
|
1277
|
+
if (song instanceof SearchResultVideo)
|
|
1278
|
+
return new Song(song, options);
|
|
1279
|
+
if (song instanceof SearchResultPlaylist)
|
|
1430
1280
|
return this.resolvePlaylist(song.url, options);
|
|
1431
|
-
}
|
|
1432
1281
|
if (isObject(song))
|
|
1433
1282
|
return new Song(song, options);
|
|
1434
1283
|
if (import_ytpl.default.validateID(song))
|
|
@@ -1453,14 +1302,19 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1453
1302
|
playlist.member = member;
|
|
1454
1303
|
return playlist;
|
|
1455
1304
|
}
|
|
1456
|
-
let solvablePlaylist;
|
|
1457
1305
|
if (typeof playlist === "string") {
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1306
|
+
const info = await (0, import_ytpl.default)(playlist, { limit: Infinity });
|
|
1307
|
+
const songs = info.items.filter((v) => !v.thumbnail.includes("no_thumbnail")).map((v) => new Song(v, { member, metadata }));
|
|
1308
|
+
return new Playlist({
|
|
1309
|
+
source,
|
|
1310
|
+
songs,
|
|
1311
|
+
member,
|
|
1312
|
+
name: info.title,
|
|
1313
|
+
url: info.url,
|
|
1314
|
+
thumbnail: songs[0].thumbnail
|
|
1315
|
+
}, { metadata });
|
|
1316
|
+
}
|
|
1317
|
+
return new Playlist(playlist, { member, properties: { source }, metadata });
|
|
1464
1318
|
}
|
|
1465
1319
|
async searchSong(message, query) {
|
|
1466
1320
|
if (!isMessageInstance(message))
|
|
@@ -1594,6 +1448,186 @@ var DisTubeHandler = class extends DisTubeBase {
|
|
|
1594
1448
|
};
|
|
1595
1449
|
__name(DisTubeHandler, "DisTubeHandler");
|
|
1596
1450
|
|
|
1451
|
+
// src/core/DisTubeOptions.ts
|
|
1452
|
+
var _validateOptions, validateOptions_fn;
|
|
1453
|
+
var Options = class {
|
|
1454
|
+
constructor(options) {
|
|
1455
|
+
__privateAdd(this, _validateOptions);
|
|
1456
|
+
__publicField(this, "plugins");
|
|
1457
|
+
__publicField(this, "emitNewSongOnly");
|
|
1458
|
+
__publicField(this, "leaveOnFinish");
|
|
1459
|
+
__publicField(this, "leaveOnStop");
|
|
1460
|
+
__publicField(this, "leaveOnEmpty");
|
|
1461
|
+
__publicField(this, "emptyCooldown");
|
|
1462
|
+
__publicField(this, "savePreviousSongs");
|
|
1463
|
+
__publicField(this, "searchSongs");
|
|
1464
|
+
__publicField(this, "searchCooldown");
|
|
1465
|
+
__publicField(this, "youtubeCookie");
|
|
1466
|
+
__publicField(this, "youtubeIdentityToken");
|
|
1467
|
+
__publicField(this, "customFilters");
|
|
1468
|
+
__publicField(this, "ytdlOptions");
|
|
1469
|
+
__publicField(this, "nsfw");
|
|
1470
|
+
__publicField(this, "emitAddSongWhenCreatingQueue");
|
|
1471
|
+
__publicField(this, "emitAddListWhenCreatingQueue");
|
|
1472
|
+
__publicField(this, "joinNewVoiceChannel");
|
|
1473
|
+
__publicField(this, "streamType");
|
|
1474
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
1475
|
+
throw new DisTubeError("INVALID_TYPE", "object", options, "DisTubeOptions");
|
|
1476
|
+
}
|
|
1477
|
+
const opts = { ...defaultOptions, ...options };
|
|
1478
|
+
this.plugins = opts.plugins;
|
|
1479
|
+
this.emitNewSongOnly = opts.emitNewSongOnly;
|
|
1480
|
+
this.leaveOnEmpty = opts.leaveOnEmpty;
|
|
1481
|
+
this.leaveOnFinish = opts.leaveOnFinish;
|
|
1482
|
+
this.leaveOnStop = opts.leaveOnStop;
|
|
1483
|
+
this.savePreviousSongs = opts.savePreviousSongs;
|
|
1484
|
+
this.searchSongs = opts.searchSongs;
|
|
1485
|
+
this.youtubeCookie = opts.youtubeCookie;
|
|
1486
|
+
this.youtubeIdentityToken = opts.youtubeIdentityToken;
|
|
1487
|
+
this.customFilters = opts.customFilters;
|
|
1488
|
+
this.ytdlOptions = opts.ytdlOptions;
|
|
1489
|
+
this.searchCooldown = opts.searchCooldown;
|
|
1490
|
+
this.emptyCooldown = opts.emptyCooldown;
|
|
1491
|
+
this.nsfw = opts.nsfw;
|
|
1492
|
+
this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;
|
|
1493
|
+
this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;
|
|
1494
|
+
this.joinNewVoiceChannel = opts.joinNewVoiceChannel;
|
|
1495
|
+
this.streamType = opts.streamType;
|
|
1496
|
+
checkInvalidKey(opts, this, "DisTubeOptions");
|
|
1497
|
+
__privateMethod(this, _validateOptions, validateOptions_fn).call(this);
|
|
1498
|
+
}
|
|
1499
|
+
};
|
|
1500
|
+
__name(Options, "Options");
|
|
1501
|
+
_validateOptions = new WeakSet();
|
|
1502
|
+
validateOptions_fn = /* @__PURE__ */ __name(function(options = this) {
|
|
1503
|
+
if (typeof options.emitNewSongOnly !== "boolean") {
|
|
1504
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitNewSongOnly, "DisTubeOptions.emitNewSongOnly");
|
|
1505
|
+
}
|
|
1506
|
+
if (typeof options.leaveOnEmpty !== "boolean") {
|
|
1507
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnEmpty, "DisTubeOptions.leaveOnEmpty");
|
|
1508
|
+
}
|
|
1509
|
+
if (typeof options.leaveOnFinish !== "boolean") {
|
|
1510
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnFinish, "DisTubeOptions.leaveOnFinish");
|
|
1511
|
+
}
|
|
1512
|
+
if (typeof options.leaveOnStop !== "boolean") {
|
|
1513
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.leaveOnStop, "DisTubeOptions.leaveOnStop");
|
|
1514
|
+
}
|
|
1515
|
+
if (typeof options.savePreviousSongs !== "boolean") {
|
|
1516
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.savePreviousSongs, "DisTubeOptions.savePreviousSongs");
|
|
1517
|
+
}
|
|
1518
|
+
if (typeof options.joinNewVoiceChannel !== "boolean") {
|
|
1519
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.joinNewVoiceChannel, "DisTubeOptions.joinNewVoiceChannel");
|
|
1520
|
+
}
|
|
1521
|
+
if (typeof options.youtubeCookie !== "undefined" && typeof options.youtubeCookie !== "string") {
|
|
1522
|
+
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeCookie, "DisTubeOptions.youtubeCookie");
|
|
1523
|
+
}
|
|
1524
|
+
if (typeof options.youtubeIdentityToken !== "undefined" && typeof options.youtubeIdentityToken !== "string") {
|
|
1525
|
+
throw new DisTubeError("INVALID_TYPE", "string", options.youtubeIdentityToken, "DisTubeOptions.youtubeIdentityToken");
|
|
1526
|
+
}
|
|
1527
|
+
if (typeof options.customFilters !== "undefined" && typeof options.customFilters !== "object" || Array.isArray(options.customFilters)) {
|
|
1528
|
+
throw new DisTubeError("INVALID_TYPE", "object", options.customFilters, "DisTubeOptions.customFilters");
|
|
1529
|
+
}
|
|
1530
|
+
if (typeof options.ytdlOptions !== "object" || Array.isArray(options.ytdlOptions)) {
|
|
1531
|
+
throw new DisTubeError("INVALID_TYPE", "object", options.ytdlOptions, "DisTubeOptions.ytdlOptions");
|
|
1532
|
+
}
|
|
1533
|
+
if (typeof options.searchCooldown !== "number" || isNaN(options.searchCooldown)) {
|
|
1534
|
+
throw new DisTubeError("INVALID_TYPE", "number", options.searchCooldown, "DisTubeOptions.searchCooldown");
|
|
1535
|
+
}
|
|
1536
|
+
if (typeof options.emptyCooldown !== "number" || isNaN(options.emptyCooldown)) {
|
|
1537
|
+
throw new DisTubeError("INVALID_TYPE", "number", options.emptyCooldown, "DisTubeOptions.emptyCooldown");
|
|
1538
|
+
}
|
|
1539
|
+
if (typeof options.searchSongs !== "number" || isNaN(options.searchSongs)) {
|
|
1540
|
+
throw new DisTubeError("INVALID_TYPE", "number", options.searchSongs, "DisTubeOptions.searchSongs");
|
|
1541
|
+
}
|
|
1542
|
+
if (!Array.isArray(options.plugins)) {
|
|
1543
|
+
throw new DisTubeError("INVALID_TYPE", "Array<Plugin>", options.plugins, "DisTubeOptions.plugins");
|
|
1544
|
+
}
|
|
1545
|
+
if (typeof options.nsfw !== "boolean") {
|
|
1546
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.nsfw, "DisTubeOptions.nsfw");
|
|
1547
|
+
}
|
|
1548
|
+
if (typeof options.emitAddSongWhenCreatingQueue !== "boolean") {
|
|
1549
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddSongWhenCreatingQueue, "DisTubeOptions.emitAddSongWhenCreatingQueue");
|
|
1550
|
+
}
|
|
1551
|
+
if (typeof options.emitAddListWhenCreatingQueue !== "boolean") {
|
|
1552
|
+
throw new DisTubeError("INVALID_TYPE", "boolean", options.emitAddListWhenCreatingQueue, "DisTubeOptions.emitAddListWhenCreatingQueue");
|
|
1553
|
+
}
|
|
1554
|
+
if (typeof options.streamType !== "number" || isNaN(options.streamType) || !StreamType[options.streamType]) {
|
|
1555
|
+
throw new DisTubeError("INVALID_TYPE", "StreamType", options.streamType, "DisTubeOptions.streamType");
|
|
1556
|
+
}
|
|
1557
|
+
}, "#validateOptions");
|
|
1558
|
+
|
|
1559
|
+
// src/core/DisTubeStream.ts
|
|
1560
|
+
var import_prism_media = require("prism-media");
|
|
1561
|
+
var import_voice3 = require("@discordjs/voice");
|
|
1562
|
+
var chooseBestVideoFormat = /* @__PURE__ */ __name((formats, isLive = false) => {
|
|
1563
|
+
let filter = /* @__PURE__ */ __name((format) => format.hasAudio, "filter");
|
|
1564
|
+
if (isLive)
|
|
1565
|
+
filter = /* @__PURE__ */ __name((format) => format.hasAudio && format.isHLS, "filter");
|
|
1566
|
+
formats = formats.filter(filter).sort((a, b) => Number(b.audioBitrate) - Number(a.audioBitrate) || Number(a.bitrate) - Number(b.bitrate));
|
|
1567
|
+
return formats.find((format) => !format.hasVideo) || formats.sort((a, b) => Number(a.bitrate) - Number(b.bitrate))[0];
|
|
1568
|
+
}, "chooseBestVideoFormat");
|
|
1569
|
+
var DisTubeStream = class {
|
|
1570
|
+
constructor(url, options) {
|
|
1571
|
+
__publicField(this, "type");
|
|
1572
|
+
__publicField(this, "stream");
|
|
1573
|
+
__publicField(this, "url");
|
|
1574
|
+
this.url = url;
|
|
1575
|
+
this.type = !options.type ? import_voice3.StreamType.OggOpus : import_voice3.StreamType.Raw;
|
|
1576
|
+
const args = [
|
|
1577
|
+
"-reconnect",
|
|
1578
|
+
"1",
|
|
1579
|
+
"-reconnect_streamed",
|
|
1580
|
+
"1",
|
|
1581
|
+
"-reconnect_delay_max",
|
|
1582
|
+
"5",
|
|
1583
|
+
"-i",
|
|
1584
|
+
url,
|
|
1585
|
+
"-analyzeduration",
|
|
1586
|
+
"0",
|
|
1587
|
+
"-loglevel",
|
|
1588
|
+
"0",
|
|
1589
|
+
"-ar",
|
|
1590
|
+
"48000",
|
|
1591
|
+
"-ac",
|
|
1592
|
+
"2",
|
|
1593
|
+
"-f"
|
|
1594
|
+
];
|
|
1595
|
+
if (!options.type) {
|
|
1596
|
+
args.push("opus", "-acodec", "libopus");
|
|
1597
|
+
} else {
|
|
1598
|
+
args.push("s16le");
|
|
1599
|
+
}
|
|
1600
|
+
if (typeof options.seek === "number" && options.seek > 0) {
|
|
1601
|
+
args.unshift("-ss", options.seek.toString());
|
|
1602
|
+
}
|
|
1603
|
+
if (Array.isArray(options.ffmpegArgs)) {
|
|
1604
|
+
args.push(...options.ffmpegArgs);
|
|
1605
|
+
}
|
|
1606
|
+
this.stream = new import_prism_media.FFmpeg({ args, shell: false });
|
|
1607
|
+
}
|
|
1608
|
+
static YouTube(formats, options = {}) {
|
|
1609
|
+
if (!formats || !formats.length)
|
|
1610
|
+
throw new DisTubeError("UNAVAILABLE_VIDEO");
|
|
1611
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
1612
|
+
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
1613
|
+
}
|
|
1614
|
+
const bestFormat = chooseBestVideoFormat(formats, options.isLive);
|
|
1615
|
+
if (!bestFormat)
|
|
1616
|
+
throw new DisTubeError("UNPLAYABLE_FORMATS");
|
|
1617
|
+
return new DisTubeStream(bestFormat.url, options);
|
|
1618
|
+
}
|
|
1619
|
+
static DirectLink(url, options = {}) {
|
|
1620
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
1621
|
+
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
1622
|
+
}
|
|
1623
|
+
if (typeof url !== "string" || !isURL(url)) {
|
|
1624
|
+
throw new DisTubeError("INVALID_TYPE", "an URL", url);
|
|
1625
|
+
}
|
|
1626
|
+
return new DisTubeStream(url, options);
|
|
1627
|
+
}
|
|
1628
|
+
};
|
|
1629
|
+
__name(DisTubeStream, "DisTubeStream");
|
|
1630
|
+
|
|
1597
1631
|
// src/struct/Queue.ts
|
|
1598
1632
|
var _filters;
|
|
1599
1633
|
var Queue = class extends DisTubeBase {
|
|
@@ -1636,7 +1670,7 @@ var Queue = class extends DisTubeBase {
|
|
|
1636
1670
|
this._listeners = void 0;
|
|
1637
1671
|
}
|
|
1638
1672
|
get clientMember() {
|
|
1639
|
-
return
|
|
1673
|
+
return this.voice.channel.guild.members.me ?? void 0;
|
|
1640
1674
|
}
|
|
1641
1675
|
get filters() {
|
|
1642
1676
|
return __privateGet(this, _filters);
|
|
@@ -1980,7 +2014,7 @@ function isVoiceChannelEmpty(voiceState) {
|
|
|
1980
2014
|
const clientId = voiceState.client.user?.id;
|
|
1981
2015
|
if (!guild || !clientId)
|
|
1982
2016
|
return false;
|
|
1983
|
-
const voiceChannel = guild.members.
|
|
2017
|
+
const voiceChannel = guild.members.me?.voice?.channel;
|
|
1984
2018
|
if (!voiceChannel)
|
|
1985
2019
|
return false;
|
|
1986
2020
|
const members = voiceChannel.members.filter((m) => !m.user.bot);
|
|
@@ -2000,7 +2034,7 @@ function isMemberInstance(member) {
|
|
|
2000
2034
|
}
|
|
2001
2035
|
__name(isMemberInstance, "isMemberInstance");
|
|
2002
2036
|
function isTextChannelInstance(channel) {
|
|
2003
|
-
return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && typeof channel.name === "string" && import_discord2.Constants.TextBasedChannelTypes.includes(channel.type) && typeof channel.messages?.cache === "object";
|
|
2037
|
+
return !!channel && isSnowflake(channel.id) && isSnowflake(channel.guildId) && typeof channel.name === "string" && import_discord2.Constants.TextBasedChannelTypes.includes(channel.type) && typeof channel.nsfw === "boolean" && typeof channel.messages?.cache === "object" && typeof channel.send === "function";
|
|
2004
2038
|
}
|
|
2005
2039
|
__name(isTextChannelInstance, "isTextChannelInstance");
|
|
2006
2040
|
function isMessageInstance(message) {
|
|
@@ -2046,34 +2080,6 @@ function checkInvalidKey(target, source, sourceName) {
|
|
|
2046
2080
|
throw new DisTubeError("INVALID_KEY", sourceName, invalidKey);
|
|
2047
2081
|
}
|
|
2048
2082
|
__name(checkInvalidKey, "checkInvalidKey");
|
|
2049
|
-
async function waitEvent(target, status, maxTime) {
|
|
2050
|
-
let cleanup = /* @__PURE__ */ __name(() => {
|
|
2051
|
-
}, "cleanup");
|
|
2052
|
-
try {
|
|
2053
|
-
await new Promise((resolve, reject) => {
|
|
2054
|
-
const timeout = setTimeout(() => reject(new Error(`Didn't trigger ${status} within ${maxTime}ms`)), maxTime);
|
|
2055
|
-
target.once(status, resolve);
|
|
2056
|
-
target.once("error", reject);
|
|
2057
|
-
cleanup = /* @__PURE__ */ __name(() => {
|
|
2058
|
-
clearTimeout(timeout);
|
|
2059
|
-
target.off(status, resolve);
|
|
2060
|
-
target.off("error", reject);
|
|
2061
|
-
}, "cleanup");
|
|
2062
|
-
if (target?.state?.status === status)
|
|
2063
|
-
resolve(0);
|
|
2064
|
-
});
|
|
2065
|
-
return target;
|
|
2066
|
-
} finally {
|
|
2067
|
-
cleanup();
|
|
2068
|
-
}
|
|
2069
|
-
}
|
|
2070
|
-
__name(waitEvent, "waitEvent");
|
|
2071
|
-
async function entersState(target, status, maxTime) {
|
|
2072
|
-
if (target.state.status === status)
|
|
2073
|
-
return target;
|
|
2074
|
-
return waitEvent(target, status, maxTime);
|
|
2075
|
-
}
|
|
2076
|
-
__name(entersState, "entersState");
|
|
2077
2083
|
function isObject(obj) {
|
|
2078
2084
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
2079
2085
|
}
|
|
@@ -2082,16 +2088,6 @@ function isRecord(obj) {
|
|
|
2082
2088
|
return isObject(obj);
|
|
2083
2089
|
}
|
|
2084
2090
|
__name(isRecord, "isRecord");
|
|
2085
|
-
function getClientMember(guild) {
|
|
2086
|
-
const clientUser = guild.client.user;
|
|
2087
|
-
if (!clientUser)
|
|
2088
|
-
return void 0;
|
|
2089
|
-
const clientMember = guild.members.resolve(clientUser);
|
|
2090
|
-
if (!clientMember)
|
|
2091
|
-
return void 0;
|
|
2092
|
-
return clientMember;
|
|
2093
|
-
}
|
|
2094
|
-
__name(getClientMember, "getClientMember");
|
|
2095
2091
|
|
|
2096
2092
|
// src/plugin/http.ts
|
|
2097
2093
|
var import_http = __toESM(require("http"));
|
|
@@ -2183,7 +2179,7 @@ var DisTube = class extends import_tiny_typed_emitter2.TypedEmitter {
|
|
|
2183
2179
|
if (!isObject(options))
|
|
2184
2180
|
throw new DisTubeError("INVALID_TYPE", "object", options, "options");
|
|
2185
2181
|
const { textChannel, member, skip, message, metadata } = {
|
|
2186
|
-
member:
|
|
2182
|
+
member: voiceChannel.guild.members.me ?? void 0,
|
|
2187
2183
|
textChannel: options?.message?.channel,
|
|
2188
2184
|
skip: false,
|
|
2189
2185
|
...options
|
|
@@ -2231,12 +2227,12 @@ var DisTube = class extends import_tiny_typed_emitter2.TypedEmitter {
|
|
|
2231
2227
|
if (!(e instanceof DisTubeError)) {
|
|
2232
2228
|
try {
|
|
2233
2229
|
e.name = "PlayError";
|
|
2234
|
-
e.message = `${song
|
|
2230
|
+
e.message = `${typeof song === "string" ? song : song.url}
|
|
2235
2231
|
${e.message}`;
|
|
2236
2232
|
} catch {
|
|
2237
2233
|
}
|
|
2238
2234
|
}
|
|
2239
|
-
|
|
2235
|
+
throw e;
|
|
2240
2236
|
} finally {
|
|
2241
2237
|
if (queuing)
|
|
2242
2238
|
queue?._taskQueue.resolve();
|
|
@@ -2248,7 +2244,7 @@ ${e.message}`;
|
|
|
2248
2244
|
throw new DisTubeError("INVALID_TYPE", "Array", songs, "songs");
|
|
2249
2245
|
if (!songs.length)
|
|
2250
2246
|
throw new DisTubeError("EMPTY_ARRAY", "songs");
|
|
2251
|
-
const filteredSongs = songs.filter((song) => song instanceof Song || song
|
|
2247
|
+
const filteredSongs = songs.filter((song) => song instanceof Song || isURL(song) || typeof song !== "string" && song.type === "video" /* VIDEO */);
|
|
2252
2248
|
if (!filteredSongs.length)
|
|
2253
2249
|
throw new DisTubeError("NO_VALID_SONG");
|
|
2254
2250
|
if (member && !isMemberInstance(member)) {
|
|
@@ -2270,7 +2266,7 @@ ${e.message}`;
|
|
|
2270
2266
|
return new Playlist(resolvedSongs, { member, properties, metadata });
|
|
2271
2267
|
}
|
|
2272
2268
|
async search(string, options = {}) {
|
|
2273
|
-
const opts = { type: "video"
|
|
2269
|
+
const opts = { type: "video" /* VIDEO */, limit: 10, safeSearch: false, ...options };
|
|
2274
2270
|
if (typeof opts.type !== "string" || !["video", "playlist"].includes(opts.type)) {
|
|
2275
2271
|
throw new DisTubeError("INVALID_TYPE", ["video", "playlist"], opts.type, "options.type");
|
|
2276
2272
|
}
|
|
@@ -2283,7 +2279,11 @@ ${e.message}`;
|
|
|
2283
2279
|
}
|
|
2284
2280
|
try {
|
|
2285
2281
|
const search = await (0, import_ytsr.default)(string, opts);
|
|
2286
|
-
const results = search.items.map((i) =>
|
|
2282
|
+
const results = search.items.map((i) => {
|
|
2283
|
+
if (i.type === "video")
|
|
2284
|
+
return new SearchResultVideo(i);
|
|
2285
|
+
return new SearchResultPlaylist(i);
|
|
2286
|
+
});
|
|
2287
2287
|
if (results.length === 0)
|
|
2288
2288
|
throw new DisTubeError("NO_RESULT");
|
|
2289
2289
|
return results;
|
|
@@ -2404,8 +2404,9 @@ __name(DisTube, "DisTube");
|
|
|
2404
2404
|
Queue,
|
|
2405
2405
|
QueueManager,
|
|
2406
2406
|
RepeatMode,
|
|
2407
|
-
|
|
2407
|
+
SearchResultPlaylist,
|
|
2408
2408
|
SearchResultType,
|
|
2409
|
+
SearchResultVideo,
|
|
2409
2410
|
Song,
|
|
2410
2411
|
StreamType,
|
|
2411
2412
|
TaskQueue,
|
|
@@ -2414,9 +2415,7 @@ __name(DisTube, "DisTube");
|
|
|
2414
2415
|
chooseBestVideoFormat,
|
|
2415
2416
|
defaultFilters,
|
|
2416
2417
|
defaultOptions,
|
|
2417
|
-
entersState,
|
|
2418
2418
|
formatDuration,
|
|
2419
|
-
getClientMember,
|
|
2420
2419
|
getResponseHeaders,
|
|
2421
2420
|
isClientInstance,
|
|
2422
2421
|
isGuildInstance,
|