discord-player 6.2.0 → 6.3.0

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.mjs CHANGED
@@ -1,3192 +1,121 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
- }) : x)(function(x) {
6
- if (typeof require !== "undefined")
7
- return require.apply(this, arguments);
8
- throw new Error('Dynamic require of "' + x + '" is not supported');
9
- });
10
- var __accessCheck = (obj, member, msg) => {
11
- if (!member.has(obj))
12
- throw TypeError("Cannot " + msg);
13
- };
14
- var __privateGet = (obj, member, getter) => {
15
- __accessCheck(obj, member, "read from private field");
16
- return getter ? getter.call(obj) : member.get(obj);
17
- };
18
- var __privateAdd = (obj, member, value) => {
19
- if (member.has(obj))
20
- throw TypeError("Cannot add the same private member more than once");
21
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
22
- };
23
- var __privateSet = (obj, member, value, setter) => {
24
- __accessCheck(obj, member, "write to private field");
25
- setter ? setter.call(obj, value) : member.set(obj, value);
26
- return value;
27
- };
28
- var __privateMethod = (obj, member, method) => {
29
- __accessCheck(obj, member, "access private method");
30
- return method;
31
- };
1
+ import DiscordPlayer from './index.js';
2
+
3
+ const {
4
+ AF_NIGHTCORE_RATE,
5
+ AF_VAPORWAVE_RATE,
6
+ AFilterGraph,
7
+ AsyncQueue,
8
+ AsyncQueueEntry,
9
+ AudioFilters,
10
+ AudioPlayer,
11
+ BASS_EQ_BANDS,
12
+ BaseExtractor,
13
+ BiquadFilterType,
14
+ DiscordPlayerQueryResultCache,
15
+ EqualizerConfigurationPreset,
16
+ ErrorStatusCode,
17
+ ExtractorExecutionContext,
18
+ FFMPEG_ARGS_PIPED,
19
+ FFMPEG_ARGS_STRING,
20
+ FFMPEG_SRATE_REGEX,
21
+ FFmpeg,
22
+ FFmpegFilterer,
23
+ FiltersChain,
24
+ GuildNodeManager,
25
+ GuildQueue,
26
+ GuildQueueAudioFilters,
27
+ GuildQueueEvent,
28
+ GuildQueueHistory,
29
+ GuildQueuePlayerNode,
30
+ PCMAudioFilters,
31
+ Player,
32
+ PlayerError,
33
+ PlayerEvent,
34
+ PlayerEventsEmitter,
35
+ Playlist,
36
+ Q_BUTTERWORTH,
37
+ QueryCache,
38
+ QueryResolver,
39
+ QueryType,
40
+ QueueRepeatMode,
41
+ SearchResult,
42
+ StreamDispatcher,
43
+ Track,
44
+ TypeUtil,
45
+ Util,
46
+ VoiceReceiverNode,
47
+ VoiceUtils,
48
+ VolumeTransformer,
49
+ createAudioPlayer,
50
+ createFFmpegStream,
51
+ findFFmpeg,
52
+ onAfterCreateStream,
53
+ onBeforeCreateStream,
54
+ useHistory,
55
+ useMasterPlayer,
56
+ useMetadata,
57
+ usePlayer,
58
+ useQueue,
59
+ useTimeline,
60
+ version
61
+ } = DiscordPlayer;
32
62
 
33
- // src/index.ts
34
- import { version as djsVersion } from "discord.js";
35
-
36
- // src/utils/PlayerEventsEmitter.ts
37
- import { EventEmitter } from "@discord-player/utils";
38
-
39
- // src/utils/Util.ts
40
- import { setTimeout as setTimeout2 } from "timers/promises";
41
- var Util = class {
42
- constructor() {
43
- }
44
- static durationString(durObj) {
45
- return Object.values(durObj).map((m) => isNaN(m) ? 0 : m).join(":");
46
- }
47
- static parseMS(milliseconds) {
48
- if (isNaN(milliseconds))
49
- milliseconds = 0;
50
- const round = milliseconds > 0 ? Math.floor : Math.ceil;
51
- return {
52
- days: round(milliseconds / 864e5),
53
- hours: round(milliseconds / 36e5) % 24,
54
- minutes: round(milliseconds / 6e4) % 60,
55
- seconds: round(milliseconds / 1e3) % 60
56
- };
57
- }
58
- static buildTimeCode(duration) {
59
- const items = Object.keys(duration);
60
- const required = ["days", "hours", "minutes", "seconds"];
61
- const parsed = items.filter((x) => required.includes(x)).map((m) => duration[m]);
62
- const final = parsed.slice(parsed.findIndex((x) => x !== 0)).map((x) => x.toString().padStart(2, "0")).join(":");
63
- return final.length <= 3 ? `0:${final.padStart(2, "0") || 0}` : final;
64
- }
65
- static last(arr) {
66
- if (!Array.isArray(arr))
67
- return arr;
68
- return arr[arr.length - 1];
69
- }
70
- static isVoiceEmpty(channel) {
71
- return channel && channel.members.filter((member) => !member.user.bot).size === 0;
72
- }
73
- static require(id) {
74
- try {
75
- return { module: __require(id), error: null };
76
- } catch (error) {
77
- return { module: null, error };
78
- }
79
- }
80
- static async import(id) {
81
- try {
82
- const mod = await import(id);
83
- return { module: mod, error: null };
84
- } catch (error) {
85
- return { module: null, error };
86
- }
87
- }
88
- static wait(time) {
89
- return setTimeout2(time, void 0, { ref: false });
90
- }
91
- static noop() {
92
- }
93
- static async getFetch() {
94
- if ("fetch" in globalThis)
95
- return globalThis.fetch;
96
- for (const lib of ["node-fetch", "undici"]) {
97
- try {
98
- return await import(lib).then((res) => res.fetch || res.default?.fetch || res.default);
99
- } catch {
100
- try {
101
- const res = __require(lib);
102
- if (res)
103
- return res.fetch || res.default?.fetch || res.default;
104
- } catch {
105
- }
106
- }
107
- }
108
- }
109
- static warn(message, code = "DeprecationWarning", detail) {
110
- process.emitWarning(message, {
111
- code,
112
- detail
113
- });
114
- }
115
- static randomChoice(src) {
116
- return src[Math.floor(Math.random() * src.length)];
117
- }
118
- };
119
- __name(Util, "Util");
120
-
121
- // src/utils/PlayerEventsEmitter.ts
122
- var PlayerEventsEmitter = class extends EventEmitter {
123
- constructor(requiredEvents = []) {
124
- super();
125
- this.requiredEvents = requiredEvents;
126
- }
127
- emit(name, ...args) {
128
- if (this.requiredEvents.includes(name) && !this.eventNames().includes(name)) {
129
- console.error(...args);
130
- Util.warn(
131
- `No event listener found for event "${String(name)}". Events ${this.requiredEvents.map((m) => `"${String(m)}"`).join(", ")} must have event listeners.`,
132
- "UnhandledEventsWarning"
133
- );
134
- return false;
135
- }
136
- return super.emit(name, ...args);
137
- }
138
- };
139
- __name(PlayerEventsEmitter, "PlayerEventsEmitter");
140
-
141
- // src/utils/AudioFilters.ts
142
- var bass = /* @__PURE__ */ __name((g) => `bass=g=${g}:f=110:w=0.3`, "bass");
143
- var _AudioFilters = class {
144
- constructor() {
145
- return _AudioFilters;
146
- }
147
- static get(name) {
148
- return this.filters[name] ?? name;
149
- }
150
- static has(name) {
151
- return name in this.filters;
152
- }
153
- static *[Symbol.iterator]() {
154
- for (const [k, v] of Object.entries(this.filters)) {
155
- yield { name: k, value: v };
156
- }
157
- }
158
- static get names() {
159
- return Object.keys(this.filters);
160
- }
161
- static get length() {
162
- return this.names.length;
163
- }
164
- static toString() {
165
- return this.names.map((m) => this[m]).join(",");
166
- }
167
- static create(filters) {
168
- if (!filters || !Array.isArray(filters))
169
- return this.toString();
170
- return filters.filter((predicate) => typeof predicate === "string").map((m) => this.get(m)).join(",");
171
- }
172
- static define(filterName, value) {
173
- this.filters[filterName] = value;
174
- }
175
- static defineBulk(filtersArray) {
176
- filtersArray.forEach((arr) => this.define(arr.name, arr.value));
177
- }
178
- };
179
- var AudioFilters = _AudioFilters;
180
- __name(AudioFilters, "AudioFilters");
181
- AudioFilters.filters = {
182
- bassboost_low: bass(15),
183
- bassboost: bass(20),
184
- bassboost_high: bass(30),
185
- "8D": "apulsator=hz=0.09",
186
- vaporwave: "aresample=48000,asetrate=48000*0.8",
187
- nightcore: "aresample=48000,asetrate=48000*1.25",
188
- lofi: "aresample=48000,asetrate=48000*0.9,extrastereo=m=2.5:c=disabled",
189
- phaser: "aphaser=in_gain=0.4",
190
- tremolo: "tremolo",
191
- vibrato: "vibrato=f=6.5",
192
- reverse: "areverse",
193
- treble: "treble=g=5",
194
- normalizer2: "dynaudnorm=g=101",
195
- normalizer: "acompressor",
196
- surrounding: "surround",
197
- pulsator: "apulsator=hz=1",
198
- subboost: "asubboost",
199
- karaoke: "stereotools=mlev=0.03",
200
- flanger: "flanger",
201
- gate: "agate",
202
- haas: "haas",
203
- mcompand: "mcompand",
204
- mono: "pan=mono|c0=.5*c0+.5*c1",
205
- mstlr: "stereotools=mode=ms>lr",
206
- mstrr: "stereotools=mode=ms>rr",
207
- compressor: "compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6",
208
- expander: "compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3",
209
- softlimiter: "compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8",
210
- chorus: "chorus=0.7:0.9:55:0.4:0.25:2",
211
- chorus2d: "chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3",
212
- chorus3d: "chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3",
213
- fadein: "afade=t=in:ss=0:d=10",
214
- dim: `afftfilt="'real=re * (1-clip((b/nb)*b,0,1))':imag='im * (1-clip((b/nb)*b,0,1))'"`,
215
- earrape: "channelsplit,sidechaingate=level_in=64"
216
- };
217
- var AudioFilters_default = AudioFilters;
218
-
219
- // src/extractors/BaseExtractor.ts
220
- var BaseExtractor = class {
221
- constructor(context, options = {}) {
222
- this.context = context;
223
- this.options = options;
224
- }
225
- get identifier() {
226
- return this.constructor.identifier;
227
- }
228
- async reconfigure(options) {
229
- this.options = options;
230
- await this.deactivate();
231
- await this.activate();
232
- }
233
- async activate() {
234
- return;
235
- }
236
- async deactivate() {
237
- return;
238
- }
239
- async validate(query, type) {
240
- return false;
241
- }
242
- async stream(info) {
243
- throw new Error("Not Implemented");
244
- }
245
- async handle(query, context) {
246
- throw new Error("Not Implemented");
247
- }
248
- async getRelatedTracks(track) {
249
- throw new Error("Not implemented");
250
- }
251
- handlePostStream(stream, next) {
252
- return next(null, stream);
253
- }
254
- emit(event, ...args) {
255
- return this.context.player.emit(event, ...args);
256
- }
257
- createResponse(playlist, tracks = playlist?.tracks || []) {
258
- return { playlist: playlist || null, tracks };
259
- }
260
- debug(message) {
261
- return this.context.player.debug(message);
262
- }
263
- };
264
- __name(BaseExtractor, "BaseExtractor");
265
- BaseExtractor.identifier = "com.discord-player.extractor";
266
-
267
- // src/extractors/ExtractorExecutionContext.ts
268
- import { Collection } from "@discord-player/utils";
269
-
270
- // src/utils/TypeUtil.ts
271
- var TypeUtil = class {
272
- constructor() {
273
- return TypeUtil;
274
- }
275
- static isFunction(t) {
276
- return typeof t === "function";
277
- }
278
- static isNumber(t) {
279
- return typeof t === "number" && !isNaN(t);
280
- }
281
- static isString(t) {
282
- return typeof t === "string";
283
- }
284
- static isBoolean(t) {
285
- return typeof t === "boolean";
286
- }
287
- static isNullish(t) {
288
- return t == null;
289
- }
290
- static isArray(t) {
291
- return Array.isArray(t);
292
- }
293
- static isError(t) {
294
- return t instanceof Error;
295
- }
296
- };
297
- __name(TypeUtil, "TypeUtil");
298
-
299
- // src/extractors/ExtractorExecutionContext.ts
300
- var knownExtractorKeys = [
301
- "SpotifyExtractor",
302
- "AppleMusicExtractor",
303
- "SoundCloudExtractor",
304
- "YouTubeExtractor",
305
- "VimeoExtractor",
306
- "ReverbnationExtractor",
307
- "AttachmentExtractor"
308
- ];
309
- var knownExtractorLib = "@discord-player/extractor";
310
- var ExtractorExecutionContext = class extends PlayerEventsEmitter {
311
- constructor(player) {
312
- super(["error"]);
313
- this.player = player;
314
- this.store = new Collection();
315
- }
316
- async loadDefault() {
317
- const mod = await Util.import(knownExtractorLib);
318
- if (mod.error)
319
- return { success: false, error: mod.error };
320
- knownExtractorKeys.forEach((key) => {
321
- if (!mod.module[key])
322
- return;
323
- this.register(mod.module[key], {});
324
- });
325
- return { success: true, error: null };
326
- }
327
- isRegistered(identifier) {
328
- return this.store.has(identifier);
329
- }
330
- get size() {
331
- return this.store.size;
332
- }
333
- get(identifier) {
334
- return this.store.get(identifier);
335
- }
336
- async register(_extractor, options) {
337
- if (typeof _extractor.identifier !== "string" || this.store.has(_extractor.identifier))
338
- return;
339
- const extractor = new _extractor(this, options);
340
- try {
341
- this.store.set(_extractor.identifier, extractor);
342
- this.player.debug(`${_extractor.identifier} extractor loaded!`);
343
- this.emit("registered", this, extractor);
344
- await extractor.activate();
345
- this.player.debug(`${_extractor.identifier} extractor activated!`);
346
- this.emit("activate", this, extractor);
347
- } catch (e) {
348
- this.store.delete(_extractor.identifier);
349
- this.player.debug(`${_extractor.identifier} extractor failed to activate! Error: ${e}`);
350
- this.emit("error", this, extractor, e);
351
- }
352
- }
353
- async unregister(_extractor) {
354
- const extractor = typeof _extractor === "string" ? this.store.get(_extractor) : this.store.find((r) => r === _extractor);
355
- if (!extractor)
356
- return;
357
- try {
358
- const key = extractor.identifier || this.store.findKey((e) => e === extractor);
359
- this.store.delete(key);
360
- this.player.debug(`${extractor.identifier} extractor disabled!`);
361
- this.emit("unregistered", this, extractor);
362
- await extractor.deactivate();
363
- this.player.debug(`${extractor.identifier} extractor deactivated!`);
364
- this.emit("deactivate", this, extractor);
365
- } catch (e) {
366
- this.player.debug(`${extractor.identifier} extractor failed to deactivate!`);
367
- this.emit("error", this, extractor, e);
368
- }
369
- }
370
- async unregisterAll() {
371
- try {
372
- await Promise.all(this.store.map((e) => this.unregister(e)));
373
- } catch {
374
- }
375
- }
376
- async run(fn, filterBlocked = true) {
377
- const blocked = this.player.options.blockExtractors ?? [];
378
- let err = null, lastExt = null;
379
- for (const ext of this.store.values()) {
380
- if (filterBlocked && blocked.some((e) => e === ext.identifier))
381
- continue;
382
- this.player.debug(`Executing extractor ${ext.identifier}...`);
383
- const result = await fn(ext).then(
384
- (res) => {
385
- return res;
386
- },
387
- (e) => {
388
- this.player.debug(`Extractor ${ext.identifier} failed with error: ${e}`);
389
- return TypeUtil.isError(e) ? e : new Error(`${e}`);
390
- }
391
- );
392
- lastExt = ext;
393
- if (result && !TypeUtil.isError(result)) {
394
- this.player.debug(`Extractor ${ext.identifier} executed successfully!`);
395
- return {
396
- extractor: ext,
397
- error: null,
398
- result
399
- };
400
- } else if (TypeUtil.isError(result)) {
401
- err = result;
402
- }
403
- }
404
- if (err)
405
- return {
406
- extractor: lastExt,
407
- error: err,
408
- result: false
409
- };
410
- }
411
- };
412
- __name(ExtractorExecutionContext, "ExtractorExecutionContext");
413
-
414
- // src/Structures/GuildNodeManager.ts
415
- import { Collection as Collection4 } from "@discord-player/utils";
416
-
417
- // src/Structures/GuildQueue.ts
418
- import { ChannelType } from "discord.js";
419
- import { Collection as Collection2, Queue as Queue2 } from "@discord-player/utils";
420
- import { StreamType as StreamType2 } from "@discordjs/voice";
421
-
422
- // src/Structures/Playlist.ts
423
- var Playlist = class {
424
- constructor(player, data) {
425
- this.player = player;
426
- this.tracks = data.tracks ?? [];
427
- this.author = data.author;
428
- this.description = data.description;
429
- this.thumbnail = data.thumbnail;
430
- this.type = data.type;
431
- this.source = data.source;
432
- this.id = data.id;
433
- this.url = data.url;
434
- this.title = data.title;
435
- }
436
- *[Symbol.iterator]() {
437
- yield* this.tracks;
438
- }
439
- get estimatedDuration() {
440
- return this.tracks.reduce((p, c) => p + c.durationMS, 0);
441
- }
442
- get durationFormatted() {
443
- return Util.buildTimeCode(Util.parseMS(this.estimatedDuration));
444
- }
445
- toJSON(withTracks = true) {
446
- const payload = {
447
- id: this.id,
448
- url: this.url,
449
- title: this.title,
450
- description: this.description,
451
- thumbnail: this.thumbnail,
452
- type: this.type,
453
- source: this.source,
454
- author: this.author,
455
- tracks: []
456
- };
457
- if (withTracks)
458
- payload.tracks = this.tracks.map((m) => m.toJSON(true));
459
- return payload;
460
- }
461
- };
462
- __name(Playlist, "Playlist");
463
-
464
- // src/Structures/GuildQueueHistory.ts
465
- import { Queue } from "@discord-player/utils";
466
- var GuildQueueHistory = class {
467
- constructor(queue) {
468
- this.queue = queue;
469
- this.tracks = new Queue("LIFO");
470
- }
471
- get currentTrack() {
472
- return this.queue.dispatcher?.audioResource?.metadata || this.queue.__current;
473
- }
474
- get nextTrack() {
475
- return this.queue.tracks.at(0) || null;
476
- }
477
- get previousTrack() {
478
- return this.tracks.at(0) || null;
479
- }
480
- get disabled() {
481
- return this.queue.options.disableHistory;
482
- }
483
- get size() {
484
- return this.tracks.size;
485
- }
486
- getSize() {
487
- return this.size;
488
- }
489
- isEmpty() {
490
- return this.tracks.size < 1;
491
- }
492
- push(track) {
493
- if (this.disabled)
494
- return false;
495
- this.tracks.add(track);
496
- return true;
497
- }
498
- clear() {
499
- this.tracks.clear();
500
- }
501
- async next() {
502
- const track = this.nextTrack;
503
- if (!track) {
504
- throw new Error("No next track in the queue");
505
- }
506
- this.queue.node.skip();
507
- }
508
- async previous(preserveCurrent = true) {
509
- const track = this.tracks.dispatch();
510
- if (!track) {
511
- throw new Error("No previous track in the queue");
512
- }
513
- const current = this.currentTrack;
514
- await this.queue.node.play(track, { queue: false });
515
- if (current && preserveCurrent)
516
- this.queue.node.insert(current, 0);
517
- }
518
- back() {
519
- return this.previous();
520
- }
521
- };
522
- __name(GuildQueueHistory, "GuildQueueHistory");
523
-
524
- // src/Structures/GuildQueuePlayerNode.ts
525
- import { StreamType } from "@discordjs/voice";
526
-
527
- // src/utils/QueryResolver.ts
528
- import { YouTube } from "youtube-sr";
529
-
530
- // src/types/types.ts
531
- var QueryType = {
532
- AUTO: "auto",
533
- YOUTUBE: "youtube",
534
- YOUTUBE_PLAYLIST: "youtubePlaylist",
535
- SOUNDCLOUD_TRACK: "soundcloudTrack",
536
- SOUNDCLOUD_PLAYLIST: "soundcloudPlaylist",
537
- SOUNDCLOUD: "soundcloud",
538
- SPOTIFY_SONG: "spotifySong",
539
- SPOTIFY_ALBUM: "spotifyAlbum",
540
- SPOTIFY_PLAYLIST: "spotifyPlaylist",
541
- SPOTIFY_SEARCH: "spotifySearch",
542
- FACEBOOK: "facebook",
543
- VIMEO: "vimeo",
544
- ARBITRARY: "arbitrary",
545
- REVERBNATION: "reverbnation",
546
- YOUTUBE_SEARCH: "youtubeSearch",
547
- YOUTUBE_VIDEO: "youtubeVideo",
548
- SOUNDCLOUD_SEARCH: "soundcloudSearch",
549
- APPLE_MUSIC_SONG: "appleMusicSong",
550
- APPLE_MUSIC_ALBUM: "appleMusicAlbum",
551
- APPLE_MUSIC_PLAYLIST: "appleMusicPlaylist",
552
- APPLE_MUSIC_SEARCH: "appleMusicSearch",
553
- FILE: "file",
554
- AUTO_SEARCH: "autoSearch"
555
- };
556
- var PlayerEvent = /* @__PURE__ */ ((PlayerEvent2) => {
557
- PlayerEvent2["debug"] = "debug";
558
- PlayerEvent2["error"] = "error";
559
- PlayerEvent2["voiceStateUpdate"] = "voiceStateUpdate";
560
- return PlayerEvent2;
561
- })(PlayerEvent || {});
562
- var QueueRepeatMode = /* @__PURE__ */ ((QueueRepeatMode2) => {
563
- QueueRepeatMode2[QueueRepeatMode2["OFF"] = 0] = "OFF";
564
- QueueRepeatMode2[QueueRepeatMode2["TRACK"] = 1] = "TRACK";
565
- QueueRepeatMode2[QueueRepeatMode2["QUEUE"] = 2] = "QUEUE";
566
- QueueRepeatMode2[QueueRepeatMode2["AUTOPLAY"] = 3] = "AUTOPLAY";
567
- return QueueRepeatMode2;
568
- })(QueueRepeatMode || {});
569
-
570
- // src/utils/QueryResolver.ts
571
- import * as soundcloud from "soundcloud-scraper";
572
- var spotifySongRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})(\?si=.+)?$/;
573
- var spotifyPlaylistRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})(\?si=.+)?$/;
574
- var spotifyAlbumRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})(\?si=.+)?$/;
575
- var vimeoRegex = /^(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)$/;
576
- var reverbnationRegex = /^https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)$/;
577
- var attachmentRegex = /^https?:\/\/.+$/;
578
- var appleMusicSongRegex = /^https?:\/\/music\.apple\.com\/.+?\/(song|album)\/.+?(\/.+?\?i=|\/)([0-9]+)$/;
579
- var appleMusicPlaylistRegex = /^https?:\/\/music\.apple\.com\/.+?\/playlist\/.+\/pl\.(u-)?[a-zA-Z0-9]+$/;
580
- var appleMusicAlbumRegex = /^https?:\/\/music\.apple\.com\/.+?\/album\/.+\/([0-9]+)$/;
581
- var QueryResolver = class {
582
- constructor() {
583
- }
584
- static get regex() {
585
- return {
586
- spotifyAlbumRegex,
587
- spotifyPlaylistRegex,
588
- spotifySongRegex,
589
- vimeoRegex,
590
- reverbnationRegex,
591
- attachmentRegex,
592
- appleMusicAlbumRegex,
593
- appleMusicPlaylistRegex,
594
- appleMusicSongRegex
595
- };
596
- }
597
- static resolve(query, fallbackSearchEngine = QueryType.AUTO_SEARCH) {
598
- if (!TypeUtil.isString(query))
599
- throw new TypeError(`Invalid query ${typeof query}, expected a string.`);
600
- if (!query.length)
601
- throw new Error("Query is required!");
602
- query = !query.includes("youtube.com") ? query.trim() : query.replace(/(m(usic)?|gaming)\./, "").trim();
603
- if ((soundcloud.validateURL || soundcloud.default.validateURL)(query, "track"))
604
- return QueryType.SOUNDCLOUD_TRACK;
605
- if ((soundcloud.validateURL || soundcloud.default.validateURL)(query, "playlist") || query.includes("/sets/"))
606
- return QueryType.SOUNDCLOUD_PLAYLIST;
607
- if (YouTube.isPlaylist(query))
608
- return QueryType.YOUTUBE_PLAYLIST;
609
- if (QueryResolver.validateId(query) || QueryResolver.validateURL(query))
610
- return QueryType.YOUTUBE_VIDEO;
611
- if (spotifySongRegex.test(query))
612
- return QueryType.SPOTIFY_SONG;
613
- if (spotifyPlaylistRegex.test(query))
614
- return QueryType.SPOTIFY_PLAYLIST;
615
- if (spotifyAlbumRegex.test(query))
616
- return QueryType.SPOTIFY_ALBUM;
617
- if (vimeoRegex.test(query))
618
- return QueryType.VIMEO;
619
- if (reverbnationRegex.test(query))
620
- return QueryType.REVERBNATION;
621
- if (appleMusicAlbumRegex.test(query))
622
- return QueryType.APPLE_MUSIC_ALBUM;
623
- if (appleMusicPlaylistRegex.test(query))
624
- return QueryType.APPLE_MUSIC_PLAYLIST;
625
- if (appleMusicSongRegex.test(query))
626
- return QueryType.APPLE_MUSIC_SONG;
627
- if (attachmentRegex.test(query))
628
- return QueryType.ARBITRARY;
629
- return fallbackSearchEngine;
630
- }
631
- static getVimeoID(query) {
632
- return QueryResolver.resolve(query) === QueryType.VIMEO ? query.split("/").filter((x) => !!x).pop() : null;
633
- }
634
- static validateId(q) {
635
- return YouTube.Regex.VIDEO_ID.test(q);
636
- }
637
- static validateURL(q) {
638
- return YouTube.Regex.VIDEO_URL.test(q);
639
- }
640
- };
641
- __name(QueryResolver, "QueryResolver");
642
-
643
- // src/Structures/Track.ts
644
- import { escapeMarkdown, SnowflakeUtil } from "discord.js";
645
- var Track = class {
646
- constructor(player, data) {
647
- this.requestedBy = null;
648
- this.queryType = null;
649
- this.raw = {
650
- source: "arbitrary"
651
- };
652
- this.extractor = null;
653
- this.id = SnowflakeUtil.generate().toString();
654
- Object.defineProperty(this, "player", { value: player, enumerable: false });
655
- void this._patch(data);
656
- }
657
- _patch(data) {
658
- this.title = escapeMarkdown(data.title ?? "");
659
- this.author = data.author ?? "";
660
- this.url = data.url ?? "";
661
- this.thumbnail = data.thumbnail ?? "";
662
- this.duration = data.duration ?? "";
663
- this.views = data.views ?? 0;
664
- this.queryType = data.queryType;
665
- this.requestedBy = data.requestedBy || null;
666
- this.playlist = data.playlist;
667
- this.raw = Object.assign({}, { source: data.raw?.source ?? data.source }, data.raw ?? data);
668
- }
669
- get queue() {
670
- return this.player.nodes.cache.find((q) => q.tracks.some((ab) => ab.id === this.id));
671
- }
672
- get durationMS() {
673
- const times = /* @__PURE__ */ __name((n, t) => {
674
- let tn = 1;
675
- for (let i = 0; i < t; i++)
676
- tn *= n;
677
- return t <= 0 ? 1e3 : tn * 1e3;
678
- }, "times");
679
- return this.duration.split(":").reverse().map((m, i) => parseInt(m) * times(60, i)).reduce((a, c) => a + c, 0);
680
- }
681
- get source() {
682
- return this.raw?.source ?? "arbitrary";
683
- }
684
- toString() {
685
- return `${this.title} by ${this.author}`;
686
- }
687
- toJSON(hidePlaylist) {
688
- return {
689
- id: this.id,
690
- title: this.title,
691
- description: this.description,
692
- author: this.author,
693
- url: this.url,
694
- thumbnail: this.thumbnail,
695
- duration: this.duration,
696
- durationMS: this.durationMS,
697
- views: this.views,
698
- requestedBy: this.requestedBy?.id || null,
699
- playlist: hidePlaylist ? null : this.playlist?.toJSON() ?? null
700
- };
701
- }
702
- };
703
- __name(Track, "Track");
704
-
705
- // src/Structures/GuildQueuePlayerNode.ts
706
- import { setTimeout as waitFor } from "timers/promises";
707
-
708
- // src/utils/AsyncQueue.ts
709
- import { SnowflakeUtil as SnowflakeUtil2 } from "discord.js";
710
- var AsyncQueue = class {
711
- constructor() {
712
- this.entries = [];
713
- }
714
- clear(consume = false) {
715
- if (consume) {
716
- this.entries.forEach((entry) => entry.consume());
717
- }
718
- this.entries = [];
719
- }
720
- get size() {
721
- return this.entries.length;
722
- }
723
- acquire(options) {
724
- const entry = new AsyncQueueEntry(this, options);
725
- if (this.entries.length === 0) {
726
- this.entries.push(entry);
727
- entry.consume();
728
- return entry;
729
- }
730
- this.entries.push(entry);
731
- return entry;
732
- }
733
- release() {
734
- if (!this.entries.length)
735
- return;
736
- this.entries.shift();
737
- this.entries[0]?.consume();
738
- }
739
- cancelAll() {
740
- this.entries.forEach((entry) => entry.cancel());
741
- }
742
- removeEntry(entry) {
743
- const entryIdx = this.entries.indexOf(entry);
744
- if (entryIdx !== -1) {
745
- this.entries.splice(entryIdx, 1);
746
- return true;
747
- }
748
- return false;
749
- }
750
- };
751
- __name(AsyncQueue, "AsyncQueue");
752
- var AsyncQueueEntry = class {
753
- constructor(queue, options) {
754
- this.queue = queue;
755
- this.options = options;
756
- this.id = SnowflakeUtil2.generate().toString();
757
- this.signal = null;
758
- this.onAbort = null;
759
- this.promise = new Promise((resolve, reject) => {
760
- this.resolve = resolve;
761
- this.reject = reject;
762
- });
763
- if (this.options?.signal) {
764
- this.setAbortSignal(this.options.signal);
765
- }
766
- }
767
- setAbortSignal(signal) {
768
- if (signal.aborted)
769
- return;
770
- this.signal = signal;
771
- this.onAbort = () => {
772
- this.queue.removeEntry(this);
773
- this.cancel();
774
- };
775
- this.signal.addEventListener("abort", this.onAbort);
776
- }
777
- consume() {
778
- this.cleanup();
779
- this.resolve();
780
- }
781
- release() {
782
- this.consume();
783
- this.queue.release();
784
- }
785
- cancel() {
786
- this.cleanup();
787
- this.reject(new Error("Cancelled"));
788
- }
789
- cleanup() {
790
- if (this.onAbort)
791
- this.signal?.removeEventListener("abort", this.onAbort);
792
- this.signal = null;
793
- this.onAbort = null;
794
- }
795
- getTask() {
796
- return this.promise;
797
- }
798
- };
799
- __name(AsyncQueueEntry, "AsyncQueueEntry");
800
-
801
- // src/Structures/GuildQueuePlayerNode.ts
802
- var FFMPEG_SRATE_REGEX = /asetrate=\d+\*(\d(\.\d)?)/;
803
- var _progress, _throw, throw_fn, _performPlay, performPlay_fn, _createGenericStream, createGenericStream_fn, _createFFmpegStream, createFFmpegStream_fn;
804
- var GuildQueuePlayerNode = class {
805
- constructor(queue) {
806
- this.queue = queue;
807
- __privateAdd(this, _throw);
808
- __privateAdd(this, _performPlay);
809
- __privateAdd(this, _createGenericStream);
810
- __privateAdd(this, _createFFmpegStream);
811
- __privateAdd(this, _progress, 0);
812
- this.tasksQueue = new AsyncQueue();
813
- }
814
- isIdle() {
815
- return !!this.queue.dispatcher?.isIdle();
816
- }
817
- isBuffering() {
818
- return !!this.queue.dispatcher?.isBuffering();
819
- }
820
- isPlaying() {
821
- return !!this.queue.dispatcher?.isPlaying();
822
- }
823
- isPaused() {
824
- return !!this.queue.dispatcher?.isPaused();
825
- }
826
- resetProgress() {
827
- __privateSet(this, _progress, 0);
828
- }
829
- setProgress(progress) {
830
- __privateSet(this, _progress, progress);
831
- }
832
- get streamTime() {
833
- return this.queue.dispatcher?.streamTime ?? 0;
834
- }
835
- get playbackTime() {
836
- const dur = __privateGet(this, _progress) + this.streamTime;
837
- return dur;
838
- }
839
- getDurationMultiplier() {
840
- const srateFilters = this.queue.filters.ffmpeg.toArray().filter((ff) => FFMPEG_SRATE_REGEX.test(ff));
841
- const multipliers = srateFilters.map((m) => {
842
- return parseFloat(FFMPEG_SRATE_REGEX.exec(m)?.[1]);
843
- }).filter((f) => !isNaN(f));
844
- return !multipliers.length ? 1 : multipliers.reduce((accumulator, current) => current + accumulator);
845
- }
846
- get estimatedPlaybackTime() {
847
- const dur = this.playbackTime;
848
- return Math.round(this.getDurationMultiplier() * dur);
849
- }
850
- get estimatedDuration() {
851
- const dur = this.queue.currentTrack?.durationMS ?? 0;
852
- return Math.round(dur / this.getDurationMultiplier());
853
- }
854
- getTimestamp(ignoreFilters = false) {
855
- if (!this.queue.currentTrack)
856
- return null;
857
- const current = ignoreFilters ? this.playbackTime : this.estimatedPlaybackTime;
858
- const total = ignoreFilters ? this.queue.currentTrack.durationMS : this.estimatedDuration;
859
- return {
860
- current: {
861
- label: Util.buildTimeCode(Util.parseMS(current)),
862
- value: current
863
- },
864
- total: {
865
- label: Util.buildTimeCode(Util.parseMS(total)),
866
- value: total
867
- },
868
- progress: Math.round(current / total * 100)
869
- };
870
- }
871
- createProgressBar(options) {
872
- const timestamp = this.getTimestamp();
873
- if (!timestamp)
874
- return null;
875
- const { indicator = "\u{1F518}", length = 15, line = "\u25AC", timecodes = true } = options || {};
876
- if (isNaN(length) || length < 0 || !Number.isFinite(length))
877
- throw new Error("invalid progressbar length");
878
- const index = Math.round(timestamp.current.value / timestamp.total.value * length);
879
- if (index >= 1 && index <= length) {
880
- const bar = line.repeat(length - 1).split("");
881
- bar.splice(index, 0, indicator);
882
- if (timecodes) {
883
- return `${timestamp.current.label} \u2503 ${bar.join("")} \u2503 ${timestamp.total.label}`;
884
- } else {
885
- return `${bar.join("")}`;
886
- }
887
- } else {
888
- if (timecodes) {
889
- return `${timestamp.current.label} \u2503 ${indicator}${line.repeat(length - 1)} \u2503 ${timestamp.total.label}`;
890
- } else {
891
- return `${indicator}${line.repeat(length - 1)}`;
892
- }
893
- }
894
- }
895
- async seek(duration) {
896
- if (!this.queue.currentTrack)
897
- return false;
898
- return await this.queue.filters.triggerReplay(duration);
899
- }
900
- get volume() {
901
- return this.queue.dispatcher?.volume ?? 100;
902
- }
903
- setVolume(vol) {
904
- if (!this.queue.dispatcher)
905
- return false;
906
- const res = this.queue.dispatcher.setVolume(vol);
907
- if (res)
908
- this.queue.filters._lastFiltersCache.volume = vol;
909
- return res;
910
- }
911
- setBitrate(rate) {
912
- this.queue.dispatcher?.audioResource?.encoder?.setBitrate(rate === "auto" ? this.queue.channel?.bitrate ?? 64e3 : rate);
913
- }
914
- setPaused(state) {
915
- if (state)
916
- return this.queue.dispatcher?.pause(true) || false;
917
- return this.queue.dispatcher?.resume() || false;
918
- }
919
- pause() {
920
- return this.setPaused(true);
921
- }
922
- resume() {
923
- return this.setPaused(false);
924
- }
925
- skip() {
926
- if (!this.queue.dispatcher)
927
- return false;
928
- this.queue.setTransitioning(false);
929
- this.queue.dispatcher.end();
930
- return true;
931
- }
932
- remove(track) {
933
- const foundTrack = this.queue.tracks.find((t, idx) => {
934
- if (track instanceof Track || typeof track === "string") {
935
- return (typeof track === "string" ? track : track.id) === t.id;
936
- }
937
- if (typeof track === "string")
938
- return track === t.id;
939
- return idx === track;
940
- });
941
- if (!foundTrack)
942
- return null;
943
- this.queue.tracks.removeOne((t) => t.id === foundTrack.id);
944
- this.queue.player.events.emit("audioTrackRemove", this.queue, foundTrack);
945
- return foundTrack;
946
- }
947
- jump(track) {
948
- const removed = this.remove(track);
949
- if (!removed)
950
- return false;
951
- this.queue.tracks.store.unshift(removed);
952
- return this.skip();
953
- }
954
- getTrackPosition(track) {
955
- return this.queue.tracks.toArray().findIndex((t, idx) => {
956
- if (track instanceof Track || typeof track === "string") {
957
- return (typeof track === "string" ? track : track.id) === t.id;
958
- }
959
- if (typeof track === "string")
960
- return track === t.id;
961
- return idx === track;
962
- });
963
- }
964
- skipTo(track) {
965
- const idx = this.getTrackPosition(track);
966
- if (idx < 0)
967
- return false;
968
- const removed = this.remove(idx);
969
- if (!removed)
970
- return false;
971
- const toRemove = this.queue.tracks.store.filter((_, i) => i <= idx);
972
- this.queue.tracks.store.splice(0, idx, removed);
973
- this.queue.player.events.emit("audioTracksRemove", this.queue, toRemove);
974
- return this.skip();
975
- }
976
- insert(track, index = 0) {
977
- if (!(track instanceof Track))
978
- throw new Error("invalid track");
979
- this.queue.tracks.store.splice(index, 0, track);
980
- if (!this.queue.options.noEmitInsert)
981
- this.queue.player.events.emit("audioTrackAdd", this.queue, track);
982
- }
983
- move(from, to) {
984
- const removed = this.remove(from);
985
- if (!removed)
986
- throw new Error("invalid track to move");
987
- this.insert(removed, to);
988
- }
989
- copy(from, to) {
990
- const src = this.queue.tracks.at(this.getTrackPosition(from));
991
- if (!src)
992
- throw new Error("invalid track to copy");
993
- this.insert(src, to);
994
- }
995
- swap(first, second) {
996
- const src = this.getTrackPosition(first);
997
- if (src < 0)
998
- throw new Error("invalid src track to swap");
999
- const dest = this.getTrackPosition(second);
1000
- if (dest < 0)
1001
- throw new Error("invalid dest track to swap");
1002
- const srcT = this.queue.tracks.store[src];
1003
- const destT = this.queue.tracks.store[dest];
1004
- this.queue.tracks.store[src] = destT;
1005
- this.queue.tracks.store[dest] = srcT;
1006
- }
1007
- stop(force = false) {
1008
- this.queue.tracks.clear();
1009
- this.queue.history.clear();
1010
- if (!this.queue.dispatcher)
1011
- return false;
1012
- this.queue.dispatcher.end();
1013
- if (force) {
1014
- this.queue.dispatcher.disconnect();
1015
- return true;
1016
- }
1017
- if (this.queue.options.leaveOnStop) {
1018
- const tm = setTimeout(() => {
1019
- if (this.isPlaying() || this.queue.tracks.size)
1020
- return clearTimeout(tm);
1021
- this.queue.dispatcher?.disconnect();
1022
- }, this.queue.options.leaveOnStopCooldown).unref();
1023
- }
1024
- return true;
1025
- }
1026
- async playRaw(resource) {
1027
- await this.queue.dispatcher?.playStream(resource);
1028
- }
1029
- async play(res, options) {
1030
- if (!this.queue.dispatcher?.voiceConnection) {
1031
- throw new Error("No voice connection available");
1032
- }
1033
- this.queue.debug(`Received play request from guild ${this.queue.guild.name} (ID: ${this.queue.guild.id})`);
1034
- options = Object.assign(
1035
- {},
1036
- {
1037
- queue: this.queue.currentTrack != null,
1038
- transitionMode: false,
1039
- seek: 0
1040
- },
1041
- options
1042
- );
1043
- if (res && options.queue) {
1044
- this.queue.debug("Requested option requires to queue the track, adding the given track to queue instead...");
1045
- return this.queue.addTrack(res);
1046
- }
1047
- const track = res || this.queue.tracks.dispatch();
1048
- if (!track) {
1049
- if (this.queue.options.skipOnNoStream)
1050
- return;
1051
- throw new Error("Play request received but track was not provided");
1052
- }
1053
- this.queue.debug("Requested option requires to play the track, initializing...");
1054
- try {
1055
- this.queue.debug(`Initiating stream extraction process...`);
1056
- const src = track.raw?.source || track.source;
1057
- const qt = track.queryType || (src === "spotify" ? "spotifySong" : src === "apple_music" ? "appleMusicSong" : src);
1058
- this.queue.debug(`Executing onBeforeCreateStream hook (QueryType: ${qt})...`);
1059
- const streamSrc = {
1060
- error: null,
1061
- stream: null
1062
- };
1063
- await this.queue.onBeforeCreateStream?.(track, qt || "arbitrary", this.queue).then(
1064
- (s) => {
1065
- if (s) {
1066
- streamSrc.stream = s;
1067
- }
1068
- },
1069
- (e) => streamSrc.error = e
1070
- );
1071
- if (!streamSrc.stream && streamSrc.error)
1072
- return __privateMethod(this, _throw, throw_fn).call(this, track, streamSrc.error);
1073
- if (!streamSrc.stream) {
1074
- this.queue.debug("Failed to get stream from onBeforeCreateStream!");
1075
- await __privateMethod(this, _createGenericStream, createGenericStream_fn).call(this, track).then(
1076
- (r) => {
1077
- if (r?.result) {
1078
- streamSrc.stream = r.result;
1079
- return;
1080
- }
1081
- if (r?.error) {
1082
- streamSrc.error = r.error;
1083
- return;
1084
- }
1085
- streamSrc.stream = streamSrc.error = null;
1086
- },
1087
- (e) => streamSrc.error = e
1088
- );
1089
- }
1090
- if (!streamSrc.stream)
1091
- return __privateMethod(this, _throw, throw_fn).call(this, track, streamSrc.error);
1092
- if (typeof options.seek === "number" && options.seek >= 0) {
1093
- __privateSet(this, _progress, options.seek);
1094
- } else {
1095
- __privateSet(this, _progress, 0);
1096
- }
1097
- const cookies = track.raw?.source === "youtube" ? this.queue.player.options.ytdlOptions?.requestOptions?.headers?.cookie : void 0;
1098
- const pcmStream = __privateMethod(this, _createFFmpegStream, createFFmpegStream_fn).call(this, streamSrc.stream, track, options.seek ?? 0, cookies);
1099
- if (options.transitionMode) {
1100
- this.queue.debug(`Transition mode detected, player will wait for buffering timeout to expire (Timeout: ${this.queue.options.bufferingTimeout}ms)`);
1101
- await waitFor(this.queue.options.bufferingTimeout);
1102
- this.queue.debug("Buffering timeout has expired!");
1103
- }
1104
- this.queue.debug(
1105
- `Preparing final stream config: ${JSON.stringify(
1106
- {
1107
- disableBiquad: this.queue.options.biquad === false,
1108
- disableEqualizer: this.queue.options.equalizer === false,
1109
- disableVolume: this.queue.options.volume === false,
1110
- disableFilters: this.queue.options.filterer === false,
1111
- disableResampler: this.queue.options.resampler === false,
1112
- sampleRate: typeof this.queue.options.resampler === "number" && this.queue.options.resampler > 0 ? this.queue.options.resampler : void 0,
1113
- biquadFilter: this.queue.filters._lastFiltersCache.biquad || void 0,
1114
- eq: this.queue.filters._lastFiltersCache.equalizer,
1115
- defaultFilters: this.queue.filters._lastFiltersCache.filters,
1116
- volume: this.queue.filters._lastFiltersCache.volume,
1117
- transitionMode: !!options.transitionMode,
1118
- ffmpegFilters: this.queue.filters.ffmpeg.toString(),
1119
- seek: options.seek
1120
- },
1121
- null,
1122
- 2
1123
- )}`
1124
- );
1125
- const resource = await this.queue.dispatcher.createStream(pcmStream, {
1126
- disableBiquad: this.queue.options.biquad === false,
1127
- disableEqualizer: this.queue.options.equalizer === false,
1128
- disableVolume: this.queue.options.volume === false,
1129
- disableFilters: this.queue.options.filterer === false,
1130
- disableResampler: this.queue.options.resampler === false,
1131
- sampleRate: typeof this.queue.options.resampler === "number" && this.queue.options.resampler > 0 ? this.queue.options.resampler : void 0,
1132
- biquadFilter: this.queue.filters._lastFiltersCache.biquad || void 0,
1133
- eq: this.queue.filters._lastFiltersCache.equalizer,
1134
- defaultFilters: this.queue.filters._lastFiltersCache.filters,
1135
- volume: this.queue.filters._lastFiltersCache.volume,
1136
- data: track,
1137
- type: StreamType.Raw
1138
- });
1139
- this.queue.setTransitioning(!!options.transitionMode);
1140
- await __privateMethod(this, _performPlay, performPlay_fn).call(this, resource);
1141
- } catch (e) {
1142
- this.queue.debug(`Failed to initialize audio player: ${e}`);
1143
- throw e;
1144
- }
1145
- }
1146
- };
1147
- __name(GuildQueuePlayerNode, "GuildQueuePlayerNode");
1148
- _progress = new WeakMap();
1149
- _throw = new WeakSet();
1150
- throw_fn = /* @__PURE__ */ __name(function(track, error) {
1151
- const streamDefinitelyFailedMyDearT_TPleaseTrustMeItsNotMyFault = new Error(`Could not extract stream for this track${error ? `
1152
-
1153
- ${error.stack || error}` : ""}`);
1154
- if (this.queue.options.skipOnNoStream) {
1155
- this.queue.player.events.emit("playerSkip", this.queue, track);
1156
- this.queue.player.events.emit("playerError", this.queue, streamDefinitelyFailedMyDearT_TPleaseTrustMeItsNotMyFault, track);
1157
- const nextTrack = this.queue.tracks.dispatch();
1158
- if (nextTrack)
1159
- this.play(nextTrack, { queue: false });
1160
- return;
1161
- }
1162
- throw streamDefinitelyFailedMyDearT_TPleaseTrustMeItsNotMyFault;
1163
- }, "#throw");
1164
- _performPlay = new WeakSet();
1165
- performPlay_fn = /* @__PURE__ */ __name(async function(resource) {
1166
- this.queue.debug("Initializing audio player...");
1167
- await this.queue.dispatcher.playStream(resource);
1168
- this.queue.debug("Dispatching audio...");
1169
- }, "#performPlay");
1170
- _createGenericStream = new WeakSet();
1171
- createGenericStream_fn = /* @__PURE__ */ __name(async function(track) {
1172
- this.queue.debug(`Attempting to extract stream for Track { title: ${track.title}, url: ${track.url} } using registered extractors`);
1173
- const streamInfo = await this.queue.player.extractors.run(async (extractor) => {
1174
- if (this.queue.player.options.blockStreamFrom?.some((ext) => ext === extractor.identifier))
1175
- return false;
1176
- const canStream = await extractor.validate(track.url, track.queryType || QueryResolver.resolve(track.url));
1177
- if (!canStream)
1178
- return false;
1179
- return await extractor.stream(track);
1180
- }, false);
1181
- if (!streamInfo || !streamInfo.result) {
1182
- this.queue.debug(`Failed to extract stream for Track { title: ${track.title}, url: ${track.url} } using registered extractors`);
1183
- return streamInfo || null;
1184
- }
1185
- this.queue.debug(`Stream extraction was successful for Track { title: ${track.title}, url: ${track.url} } (Extractor: ${streamInfo.extractor?.identifier || "N/A"})`);
1186
- return streamInfo;
1187
- }, "#createGenericStream");
1188
- _createFFmpegStream = new WeakSet();
1189
- createFFmpegStream_fn = /* @__PURE__ */ __name(function(stream, track, seek = 0, cookies) {
1190
- const ffmpegStream = this.queue.filters.ffmpeg.createStream(stream, {
1191
- encoderArgs: this.queue.filters.ffmpeg.filters.length ? ["-af", this.queue.filters.ffmpeg.toString()] : [],
1192
- seek: seek / 1e3,
1193
- fmt: "s16le",
1194
- cookies
1195
- }).on("error", (err) => {
1196
- const m = `${err}`.toLowerCase();
1197
- this.queue.debug(`Stream closed due to an error from FFmpeg stream: ${err.stack || err.message || err}`);
1198
- if (m.includes("premature close") || m.includes("epipe"))
1199
- return;
1200
- this.queue.player.events.emit("playerError", this.queue, err, track);
1201
- });
1202
- return ffmpegStream;
1203
- }, "#createFFmpegStream");
1204
-
1205
- // src/Structures/GuildQueueAudioFilters.ts
1206
- import { Equalizer } from "@discord-player/equalizer";
1207
-
1208
- // src/utils/FFmpegStream.ts
1209
- import * as prism from "prism-media";
1210
- function FFMPEG_ARGS_STRING(stream, fmt, cookies) {
1211
- const args = [
1212
- "-reconnect",
1213
- "1",
1214
- "-reconnect_streamed",
1215
- "1",
1216
- "-reconnect_delay_max",
1217
- "5",
1218
- "-i",
1219
- stream,
1220
- "-analyzeduration",
1221
- "0",
1222
- "-loglevel",
1223
- "0",
1224
- "-f",
1225
- `${typeof fmt === "string" ? fmt : "s16le"}`,
1226
- "-ar",
1227
- "48000",
1228
- "-ac",
1229
- "2"
1230
- ];
1231
- if (typeof cookies === "string") {
1232
- args.push("-cookies", cookies.startsWith('"') ? cookies : `"${cookies}"`);
1233
- }
1234
- return args;
1235
- }
1236
- __name(FFMPEG_ARGS_STRING, "FFMPEG_ARGS_STRING");
1237
- function FFMPEG_ARGS_PIPED(fmt) {
1238
- return [
1239
- "-analyzeduration",
1240
- "0",
1241
- "-loglevel",
1242
- "0",
1243
- "-f",
1244
- `${typeof fmt === "string" ? fmt : "s16le"}`,
1245
- "-ar",
1246
- "48000",
1247
- "-ac",
1248
- "2"
1249
- ];
1250
- }
1251
- __name(FFMPEG_ARGS_PIPED, "FFMPEG_ARGS_PIPED");
1252
- function createFFmpegStream(stream, options) {
1253
- if (options?.skip && typeof stream !== "string")
1254
- return stream;
1255
- options ?? (options = {});
1256
- const args = typeof stream === "string" ? FFMPEG_ARGS_STRING(stream, options.fmt, options.cookies) : FFMPEG_ARGS_PIPED(options.fmt);
1257
- if (!Number.isNaN(options.seek))
1258
- args.unshift("-ss", String(options.seek));
1259
- if (Array.isArray(options.encoderArgs))
1260
- args.push(...options.encoderArgs);
1261
- const transcoder = new (prism.FFmpeg || prism.default.FFmpeg)({ shell: false, args });
1262
- transcoder.on("close", () => transcoder.destroy());
1263
- if (typeof stream !== "string") {
1264
- stream.on("error", () => transcoder.destroy());
1265
- stream.pipe(transcoder);
1266
- }
1267
- return transcoder;
1268
- }
1269
- __name(createFFmpegStream, "createFFmpegStream");
1270
-
1271
- // src/Structures/GuildQueueAudioFilters.ts
1272
- var makeBands = /* @__PURE__ */ __name((arr) => {
1273
- return Array.from(
1274
- {
1275
- length: Equalizer.BAND_COUNT
1276
- },
1277
- (_, i) => ({
1278
- band: i,
1279
- gain: arr[i] ? arr[i] / 30 : 0
1280
- })
1281
- );
1282
- }, "makeBands");
1283
- var EqualizerConfigurationPreset = {
1284
- Flat: makeBands([]),
1285
- Classical: makeBands([-111022e-20, -111022e-20, -111022e-20, -111022e-20, -111022e-20, -111022e-20, -7.2, -7.2, -7.2, -9.6]),
1286
- Club: makeBands([-111022e-20, -111022e-20, 8, 5.6, 5.6, 5.6, 3.2, -111022e-20, -111022e-20, -111022e-20]),
1287
- Dance: makeBands([9.6, 7.2, 2.4, -111022e-20, -111022e-20, -5.6, -7.2, -7.2, -111022e-20, -111022e-20]),
1288
- FullBass: makeBands([-8, 9.6, 9.6, 5.6, 1.6, -4, -8, -10.4, -11.2, -11.2]),
1289
- FullBassTreble: makeBands([7.2, 5.6, -111022e-20, -7.2, -4.8, 1.6, 8, 11.2, 12, 12]),
1290
- FullTreble: makeBands([-9.6, -9.6, -9.6, -4, 2.4, 11.2, 16, 16, 16, 16.8]),
1291
- Headphones: makeBands([4.8, 11.2, 5.6, -3.2, -2.4, 1.6, 4.8, 9.6, 12.8, 14.4]),
1292
- LargeHall: makeBands([10.4, 10.4, 5.6, 5.6, -111022e-20, -4.8, -4.8, -4.8, -111022e-20, -111022e-20]),
1293
- Live: makeBands([-4.8, -111022e-20, 4, 5.6, 5.6, 5.6, 4, 2.4, 2.4, 2.4]),
1294
- Party: makeBands([7.2, 7.2, -111022e-20, -111022e-20, -111022e-20, -111022e-20, -111022e-20, -111022e-20, 7.2, 7.2]),
1295
- Pop: makeBands([-1.6, 4.8, 7.2, 8, 5.6, -111022e-20, -2.4, -2.4, -1.6, -1.6]),
1296
- Reggae: makeBands([-111022e-20, -111022e-20, -111022e-20, -5.6, -111022e-20, 6.4, 6.4, -111022e-20, -111022e-20, -111022e-20]),
1297
- Rock: makeBands([8, 4.8, -5.6, -8, -3.2, 4, 8.8, 11.2, 11.2, 11.2]),
1298
- Ska: makeBands([-2.4, -4.8, -4, -111022e-20, 4, 5.6, 8.8, 9.6, 11.2, 9.6]),
1299
- Soft: makeBands([4.8, 1.6, -111022e-20, -2.4, -111022e-20, 4, 8, 9.6, 11.2, 12]),
1300
- SoftRock: makeBands([4, 4, 2.4, -111022e-20, -4, -5.6, -3.2, -111022e-20, 2.4, 8.8]),
1301
- Techno: makeBands([8, 5.6, -111022e-20, -5.6, -4.8, -111022e-20, 8, 9.6, 9.6, 8.8])
1302
- };
1303
- var _ffmpegFilters, _setFilters, setFilters_fn;
1304
- var FFmpegFilterer = class {
1305
- constructor(af) {
1306
- this.af = af;
1307
- __privateAdd(this, _setFilters);
1308
- __privateAdd(this, _ffmpegFilters, []);
1309
- }
1310
- createStream(source, options) {
1311
- return createFFmpegStream(source, options);
1312
- }
1313
- setFilters(filters) {
1314
- let _filters = [];
1315
- if (typeof filters === "boolean") {
1316
- _filters = !filters ? [] : Object.keys(AudioFilters_default.filters);
1317
- } else if (Array.isArray(filters)) {
1318
- _filters = filters;
1319
- } else {
1320
- _filters = Object.entries(filters).filter((res) => res[1] === true).map((m) => m[0]);
1321
- }
1322
- return __privateMethod(this, _setFilters, setFilters_fn).call(this, _filters);
1323
- }
1324
- get filters() {
1325
- return __privateGet(this, _ffmpegFilters);
1326
- }
1327
- set filters(filters) {
1328
- this.setFilters(filters);
1329
- }
1330
- toggle(filters) {
1331
- if (!Array.isArray(filters))
1332
- filters = [filters];
1333
- const fresh = [];
1334
- filters.forEach((f) => {
1335
- if (this.filters.includes(f))
1336
- return;
1337
- fresh.push(f);
1338
- });
1339
- return __privateMethod(this, _setFilters, setFilters_fn).call(this, __privateGet(this, _ffmpegFilters).filter((r) => !filters.includes(r)).concat(fresh));
1340
- }
1341
- setDefaults(ff) {
1342
- __privateSet(this, _ffmpegFilters, ff);
1343
- }
1344
- getFiltersEnabled() {
1345
- return __privateGet(this, _ffmpegFilters);
1346
- }
1347
- getFiltersDisabled() {
1348
- return AudioFilters_default.names.filter((f) => !__privateGet(this, _ffmpegFilters).includes(f));
1349
- }
1350
- isEnabled(filter) {
1351
- return __privateGet(this, _ffmpegFilters).includes(filter);
1352
- }
1353
- isDisabled(filter) {
1354
- return !this.isEnabled(filter);
1355
- }
1356
- isValidFilter(filter) {
1357
- return AudioFilters_default.has(filter);
1358
- }
1359
- toArray() {
1360
- return this.filters.map((filter) => AudioFilters_default.get(filter));
1361
- }
1362
- toJSON() {
1363
- const obj = {};
1364
- this.filters.forEach((filter) => obj[filter] = AudioFilters_default.get(filter));
1365
- return obj;
1366
- }
1367
- toString() {
1368
- return AudioFilters_default.create(this.filters);
1369
- }
1370
- };
1371
- __name(FFmpegFilterer, "FFmpegFilterer");
1372
- _ffmpegFilters = new WeakMap();
1373
- _setFilters = new WeakSet();
1374
- setFilters_fn = /* @__PURE__ */ __name(function(filters) {
1375
- const { queue } = this.af;
1376
- const prev = __privateGet(this, _ffmpegFilters).slice();
1377
- const ignoreFilters = this.filters.some((ff) => ff === "nightcore" || ff === "vaporwave") && !filters.some((ff) => ff === "nightcore" || ff === "vaporwave");
1378
- const seekTime = queue.node.getTimestamp(ignoreFilters)?.current.value || 0;
1379
- __privateSet(this, _ffmpegFilters, [...new Set(filters)]);
1380
- return this.af.triggerReplay(seekTime).then((t) => {
1381
- queue.player.events.emit("audioFiltersUpdate", queue, prev, __privateGet(this, _ffmpegFilters).slice());
1382
- return t;
1383
- });
1384
- }, "#setFilters");
1385
- var GuildQueueAudioFilters = class {
1386
- constructor(queue) {
1387
- this.queue = queue;
1388
- this.graph = new AFilterGraph(this);
1389
- this.ffmpeg = new FFmpegFilterer(this);
1390
- this.equalizerPresets = EqualizerConfigurationPreset;
1391
- this._lastFiltersCache = {
1392
- biquad: null,
1393
- equalizer: [],
1394
- filters: [],
1395
- volume: 100,
1396
- sampleRate: -1
1397
- };
1398
- if (typeof this.queue.options.volume === "number") {
1399
- this._lastFiltersCache.volume = this.queue.options.volume;
1400
- }
1401
- }
1402
- get volume() {
1403
- return this.queue.dispatcher?.dsp?.volume || null;
1404
- }
1405
- get equalizer() {
1406
- return this.queue.dispatcher?.equalizer || null;
1407
- }
1408
- get biquad() {
1409
- return this.queue.dispatcher?.biquad || null;
1410
- }
1411
- get filters() {
1412
- return this.queue.dispatcher?.filters || null;
1413
- }
1414
- get resampler() {
1415
- return this.queue.dispatcher?.resampler || null;
1416
- }
1417
- async triggerReplay(seek = 0) {
1418
- if (!this.queue.currentTrack)
1419
- return false;
1420
- const entry = this.queue.node.tasksQueue.acquire();
1421
- try {
1422
- await entry.getTask();
1423
- await this.queue.node.play(this.queue.currentTrack, {
1424
- queue: false,
1425
- seek,
1426
- transitionMode: true
1427
- });
1428
- this.queue.node.tasksQueue.release();
1429
- return true;
1430
- } catch {
1431
- this.queue.node.tasksQueue.release();
1432
- return false;
1433
- }
1434
- }
1435
- };
1436
- __name(GuildQueueAudioFilters, "GuildQueueAudioFilters");
1437
- var AFilterGraph = class {
1438
- constructor(af) {
1439
- this.af = af;
1440
- }
1441
- get ffmpeg() {
1442
- return this.af.ffmpeg.filters;
1443
- }
1444
- get equalizer() {
1445
- return (this.af.equalizer?.bandMultipliers || []).map((m, i) => ({
1446
- band: i,
1447
- gain: m
1448
- }));
1449
- }
1450
- get biquad() {
1451
- return null;
1452
- }
1453
- get filters() {
1454
- return this.af.filters?.filters || [];
1455
- }
1456
- get volume() {
1457
- return this.af.volume;
1458
- }
1459
- get resampler() {
1460
- return this.af.resampler;
1461
- }
1462
- dump() {
1463
- return {
1464
- ffmpeg: this.ffmpeg,
1465
- equalizer: this.equalizer,
1466
- biquad: this.biquad,
1467
- filters: this.filters,
1468
- sampleRate: this.resampler?.targetSampleRate || this.resampler?.sampleRate || 48e3,
1469
- volume: this.volume?.volume ?? 100
1470
- };
1471
- }
1472
- };
1473
- __name(AFilterGraph, "AFilterGraph");
1474
-
1475
- // src/Structures/GuildQueue.ts
1476
- import { setTimeout as setTimeout3 } from "timers";
1477
-
1478
- // src/Structures/GuildQueueStatistics.ts
1479
- var GuildQueueStatistics = class {
1480
- constructor(queue) {
1481
- this.queue = queue;
1482
- }
1483
- generate() {
1484
- return {
1485
- latency: {
1486
- eventLoop: this.queue.player.eventLoopLag,
1487
- voiceConnection: this.queue.ping
1488
- },
1489
- status: {
1490
- buffering: this.queue.node.isBuffering(),
1491
- playing: this.queue.node.isPlaying(),
1492
- paused: this.queue.node.isPaused(),
1493
- idle: this.queue.node.isIdle()
1494
- },
1495
- tracksCount: this.queue.tracks.size,
1496
- historySize: this.queue.history.tracks.size,
1497
- extractors: this.queue.player.extractors.size,
1498
- listeners: this.queue.guild.members.me?.voice.channel?.members.filter((m) => !m.user.bot).size || 0,
1499
- memoryUsage: process.memoryUsage(),
1500
- versions: {
1501
- node: process.version,
1502
- player: "6.2.0"
1503
- }
1504
- };
1505
- }
1506
- };
1507
- __name(GuildQueueStatistics, "GuildQueueStatistics");
1508
-
1509
- // src/Structures/GuildQueue.ts
1510
- var GuildQueueEvent = /* @__PURE__ */ ((GuildQueueEvent2) => {
1511
- GuildQueueEvent2["audioTrackAdd"] = "audioTrackadd";
1512
- GuildQueueEvent2["audioTracksAdd"] = "audioTracksAdd";
1513
- GuildQueueEvent2["audioTrackRemove"] = "audioTrackRemove";
1514
- GuildQueueEvent2["audioTracksRemove"] = "audioTracksRemove";
1515
- GuildQueueEvent2["connection"] = "connection";
1516
- GuildQueueEvent2["disconnect"] = "disconnect";
1517
- GuildQueueEvent2["debug"] = "debug";
1518
- GuildQueueEvent2["error"] = "error";
1519
- GuildQueueEvent2["emptyChannel"] = "emptyChannel";
1520
- GuildQueueEvent2["emptyQueue"] = "emptyQueue";
1521
- GuildQueueEvent2["playerStart"] = "playerStart";
1522
- GuildQueueEvent2["playerError"] = "playerError";
1523
- GuildQueueEvent2["playerFinish"] = "playerFinish";
1524
- GuildQueueEvent2["playerSkip"] = "playerSkip";
1525
- GuildQueueEvent2["playerTrigger"] = "playerTrigger";
1526
- GuildQueueEvent2["voiceStateUpdate"] = "voiceStateUpdate";
1527
- GuildQueueEvent2["volumeChange"] = "volumeChange";
1528
- GuildQueueEvent2["playerPause"] = "playerPause";
1529
- GuildQueueEvent2["playerResume"] = "playerResume";
1530
- GuildQueueEvent2["biquadFiltersUpdate"] = "biquadFiltersUpdate";
1531
- GuildQueueEvent2["equalizerUpdate"] = "equalizerUpdate";
1532
- GuildQueueEvent2["dspUpdate"] = "dspUpdate";
1533
- GuildQueueEvent2["audioFiltersUpdate"] = "audioFiltersUpdate";
1534
- return GuildQueueEvent2;
1535
- })(GuildQueueEvent || {});
1536
- var _transitioning, _deleted, _attachListeners, attachListeners_fn, _removeListeners, removeListeners_fn, _performStart, performStart_fn, _performFinish, performFinish_fn, _emitEnd, emitEnd_fn, _handleAutoplay, handleAutoplay_fn;
1537
- var GuildQueue = class {
1538
- constructor(player, options) {
1539
- this.player = player;
1540
- this.options = options;
1541
- __privateAdd(this, _attachListeners);
1542
- __privateAdd(this, _removeListeners);
1543
- __privateAdd(this, _performStart);
1544
- __privateAdd(this, _performFinish);
1545
- __privateAdd(this, _emitEnd);
1546
- __privateAdd(this, _handleAutoplay);
1547
- __privateAdd(this, _transitioning, false);
1548
- __privateAdd(this, _deleted, false);
1549
- this.__current = null;
1550
- this.history = new GuildQueueHistory(this);
1551
- this.dispatcher = null;
1552
- this.node = new GuildQueuePlayerNode(this);
1553
- this.filters = new GuildQueueAudioFilters(this);
1554
- this.onBeforeCreateStream = /* @__PURE__ */ __name(async () => null, "onBeforeCreateStream");
1555
- this.onAfterCreateStream = /* @__PURE__ */ __name(async (stream) => ({
1556
- stream,
1557
- type: StreamType2.Raw
1558
- }), "onAfterCreateStream");
1559
- this.repeatMode = 0 /* OFF */;
1560
- this.timeouts = new Collection2();
1561
- this.stats = new GuildQueueStatistics(this);
1562
- this.tasksQueue = new AsyncQueue();
1563
- this.tracks = new Queue2(options.queueStrategy);
1564
- if (TypeUtil.isFunction(options.onBeforeCreateStream))
1565
- this.onBeforeCreateStream = options.onBeforeCreateStream;
1566
- if (TypeUtil.isFunction(options.onAfterCreateStream))
1567
- this.onAfterCreateStream = options.onAfterCreateStream;
1568
- if (!TypeUtil.isNullish(options.repeatMode))
1569
- this.repeatMode = options.repeatMode;
1570
- options.selfDeaf ?? (options.selfDeaf = true);
1571
- if (!TypeUtil.isNullish(this.options.biquad) && !TypeUtil.isBoolean(this.options.biquad)) {
1572
- this.filters._lastFiltersCache.biquad = this.options.biquad;
1573
- }
1574
- if (Array.isArray(this.options.equalizer)) {
1575
- this.filters._lastFiltersCache.equalizer = this.options.equalizer;
1576
- }
1577
- if (Array.isArray(this.options.filterer)) {
1578
- this.filters._lastFiltersCache.filters = this.options.filterer;
1579
- }
1580
- if (TypeUtil.isNumber(this.options.resampler)) {
1581
- this.filters._lastFiltersCache.sampleRate = this.options.resampler;
1582
- }
1583
- if (TypeUtil.isArray(this.options.ffmpegFilters)) {
1584
- this.filters.ffmpeg.setDefaults(this.options.ffmpegFilters);
1585
- }
1586
- this.debug(`GuildQueue initialized for guild ${this.options.guild.name} (ID: ${this.options.guild.id})`);
1587
- }
1588
- get estimatedDuration() {
1589
- return this.tracks.store.reduce((a, c) => a + c.durationMS, 0);
1590
- }
1591
- get durationFormatted() {
1592
- return Util.buildTimeCode(Util.parseMS(this.estimatedDuration));
1593
- }
1594
- get voiceReceiver() {
1595
- return this.dispatcher?.receiver ?? null;
1596
- }
1597
- debug(m) {
1598
- this.player.events.emit("debug", this, m);
1599
- }
1600
- get metadata() {
1601
- return this.options.metadata;
1602
- }
1603
- set metadata(m) {
1604
- this.options.metadata = m;
1605
- }
1606
- setMetadata(m) {
1607
- this.options.metadata = m;
1608
- }
1609
- get currentTrack() {
1610
- return this.dispatcher?.audioResource?.metadata || this.__current;
1611
- }
1612
- get deleted() {
1613
- return __privateGet(this, _deleted);
1614
- }
1615
- get channel() {
1616
- return this.dispatcher?.channel || null;
1617
- }
1618
- set channel(c) {
1619
- if (this.dispatcher) {
1620
- if (c) {
1621
- this.dispatcher.channel = c;
1622
- } else {
1623
- this.delete();
1624
- }
1625
- }
1626
- }
1627
- get connection() {
1628
- return this.dispatcher?.voiceConnection || null;
1629
- }
1630
- get guild() {
1631
- return this.options.guild;
1632
- }
1633
- get id() {
1634
- return this.guild.id;
1635
- }
1636
- setTransitioning(state) {
1637
- __privateSet(this, _transitioning, state);
1638
- }
1639
- isTransitioning() {
1640
- return __privateGet(this, _transitioning);
1641
- }
1642
- setRepeatMode(mode) {
1643
- this.repeatMode = mode;
1644
- }
1645
- get size() {
1646
- return this.tracks.size;
1647
- }
1648
- getSize() {
1649
- return this.size;
1650
- }
1651
- clear() {
1652
- this.tracks.clear();
1653
- this.history.clear();
1654
- }
1655
- isEmpty() {
1656
- return this.tracks.size < 1;
1657
- }
1658
- isPlaying() {
1659
- return this.dispatcher?.audioResource != null && !this.dispatcher.audioResource.ended;
1660
- }
1661
- addTrack(track) {
1662
- const toAdd = track instanceof Playlist ? track.tracks : track;
1663
- this.tracks.add(toAdd);
1664
- const isMulti = Array.isArray(toAdd);
1665
- if (isMulti) {
1666
- this.player.events.emit("audioTracksAdd", this, toAdd);
1667
- } else {
1668
- this.player.events.emit("audioTrackAdd", this, toAdd);
1669
- }
1670
- }
1671
- removeTrack(track) {
1672
- return this.node.remove(track);
1673
- }
1674
- insertTrack(track, index = 0) {
1675
- return this.node.insert(track, index);
1676
- }
1677
- moveTrack(track, index = 0) {
1678
- return this.node.move(track, index);
1679
- }
1680
- copyTrack(track, index = 0) {
1681
- return this.node.copy(track, index);
1682
- }
1683
- swapTracks(src, dest) {
1684
- return this.node.swap(src, dest);
1685
- }
1686
- async connect(channelResolvable, options = {}) {
1687
- const channel = this.player.client.channels.resolve(channelResolvable);
1688
- if (!channel || !channel.isVoiceBased()) {
1689
- throw new Error(`Expected a voice based channel (type ${ChannelType.GuildVoice}/${ChannelType.GuildStageVoice}), received ${channel?.type}`);
1690
- }
1691
- this.debug(`Connecting to ${channel.type === ChannelType.GuildStageVoice ? "stage" : "voice"} channel ${channel.name} (ID: ${channel.id})`);
1692
- if (this.dispatcher) {
1693
- this.debug("Destroying old connection");
1694
- __privateMethod(this, _removeListeners, removeListeners_fn).call(this, this.dispatcher);
1695
- this.dispatcher.disconnect();
1696
- }
1697
- this.dispatcher = await this.player.voiceUtils.connect(channel, {
1698
- deaf: options.deaf ?? this.options.selfDeaf ?? true,
1699
- maxTime: options?.timeout ?? this.options.connectionTimeout ?? 12e4,
1700
- queue: this,
1701
- audioPlayer: options?.audioPlayer
1702
- });
1703
- this.player.events.emit("connection", this);
1704
- if (this.channel.type === ChannelType.GuildStageVoice) {
1705
- await this.channel.guild.members.me.voice.setSuppressed(false).catch(async () => {
1706
- return await this.channel.guild.members.me.voice.setRequestToSpeak(true).catch(Util.noop);
1707
- });
1708
- }
1709
- __privateMethod(this, _attachListeners, attachListeners_fn).call(this, this.dispatcher);
1710
- return this;
1711
- }
1712
- get ping() {
1713
- return this.connection?.ping.udp ?? -1;
1714
- }
1715
- delete() {
1716
- if (this.player.nodes.delete(this.id)) {
1717
- __privateSet(this, _deleted, true);
1718
- }
1719
- }
1720
- revive() {
1721
- if (!this.deleted || this.player.nodes.has(this.id))
1722
- return;
1723
- __privateSet(this, _deleted, false);
1724
- this.player.nodes.cache.set(this.id, this);
1725
- }
1726
- setSelfDeaf(mode, reason) {
1727
- return this.guild.members.me.voice.setDeaf(mode, reason);
1728
- }
1729
- setSelfMute(mode, reason) {
1730
- return this.guild.members.me.voice.setMute(mode, reason);
1731
- }
1732
- };
1733
- __name(GuildQueue, "GuildQueue");
1734
- _transitioning = new WeakMap();
1735
- _deleted = new WeakMap();
1736
- _attachListeners = new WeakSet();
1737
- attachListeners_fn = /* @__PURE__ */ __name(function(dispatcher) {
1738
- dispatcher.on("error", (e) => this.player.events.emit("error", this, e));
1739
- dispatcher.on("debug", (m) => this.player.events.emit("debug", this, m));
1740
- dispatcher.on("finish", (r) => __privateMethod(this, _performFinish, performFinish_fn).call(this, r));
1741
- dispatcher.on("start", (r) => __privateMethod(this, _performStart, performStart_fn).call(this, r));
1742
- dispatcher.on("dsp", (f) => {
1743
- if (!Object.is(this.filters._lastFiltersCache.filters, f)) {
1744
- this.player.events.emit("dspUpdate", this, this.filters._lastFiltersCache.filters, f);
1745
- }
1746
- this.filters._lastFiltersCache.filters = f;
1747
- });
1748
- dispatcher.on("biquad", (f) => {
1749
- if (this.filters._lastFiltersCache.biquad !== f) {
1750
- this.player.events.emit("biquadFiltersUpdate", this, this.filters._lastFiltersCache.biquad, f);
1751
- }
1752
- this.filters._lastFiltersCache.biquad = f;
1753
- });
1754
- dispatcher.on("eqBands", (f) => {
1755
- if (!Object.is(f, this.filters._lastFiltersCache.equalizer)) {
1756
- this.player.events.emit("equalizerUpdate", this, this.filters._lastFiltersCache.equalizer, f);
1757
- }
1758
- this.filters._lastFiltersCache.equalizer = f;
1759
- });
1760
- dispatcher.on("volume", (f) => {
1761
- if (this.filters._lastFiltersCache.volume !== f)
1762
- this.player.events.emit("volumeChange", this, this.filters._lastFiltersCache.volume, f);
1763
- this.filters._lastFiltersCache.volume = f;
1764
- });
1765
- }, "#attachListeners");
1766
- _removeListeners = new WeakSet();
1767
- removeListeners_fn = /* @__PURE__ */ __name(function(dispatcher) {
1768
- dispatcher.removeAllListeners();
1769
- }, "#removeListeners");
1770
- _performStart = new WeakSet();
1771
- performStart_fn = /* @__PURE__ */ __name(function(resource) {
1772
- const track = resource?.metadata || this.currentTrack;
1773
- const reason = this.isTransitioning() ? "filters" : "normal";
1774
- this.debug(
1775
- `Player triggered for Track ${JSON.stringify({
1776
- title: track?.title,
1777
- reason
1778
- })}`
1779
- );
1780
- this.player.events.emit("playerTrigger", this, track, reason);
1781
- if (track && !this.isTransitioning())
1782
- this.player.events.emit("playerStart", this, track);
1783
- this.setTransitioning(false);
1784
- }, "#performStart");
1785
- _performFinish = new WeakSet();
1786
- performFinish_fn = /* @__PURE__ */ __name(function(resource) {
1787
- const track = resource?.metadata || this.currentTrack;
1788
- this.debug(
1789
- `Track ${JSON.stringify({
1790
- title: track?.title,
1791
- isTransitionMode: this.isTransitioning()
1792
- })} was marked as finished`
1793
- );
1794
- if (track && !this.isTransitioning()) {
1795
- this.debug("Adding track to history and emitting finish event since transition mode is disabled...");
1796
- this.history.push(track);
1797
- this.node.resetProgress();
1798
- this.player.events.emit("playerFinish", this, track);
1799
- if (this.tracks.size < 1 && this.repeatMode === 0 /* OFF */) {
1800
- this.debug("No more tracks left in the queue to play and repeat mode is off, initiating #emitEnd()");
1801
- __privateMethod(this, _emitEnd, emitEnd_fn).call(this);
1802
- } else {
1803
- if (this.repeatMode === 1 /* TRACK */) {
1804
- this.debug("Repeat mode is set to track, repeating last track from the history...");
1805
- this.__current = this.history.tracks.dispatch() || track;
1806
- return this.node.play(this.__current, { queue: false });
1807
- }
1808
- if (this.repeatMode === 2 /* QUEUE */) {
1809
- this.debug("Repeat mode is set to queue, moving last track from the history to current queue...");
1810
- this.tracks.add(this.history.tracks.dispatch() || track);
1811
- }
1812
- if (!this.tracks.size) {
1813
- if (this.repeatMode === 3 /* AUTOPLAY */) {
1814
- this.debug("Repeat mode is set to autoplay, initiating autoplay handler...");
1815
- __privateMethod(this, _handleAutoplay, handleAutoplay_fn).call(this, track);
1816
- return;
1817
- }
1818
- } else {
1819
- this.debug("Initializing next track of the queue...");
1820
- this.__current = this.tracks.dispatch();
1821
- this.node.play(this.__current, {
1822
- queue: false
1823
- });
1824
- }
1825
- }
1826
- }
1827
- }, "#performFinish");
1828
- _emitEnd = new WeakSet();
1829
- emitEnd_fn = /* @__PURE__ */ __name(function() {
1830
- this.__current = null;
1831
- this.player.events.emit("emptyQueue", this);
1832
- if (this.options.leaveOnEnd) {
1833
- const tm = setTimeout3(() => {
1834
- if (this.tracks.size)
1835
- return clearTimeout(tm);
1836
- this.dispatcher?.disconnect();
1837
- }, this.options.leaveOnEndCooldown).unref();
1838
- }
1839
- }, "#emitEnd");
1840
- _handleAutoplay = new WeakSet();
1841
- handleAutoplay_fn = /* @__PURE__ */ __name(async function(track) {
1842
- try {
1843
- this.debug(`Autoplay >> Finding related tracks for Track ${track.title} (${track.url}) [ext:${track.extractor?.identifier || "N/A"}]`);
1844
- const tracks = (await track.extractor?.getRelatedTracks(track))?.tracks || (await this.player.extractors.run(async (ext) => {
1845
- this.debug(`Autoplay >> Querying extractor ${ext.identifier}`);
1846
- const res = await ext.getRelatedTracks(track);
1847
- if (!res.tracks.length) {
1848
- this.debug(`Autoplay >> Extractor ${ext.identifier} failed to provide results.`);
1849
- return false;
1850
- }
1851
- this.debug(`Autoplay >> Extractor ${ext.identifier} successfully returned results.`);
1852
- return res.tracks;
1853
- }))?.result;
1854
- if (!tracks?.length) {
1855
- this.debug(`Autoplay >> No related tracks found.`);
1856
- throw "no related tracks";
1857
- }
1858
- this.debug(`Autoplay >> Picking random track from first 5 tracks...`);
1859
- const nextTrack = Util.randomChoice(tracks.slice(0, 5));
1860
- await this.node.play(nextTrack, {
1861
- queue: false,
1862
- seek: 0,
1863
- transitionMode: false
1864
- });
1865
- } catch {
1866
- return __privateMethod(this, _emitEnd, emitEnd_fn).call(this);
1867
- }
1868
- }, "#handleAutoplay");
1869
-
1870
- // src/utils/__internal__/_container.ts
1871
- import { Collection as Collection3 } from "@discord-player/utils";
1872
- var instances = new Collection3();
1873
- var globalRegistry = new Collection3();
1874
-
1875
- // src/utils/__internal__/addPlayer.ts
1876
- function addPlayer(player) {
1877
- if (instances.has(player.id))
1878
- return true;
1879
- instances.set(player.id, player);
1880
- return instances.has(player.id);
1881
- }
1882
- __name(addPlayer, "addPlayer");
1883
-
1884
- // src/utils/__internal__/clearPlayer.ts
1885
- function clearPlayer(player) {
1886
- return instances.delete(player.id);
1887
- }
1888
- __name(clearPlayer, "clearPlayer");
1889
-
1890
- // src/utils/__internal__/getPlayers.ts
1891
- function getPlayers() {
1892
- return instances.array();
1893
- }
1894
- __name(getPlayers, "getPlayers");
1895
-
1896
- // src/utils/__internal__/getGlobalRegistry.ts
1897
- function getGlobalRegistry() {
1898
- return globalRegistry;
1899
- }
1900
- __name(getGlobalRegistry, "getGlobalRegistry");
1901
-
1902
- // src/Structures/GuildNodeManager.ts
1903
- var GuildNodeManager = class {
1904
- constructor(player) {
1905
- this.player = player;
1906
- this.cache = new Collection4();
1907
- }
1908
- create(guild, options = {}) {
1909
- const server = this.player.client.guilds.resolve(guild);
1910
- if (!server) {
1911
- throw new Error("Invalid or unknown guild");
1912
- }
1913
- if (this.cache.has(server.id)) {
1914
- return this.cache.get(server.id);
1915
- }
1916
- options.strategy ?? (options.strategy = "FIFO");
1917
- options.volume ?? (options.volume = 100);
1918
- options.equalizer ?? (options.equalizer = []);
1919
- options.a_filter ?? (options.a_filter = []);
1920
- options.disableHistory ?? (options.disableHistory = false);
1921
- options.skipOnNoStream ?? (options.skipOnNoStream = false);
1922
- options.leaveOnEmpty ?? (options.leaveOnEmpty = true);
1923
- options.leaveOnEmptyCooldown ?? (options.leaveOnEmptyCooldown = 0);
1924
- options.leaveOnEnd ?? (options.leaveOnEnd = true);
1925
- options.leaveOnEndCooldown ?? (options.leaveOnEndCooldown = 0);
1926
- options.leaveOnStop ?? (options.leaveOnStop = true);
1927
- options.leaveOnStopCooldown ?? (options.leaveOnStopCooldown = 0);
1928
- options.resampler ?? (options.resampler = 48e3);
1929
- options.selfDeaf ?? (options.selfDeaf = true);
1930
- options.connectionTimeout ?? (options.connectionTimeout = this.player.options.connectionTimeout);
1931
- options.bufferingTimeout ?? (options.bufferingTimeout = 1e3);
1932
- if (getGlobalRegistry().has("@[onBeforeCreateStream]") && !options.onBeforeCreateStream) {
1933
- options.onBeforeCreateStream = getGlobalRegistry().get("@[onBeforeCreateStream]");
1934
- }
1935
- if (getGlobalRegistry().has("@[onAfterCreateStream]") && !options.onAfterCreateStream) {
1936
- options.onAfterCreateStream = getGlobalRegistry().get("@[onAfterCreateStream]");
1937
- }
1938
- const queue = new GuildQueue(this.player, {
1939
- guild: server,
1940
- queueStrategy: options.strategy,
1941
- volume: options.volume,
1942
- equalizer: options.equalizer,
1943
- filterer: options.a_filter,
1944
- biquad: options.biquad,
1945
- resampler: options.resampler,
1946
- disableHistory: options.disableHistory,
1947
- skipOnNoStream: options.skipOnNoStream,
1948
- onBeforeCreateStream: options.onBeforeCreateStream,
1949
- onAfterCreateStream: options.onAfterCreateStream,
1950
- repeatMode: options.repeatMode,
1951
- leaveOnEmpty: options.leaveOnEmpty,
1952
- leaveOnEmptyCooldown: options.leaveOnEmptyCooldown,
1953
- leaveOnEnd: options.leaveOnEnd,
1954
- leaveOnEndCooldown: options.leaveOnEndCooldown,
1955
- leaveOnStop: options.leaveOnStop,
1956
- leaveOnStopCooldown: options.leaveOnStopCooldown,
1957
- metadata: options.metadata,
1958
- connectionTimeout: options.connectionTimeout ?? 12e4,
1959
- selfDeaf: options.selfDeaf,
1960
- ffmpegFilters: options.defaultFFmpegFilters ?? [],
1961
- bufferingTimeout: options.bufferingTimeout,
1962
- noEmitInsert: options.noEmitInsert ?? false
1963
- });
1964
- this.cache.set(server.id, queue);
1965
- return queue;
1966
- }
1967
- get(node) {
1968
- const queue = this.resolve(node);
1969
- if (!queue)
1970
- return null;
1971
- return this.cache.get(queue.id) || null;
1972
- }
1973
- has(node) {
1974
- const id = node instanceof GuildQueue ? node.id : this.player.client.guilds.resolveId(node);
1975
- return this.cache.has(id);
1976
- }
1977
- delete(node) {
1978
- const queue = this.resolve(node);
1979
- if (!queue)
1980
- throw new Error("Cannot delete non-existing queue");
1981
- queue.node.stop(true);
1982
- queue.connection?.removeAllListeners();
1983
- queue.dispatcher?.removeAllListeners();
1984
- queue.dispatcher?.disconnect();
1985
- queue.timeouts.forEach((tm) => clearTimeout(tm));
1986
- queue.history.clear();
1987
- queue.tracks.clear();
1988
- return this.cache.delete(queue.id);
1989
- }
1990
- resolve(node) {
1991
- if (node instanceof GuildQueue) {
1992
- return node;
1993
- }
1994
- return this.cache.get(this.player.client.guilds.resolveId(node));
1995
- }
1996
- resolveId(node) {
1997
- const q = this.resolve(node);
1998
- return q?.id || null;
1999
- }
2000
- };
2001
- __name(GuildNodeManager, "GuildNodeManager");
2002
-
2003
- // src/Structures/VoiceReceiverNode.ts
2004
- import { PassThrough } from "stream";
2005
- import { EndBehaviorType } from "@discordjs/voice";
2006
- import * as prism2 from "prism-media";
2007
- var VoiceReceiverNode = class {
2008
- constructor(dispatcher) {
2009
- this.dispatcher = dispatcher;
2010
- }
2011
- createRawTrack(stream, data = {}) {
2012
- data.title ?? (data.title = `Recording ${Date.now()}`);
2013
- return new Track(this.dispatcher.queue.player, {
2014
- author: "Discord",
2015
- description: data.title,
2016
- title: data.title,
2017
- duration: data.duration || "0:00",
2018
- views: 0,
2019
- requestedBy: data.requestedBy,
2020
- thumbnail: data.thumbnail || "https://cdn.discordapp.com/embed/avatars/0.png",
2021
- url: data.url || "https://discord.com",
2022
- source: "arbitrary",
2023
- raw: {
2024
- engine: stream,
2025
- source: "arbitrary"
2026
- }
2027
- });
2028
- }
2029
- mergeRecordings(streams) {
2030
- throw new Error("Not implemented");
2031
- }
2032
- recordUser(user, options = {
2033
- end: EndBehaviorType.AfterSilence,
2034
- mode: "pcm",
2035
- silenceDuration: 1e3
2036
- }) {
2037
- const _user = this.dispatcher.queue.player.client.users.resolveId(user);
2038
- const passThrough = new PassThrough();
2039
- const receiver = this.dispatcher.voiceConnection.receiver;
2040
- if (!receiver)
2041
- throw new Error("Voice receiver is not available, maybe connect to a voice channel first?");
2042
- receiver.speaking.on("start", (userId) => {
2043
- if (userId === _user) {
2044
- const receiveStream = receiver.subscribe(_user, {
2045
- end: {
2046
- behavior: options.end || EndBehaviorType.AfterSilence,
2047
- duration: options.silenceDuration ?? 1e3
2048
- }
2049
- });
2050
- setImmediate(async () => {
2051
- if (options.mode === "pcm") {
2052
- const pcm = receiveStream.pipe(
2053
- new (prism2.opus || prism2.default.opus).Decoder({
2054
- channels: 2,
2055
- frameSize: 960,
2056
- rate: 48e3
2057
- })
2058
- );
2059
- return pcm.pipe(passThrough);
2060
- } else {
2061
- return receiveStream.pipe(passThrough);
2062
- }
2063
- }).unref();
2064
- }
2065
- });
2066
- return passThrough;
2067
- }
2068
- };
2069
- __name(VoiceReceiverNode, "VoiceReceiverNode");
2070
-
2071
- // src/Structures/SearchResult.ts
2072
- var SearchResult = class {
2073
- constructor(player, _data) {
2074
- this.player = player;
2075
- this._data = _data;
2076
- this._data.tracks?.forEach((track) => {
2077
- track.extractor ?? (track.extractor = this._data.extractor || null);
2078
- track.requestedBy ?? (track.requestedBy = _data.requestedBy || null);
2079
- });
2080
- }
2081
- setQueryType(type) {
2082
- this._data.queryType = type;
2083
- return this;
2084
- }
2085
- setRequestedBy(user) {
2086
- this._data.requestedBy = user;
2087
- this._data.tracks?.forEach((track) => {
2088
- track.requestedBy = user;
2089
- });
2090
- return this;
2091
- }
2092
- setExtractor(extractor) {
2093
- this._data.extractor = extractor;
2094
- this._data.tracks?.forEach((track) => {
2095
- track.extractor = extractor;
2096
- });
2097
- return this;
2098
- }
2099
- setTracks(tracks) {
2100
- this._data.tracks = tracks;
2101
- return this;
2102
- }
2103
- setQuery(query) {
2104
- this._data.query = query;
2105
- return this;
2106
- }
2107
- setPlaylist(playlist) {
2108
- this._data.playlist = playlist;
2109
- return this;
2110
- }
2111
- get query() {
2112
- return this._data.query;
2113
- }
2114
- get queryType() {
2115
- return this._data.queryType || QueryType.AUTO;
2116
- }
2117
- get extractor() {
2118
- return this._data.extractor || null;
2119
- }
2120
- get playlist() {
2121
- return this._data.playlist;
2122
- }
2123
- get tracks() {
2124
- return this._data.tracks || [];
2125
- }
2126
- get requestedBy() {
2127
- return this._data.requestedBy || null;
2128
- }
2129
- async execute() {
2130
- return this.player.search(this.query, {
2131
- searchEngine: this.queryType,
2132
- requestedBy: this.requestedBy
2133
- });
2134
- }
2135
- isEmpty() {
2136
- return !this.tracks.length;
2137
- }
2138
- hasPlaylist() {
2139
- return this.playlist != null;
2140
- }
2141
- hasTracks() {
2142
- return this.tracks.length > 0;
2143
- }
2144
- toJSON() {
2145
- return {
2146
- query: this.query,
2147
- queryType: this.queryType,
2148
- playlist: this.playlist?.toJSON(false) || null,
2149
- tracks: this.tracks.map((m) => m.toJSON(true)),
2150
- extractor: this.extractor?.identifier || null,
2151
- requestedBy: this.requestedBy?.toJSON() || null
2152
- };
2153
- }
2154
- };
2155
- __name(SearchResult, "SearchResult");
2156
-
2157
- // src/Structures/PlayerError.ts
2158
- var ErrorStatusCode = /* @__PURE__ */ ((ErrorStatusCode2) => {
2159
- ErrorStatusCode2["STREAM_ERROR"] = "StreamError";
2160
- ErrorStatusCode2["AUDIO_PLAYER_ERROR"] = "AudioPlayerError";
2161
- ErrorStatusCode2["PLAYER_ERROR"] = "PlayerError";
2162
- ErrorStatusCode2["NO_AUDIO_RESOURCE"] = "NoAudioResource";
2163
- ErrorStatusCode2["UNKNOWN_GUILD"] = "UnknownGuild";
2164
- ErrorStatusCode2["INVALID_ARG_TYPE"] = "InvalidArgType";
2165
- ErrorStatusCode2["UNKNOWN_EXTRACTOR"] = "UnknownExtractor";
2166
- ErrorStatusCode2["INVALID_EXTRACTOR"] = "InvalidExtractor";
2167
- ErrorStatusCode2["INVALID_CHANNEL_TYPE"] = "InvalidChannelType";
2168
- ErrorStatusCode2["INVALID_TRACK"] = "InvalidTrack";
2169
- ErrorStatusCode2["UNKNOWN_REPEAT_MODE"] = "UnknownRepeatMode";
2170
- ErrorStatusCode2["TRACK_NOT_FOUND"] = "TrackNotFound";
2171
- ErrorStatusCode2["NO_CONNECTION"] = "NoConnection";
2172
- ErrorStatusCode2["DESTROYED_QUEUE"] = "DestroyedQueue";
2173
- return ErrorStatusCode2;
2174
- })(ErrorStatusCode || {});
2175
- var PlayerError = class extends Error {
2176
- constructor(message, code = "PlayerError" /* PLAYER_ERROR */) {
2177
- super();
2178
- this.createdAt = new Date();
2179
- this.message = `[${code}] ${message}`;
2180
- this.statusCode = code;
2181
- this.name = code;
2182
- Error.captureStackTrace(this);
2183
- }
2184
- get createdTimestamp() {
2185
- return this.createdAt.getTime();
2186
- }
2187
- valueOf() {
2188
- return this.statusCode;
2189
- }
2190
- toJSON() {
2191
- return {
2192
- stack: this.stack,
2193
- code: this.statusCode,
2194
- message: this.message,
2195
- created: this.createdTimestamp
2196
- };
2197
- }
2198
- toString() {
2199
- return this.stack;
2200
- }
2201
- };
2202
- __name(PlayerError, "PlayerError");
2203
-
2204
- // src/VoiceInterface/VoiceUtils.ts
2205
- import { joinVoiceChannel, getVoiceConnection, VoiceConnectionStatus as VoiceConnectionStatus2 } from "@discordjs/voice";
2206
-
2207
- // src/VoiceInterface/StreamDispatcher.ts
2208
- import {
2209
- AudioPlayerStatus,
2210
- createAudioPlayer,
2211
- createAudioResource,
2212
- entersState,
2213
- StreamType as StreamType3,
2214
- VoiceConnectionStatus,
2215
- VoiceConnectionDisconnectReason,
2216
- version
2217
- } from "@discordjs/voice";
2218
- import { EventEmitter as EventEmitter2 } from "@discord-player/utils";
2219
- import { FiltersChain } from "@discord-player/equalizer";
2220
- var needsKeepAlivePatch = (() => {
2221
- if ("DP_NO_KEEPALIVE_PATCH" in process.env)
2222
- return false;
2223
- if (version.includes("-dev") || version.startsWith("1"))
2224
- return false;
2225
- const [, minor, patch] = version.split(".").map((n) => parseInt(n));
2226
- if (isNaN(minor))
2227
- return false;
2228
- return minor > 14 ? false : minor < 15 && patch < 1;
2229
- })();
2230
- var StreamDispatcher = class extends EventEmitter2 {
2231
- constructor(connection, channel, queue, connectionTimeout = 2e4, audioPlayer) {
2232
- super();
2233
- this.queue = queue;
2234
- this.connectionTimeout = connectionTimeout;
2235
- this.receiver = new VoiceReceiverNode(this);
2236
- this.readyLock = false;
2237
- this.dsp = new FiltersChain();
2238
- this.voiceConnection = connection;
2239
- this.audioPlayer = audioPlayer || createAudioPlayer({
2240
- debug: this.queue.player.events.eventNames().includes("debug")
2241
- });
2242
- this.channel = channel;
2243
- this.voiceConnection.on("debug", (m) => void this.emit("debug", m));
2244
- this.voiceConnection.on("error", (error) => void this.emit("error", error));
2245
- this.audioPlayer.on("debug", (m) => void this.emit("debug", m));
2246
- this.audioPlayer.on("error", (error) => void this.emit("error", error));
2247
- this.dsp.onUpdate = () => {
2248
- if (!this.dsp)
2249
- return;
2250
- if (this.dsp.filters?.filters)
2251
- this.emit("dsp", this.dsp.filters?.filters);
2252
- if (this.dsp.biquad?.filter)
2253
- this.emit("biquad", this.dsp.biquad?.filter);
2254
- if (this.dsp.equalizer)
2255
- this.emit("eqBands", this.dsp.equalizer.getEQ());
2256
- if (this.dsp.volume)
2257
- this.emit("volume", this.dsp.volume.volume);
2258
- if (this.dsp.resampler)
2259
- this.emit("sampleRate", this.dsp.resampler.targetSampleRate);
2260
- };
2261
- this.dsp.onError = (e) => this.emit("error", e);
2262
- this.voiceConnection.on("stateChange", async (oldState, newState) => {
2263
- if (needsKeepAlivePatch) {
2264
- this.queue.debug(`Detected @discordjs/voice version ${version} which needs keepAlive patch, applying patch...`);
2265
- const oldNetworking = Reflect.get(oldState, "networking");
2266
- const newNetworking = Reflect.get(newState, "networking");
2267
- const networkStateChangeHandler = /* @__PURE__ */ __name((_, newNetworkState) => {
2268
- const newUdp = Reflect.get(newNetworkState, "udp");
2269
- clearInterval(newUdp?.keepAliveInterval);
2270
- }, "networkStateChangeHandler");
2271
- oldNetworking?.off("stateChange", networkStateChangeHandler);
2272
- newNetworking?.on("stateChange", networkStateChangeHandler);
2273
- }
2274
- if (newState.status === VoiceConnectionStatus.Disconnected) {
2275
- if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
2276
- try {
2277
- await entersState(this.voiceConnection, VoiceConnectionStatus.Connecting, this.connectionTimeout);
2278
- } catch {
2279
- try {
2280
- if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed)
2281
- this.voiceConnection.destroy();
2282
- } catch (err) {
2283
- this.emit("error", err);
2284
- }
2285
- }
2286
- } else if (this.voiceConnection.rejoinAttempts < 5) {
2287
- await Util.wait((this.voiceConnection.rejoinAttempts + 1) * 5e3);
2288
- this.voiceConnection.rejoin();
2289
- } else {
2290
- try {
2291
- if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed)
2292
- this.voiceConnection.destroy();
2293
- } catch (err) {
2294
- this.emit("error", err);
2295
- }
2296
- }
2297
- } else if (newState.status === VoiceConnectionStatus.Destroyed) {
2298
- this.end();
2299
- } else if (!this.readyLock && (newState.status === VoiceConnectionStatus.Connecting || newState.status === VoiceConnectionStatus.Signalling)) {
2300
- this.readyLock = true;
2301
- try {
2302
- await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, this.connectionTimeout);
2303
- } catch {
2304
- if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed) {
2305
- try {
2306
- this.voiceConnection.destroy();
2307
- } catch (err) {
2308
- this.emit("error", err);
2309
- }
2310
- }
2311
- } finally {
2312
- this.readyLock = false;
2313
- }
2314
- }
2315
- });
2316
- this.audioPlayer.on("stateChange", (oldState, newState) => {
2317
- if (oldState.status !== AudioPlayerStatus.Paused && newState.status === AudioPlayerStatus.Paused) {
2318
- this.queue.player.events.emit("playerPause", this.queue);
2319
- }
2320
- if (oldState.status === AudioPlayerStatus.Paused && newState.status !== AudioPlayerStatus.Paused) {
2321
- this.queue.player.events.emit("playerResume", this.queue);
2322
- }
2323
- if (newState.status === AudioPlayerStatus.Playing) {
2324
- if (oldState.status === AudioPlayerStatus.Idle || oldState.status === AudioPlayerStatus.Buffering) {
2325
- return this.emit("start", this.audioResource);
2326
- }
2327
- } else if (newState.status === AudioPlayerStatus.Idle && oldState.status !== AudioPlayerStatus.Idle) {
2328
- this.emit("finish", this.audioResource);
2329
- this.dsp.destroy();
2330
- this.audioResource = null;
2331
- }
2332
- });
2333
- this.voiceConnection.subscribe(this.audioPlayer);
2334
- }
2335
- get paused() {
2336
- return this.audioPlayer.state.status === AudioPlayerStatus.Paused;
2337
- }
2338
- set paused(val) {
2339
- val ? this.pause(true) : this.resume();
2340
- }
2341
- isPaused() {
2342
- return this.paused || this.audioPlayer.state.status === AudioPlayerStatus.AutoPaused;
2343
- }
2344
- isBuffering() {
2345
- return this.audioPlayer.state.status === AudioPlayerStatus.Buffering;
2346
- }
2347
- isPlaying() {
2348
- return this.audioPlayer.state.status === AudioPlayerStatus.Playing;
2349
- }
2350
- isIdle() {
2351
- return this.audioPlayer.state.status === AudioPlayerStatus.Idle;
2352
- }
2353
- isDestroyed() {
2354
- return this.voiceConnection.state.status === VoiceConnectionStatus.Destroyed;
2355
- }
2356
- isDisconnected() {
2357
- return this.voiceConnection.state.status === VoiceConnectionStatus.Disconnected;
2358
- }
2359
- isReady() {
2360
- return this.voiceConnection.state.status === VoiceConnectionStatus.Ready;
2361
- }
2362
- isSignalling() {
2363
- return this.voiceConnection.state.status === VoiceConnectionStatus.Signalling;
2364
- }
2365
- isConnecting() {
2366
- return this.voiceConnection.state.status === VoiceConnectionStatus.Connecting;
2367
- }
2368
- async createStream(src, ops) {
2369
- if (!ops?.disableFilters)
2370
- this.queue.debug("Initiating DSP filters pipeline...");
2371
- const stream = !ops?.disableFilters ? this.dsp.create(src, {
2372
- dsp: {
2373
- filters: ops?.defaultFilters,
2374
- disabled: ops?.disableFilters
2375
- },
2376
- biquad: ops?.biquadFilter ? {
2377
- filter: ops.biquadFilter,
2378
- disabled: ops?.disableBiquad
2379
- } : void 0,
2380
- resampler: {
2381
- targetSampleRate: ops?.sampleRate,
2382
- disabled: ops?.disableResampler
2383
- },
2384
- equalizer: {
2385
- bandMultiplier: ops?.eq,
2386
- disabled: ops?.disableEqualizer
2387
- },
2388
- volume: {
2389
- volume: ops?.volume,
2390
- disabled: ops?.disableVolume
2391
- }
2392
- }) : src;
2393
- this.queue.debug("Executing onAfterCreateStream hook...");
2394
- const postStream = await this.queue.onAfterCreateStream?.(stream, this.queue).catch(
2395
- () => ({
2396
- stream,
2397
- type: ops?.type ?? StreamType3.Arbitrary
2398
- })
2399
- );
2400
- this.queue.debug("Preparing AudioResource...");
2401
- this.audioResource = createAudioResource(postStream?.stream ?? stream, {
2402
- inputType: postStream?.type ?? ops?.type ?? StreamType3.Arbitrary,
2403
- metadata: ops?.data,
2404
- inlineVolume: false
2405
- });
2406
- return this.audioResource;
2407
- }
2408
- get resampler() {
2409
- return this.dsp?.resampler;
2410
- }
2411
- get filters() {
2412
- return this.dsp?.filters;
2413
- }
2414
- get biquad() {
2415
- return this.dsp?.biquad || null;
2416
- }
2417
- get equalizer() {
2418
- return this.dsp?.equalizer || null;
2419
- }
2420
- get status() {
2421
- return this.audioPlayer.state.status;
2422
- }
2423
- disconnect() {
2424
- try {
2425
- if (this.audioPlayer)
2426
- this.audioPlayer.stop(true);
2427
- if (this.voiceConnection.state.status !== VoiceConnectionStatus.Destroyed)
2428
- this.voiceConnection.destroy();
2429
- } catch {
2430
- }
2431
- }
2432
- end() {
2433
- try {
2434
- this.audioPlayer.stop();
2435
- } catch {
2436
- }
2437
- }
2438
- pause(interpolateSilence) {
2439
- const success = this.audioPlayer.pause(interpolateSilence);
2440
- return success;
2441
- }
2442
- resume() {
2443
- const success = this.audioPlayer.unpause();
2444
- return success;
2445
- }
2446
- async playStream(resource = this.audioResource) {
2447
- if (!resource)
2448
- throw new PlayerError("Audio resource is not available!", "NoAudioResource" /* NO_AUDIO_RESOURCE */);
2449
- if (resource.ended) {
2450
- return void this.emit("finish", resource);
2451
- }
2452
- if (!this.audioResource)
2453
- this.audioResource = resource;
2454
- if (this.voiceConnection.state.status !== VoiceConnectionStatus.Ready) {
2455
- try {
2456
- await entersState(this.voiceConnection, VoiceConnectionStatus.Ready, this.connectionTimeout);
2457
- } catch (err) {
2458
- return void this.emit("error", err);
2459
- }
2460
- }
2461
- try {
2462
- this.audioPlayer.play(resource);
2463
- } catch (e) {
2464
- this.emit("error", e);
2465
- }
2466
- return this;
2467
- }
2468
- setVolume(value) {
2469
- if (!this.dsp.volume)
2470
- return false;
2471
- return this.dsp.volume.setVolume(value);
2472
- }
2473
- get volume() {
2474
- if (!this.dsp.volume)
2475
- return 100;
2476
- return this.dsp.volume.volume;
2477
- }
2478
- get streamTime() {
2479
- if (!this.audioResource)
2480
- return 0;
2481
- return this.audioResource.playbackDuration;
2482
- }
2483
- };
2484
- __name(StreamDispatcher, "StreamDispatcher");
2485
-
2486
- // src/VoiceInterface/VoiceUtils.ts
2487
- import { Collection as Collection5 } from "@discord-player/utils";
2488
- var VoiceUtils = class {
2489
- constructor(player) {
2490
- this.player = player;
2491
- this.cache = new Collection5();
2492
- }
2493
- async connect(channel, options) {
2494
- if (!options?.queue)
2495
- throw new Error("GuildQueue is required");
2496
- const conn = await this.join(channel, options);
2497
- const sub = new StreamDispatcher(conn, channel, options.queue, options.maxTime, options.audioPlayer);
2498
- this.cache.set(channel.guild.id, sub);
2499
- return sub;
2500
- }
2501
- async join(channel, options) {
2502
- const conn = joinVoiceChannel({
2503
- guildId: channel.guild.id,
2504
- channelId: channel.id,
2505
- adapterCreator: channel.guild.voiceAdapterCreator,
2506
- selfDeaf: Boolean(options?.deaf),
2507
- debug: this.player.events.eventNames().includes("debug")
2508
- });
2509
- return conn;
2510
- }
2511
- disconnect(connection) {
2512
- if (connection instanceof StreamDispatcher)
2513
- connection = connection.voiceConnection;
2514
- try {
2515
- if (connection.state.status !== VoiceConnectionStatus2.Destroyed)
2516
- return connection.destroy();
2517
- } catch {
2518
- }
2519
- }
2520
- getConnection(guild) {
2521
- return this.cache.get(guild) || getVoiceConnection(guild);
2522
- }
2523
- };
2524
- __name(VoiceUtils, "VoiceUtils");
2525
-
2526
- // src/utils/QueryCache.ts
2527
- var DEFAULT_EXPIRY_TIMEOUT = 18e6;
2528
- var _defaultCache;
2529
- var QueryCache = class {
2530
- constructor(player, options = {
2531
- checkInterval: DEFAULT_EXPIRY_TIMEOUT
2532
- }) {
2533
- this.player = player;
2534
- this.options = options;
2535
- __privateAdd(this, _defaultCache, /* @__PURE__ */ new Map());
2536
- this.timer = setInterval(this.cleanup.bind(this), this.checkInterval).unref();
2537
- }
2538
- get checkInterval() {
2539
- return this.options.checkInterval ?? DEFAULT_EXPIRY_TIMEOUT;
2540
- }
2541
- async cleanup() {
2542
- for (const [id, value] of __privateGet(this, _defaultCache)) {
2543
- if (value.hasExpired()) {
2544
- __privateGet(this, _defaultCache).delete(id);
2545
- }
2546
- }
2547
- }
2548
- async clear() {
2549
- __privateGet(this, _defaultCache).clear();
2550
- }
2551
- async getData() {
2552
- return [...__privateGet(this, _defaultCache).values()];
2553
- }
2554
- async addData(data) {
2555
- data.tracks.forEach((d) => {
2556
- if (__privateGet(this, _defaultCache).has(d.url))
2557
- return;
2558
- __privateGet(this, _defaultCache).set(d.url, new DiscordPlayerQueryResultCache(d));
2559
- });
2560
- }
2561
- async resolve(context) {
2562
- const result = __privateGet(this, _defaultCache).get(context.query);
2563
- if (!result)
2564
- return new SearchResult(this.player, {
2565
- query: context.query,
2566
- requestedBy: context.requestedBy,
2567
- queryType: context.queryType
2568
- });
2569
- return new SearchResult(this.player, {
2570
- query: context.query,
2571
- tracks: [result.data],
2572
- playlist: null,
2573
- queryType: context.queryType,
2574
- requestedBy: context.requestedBy
2575
- });
2576
- }
2577
- };
2578
- __name(QueryCache, "QueryCache");
2579
- _defaultCache = new WeakMap();
2580
- var DiscordPlayerQueryResultCache = class {
2581
- constructor(data, expireAfter = DEFAULT_EXPIRY_TIMEOUT) {
2582
- this.data = data;
2583
- this.expireAfter = DEFAULT_EXPIRY_TIMEOUT;
2584
- if (typeof expireAfter === "number") {
2585
- this.expireAfter = Date.now() + expireAfter;
2586
- }
2587
- }
2588
- hasExpired() {
2589
- if (typeof this.expireAfter !== "number" || isNaN(this.expireAfter) || this.expireAfter < 1)
2590
- return false;
2591
- return Date.now() <= this.expireAfter;
2592
- }
2593
- };
2594
- __name(DiscordPlayerQueryResultCache, "DiscordPlayerQueryResultCache");
2595
-
2596
- // src/Player.ts
2597
- import { SnowflakeUtil as SnowflakeUtil3, IntentsBitField, ChannelType as ChannelType2 } from "discord.js";
2598
- import { generateDependencyReport } from "@discordjs/voice";
2599
- var kSingleton = Symbol("InstanceDiscordPlayerSingleton");
2600
- var _lastLatency, _voiceStateUpdateListener, _lagMonitorTimeout, _lagMonitorInterval;
2601
- var _Player = class extends PlayerEventsEmitter {
2602
- constructor(client, options = {}) {
2603
- if (!options.ignoreInstance && kSingleton in _Player)
2604
- return _Player[kSingleton];
2605
- super(["error"]);
2606
- __privateAdd(this, _lastLatency, -1);
2607
- __privateAdd(this, _voiceStateUpdateListener, this.handleVoiceState.bind(this));
2608
- __privateAdd(this, _lagMonitorTimeout, void 0);
2609
- __privateAdd(this, _lagMonitorInterval, void 0);
2610
- this.id = SnowflakeUtil3.generate().toString();
2611
- this.nodes = new GuildNodeManager(this);
2612
- this.voiceUtils = new VoiceUtils(this);
2613
- this.extractors = new ExtractorExecutionContext(this);
2614
- this.events = new PlayerEventsEmitter(["error", "playerError"]);
2615
- this.client = client;
2616
- if (this.client?.options?.intents && !new IntentsBitField(this.client?.options?.intents).has(IntentsBitField.Flags.GuildVoiceStates)) {
2617
- Util.warn('client is missing "GuildVoiceStates" intent', "InvalidIntentsBitField");
2618
- }
2619
- this.options = {
2620
- autoRegisterExtractor: true,
2621
- lockVoiceStateHandler: false,
2622
- blockExtractors: [],
2623
- blockStreamFrom: [],
2624
- connectionTimeout: 2e4,
2625
- smoothVolume: true,
2626
- lagMonitor: 3e4,
2627
- queryCache: options.queryCache === null ? null : new QueryCache(this),
2628
- ...options,
2629
- ytdlOptions: {
2630
- highWaterMark: 1 << 25,
2631
- ...options.ytdlOptions
2632
- }
2633
- };
2634
- this.client.on("voiceStateUpdate", __privateGet(this, _voiceStateUpdateListener));
2635
- if (this.options?.autoRegisterExtractor) {
2636
- Util.warn('Use of "<Player>[options.autoRegisterExtractor]" is deprecated, use "await <Player>.extractors.loadDefault()" instead!');
2637
- this.extractors.loadDefault().then((r) => {
2638
- if (r.error) {
2639
- this.emit("error", new Error(`Failed to load default extractors: ${r.error?.stack ?? r.error}`));
2640
- } else {
2641
- this.debug("Default extractors loaded!");
2642
- }
2643
- this.debug(`[Dependencies Report]
2644
- ${this.scanDeps()}`);
2645
- });
2646
- }
2647
- if (typeof this.options.lagMonitor === "number" && this.options.lagMonitor > 0) {
2648
- __privateSet(this, _lagMonitorInterval, setInterval(() => {
2649
- const start = performance.now();
2650
- __privateSet(this, _lagMonitorTimeout, setTimeout(() => {
2651
- __privateSet(this, _lastLatency, performance.now() - start);
2652
- this.debug(`[Lag Monitor] Event loop latency: ${__privateGet(this, _lastLatency)}ms`);
2653
- }, 0).unref());
2654
- }, this.options.lagMonitor).unref());
2655
- }
2656
- addPlayer(this);
2657
- if (!(kSingleton in _Player)) {
2658
- Object.defineProperty(_Player, kSingleton, {
2659
- value: this,
2660
- writable: true,
2661
- configurable: true,
2662
- enumerable: false
2663
- });
2664
- }
2665
- }
2666
- debug(m) {
2667
- return this.emit("debug", m);
2668
- }
2669
- static singleton(client, options = {}) {
2670
- return new _Player(client, {
2671
- ...options,
2672
- ignoreInstance: false
2673
- });
2674
- }
2675
- static getAllPlayers() {
2676
- return getPlayers();
2677
- }
2678
- static clearAllPlayers() {
2679
- return instances.clear();
2680
- }
2681
- get queryCache() {
2682
- return this.options.queryCache ?? null;
2683
- }
2684
- get queues() {
2685
- return this.nodes;
2686
- }
2687
- get eventLoopLag() {
2688
- return __privateGet(this, _lastLatency);
2689
- }
2690
- generateStatistics() {
2691
- return {
2692
- instances: instances.size,
2693
- queuesCount: this.queues.cache.size,
2694
- queryCacheEnabled: this.queryCache != null,
2695
- queues: this.queues.cache.map((m) => m.stats.generate())
2696
- };
2697
- }
2698
- async destroy() {
2699
- this.nodes.cache.forEach((node) => node.delete());
2700
- this.client.off("voiceStateUpdate", __privateGet(this, _voiceStateUpdateListener));
2701
- this.removeAllListeners();
2702
- this.events.removeAllListeners();
2703
- await this.extractors.unregisterAll();
2704
- if (__privateGet(this, _lagMonitorInterval))
2705
- clearInterval(__privateGet(this, _lagMonitorInterval));
2706
- if (__privateGet(this, _lagMonitorTimeout))
2707
- clearInterval(__privateGet(this, _lagMonitorTimeout));
2708
- clearPlayer(this);
2709
- }
2710
- _handleVoiceState(oldState, newState) {
2711
- const queue = this.nodes.get(oldState.guild.id);
2712
- if (!queue || !queue.connection || !queue.channel)
2713
- return;
2714
- const wasHandled = this.events.emit("voiceStateUpdate", queue, oldState, newState);
2715
- if (wasHandled && !this.options.lockVoiceStateHandler)
2716
- return;
2717
- if (oldState.channelId && !newState.channelId && newState.member?.id === newState.guild.members.me?.id) {
2718
- try {
2719
- queue.delete();
2720
- } catch {
2721
- }
2722
- return void this.events.emit("disconnect", queue);
2723
- }
2724
- if (!oldState.channelId && newState.channelId && newState.member?.id === newState.guild.members.me?.id) {
2725
- if (newState.serverMute != null && oldState.serverMute !== newState.serverMute) {
2726
- queue.node.setPaused(newState.serverMute);
2727
- } else if (newState.channel?.type === ChannelType2.GuildStageVoice && newState.suppress != null && oldState.suppress !== newState.suppress) {
2728
- queue.node.setPaused(newState.suppress);
2729
- if (newState.suppress) {
2730
- newState.guild.members.me?.voice.setRequestToSpeak(true).catch(Util.noop);
2731
- }
2732
- }
2733
- }
2734
- if (!newState.channelId && oldState.channelId === queue.channel.id) {
2735
- if (!Util.isVoiceEmpty(queue.channel))
2736
- return;
2737
- const timeout = setTimeout(() => {
2738
- if (!Util.isVoiceEmpty(queue.channel))
2739
- return;
2740
- if (!this.nodes.has(queue.guild.id))
2741
- return;
2742
- if (queue.options.leaveOnEmpty)
2743
- queue.delete();
2744
- this.events.emit("emptyChannel", queue);
2745
- }, queue.options.leaveOnEmptyCooldown || 0).unref();
2746
- queue.timeouts.set(`empty_${oldState.guild.id}`, timeout);
2747
- }
2748
- if (newState.channelId && newState.channelId === queue.channel.id) {
2749
- const emptyTimeout = queue.timeouts.get(`empty_${oldState.guild.id}`);
2750
- const channelEmpty = Util.isVoiceEmpty(queue.channel);
2751
- if (!channelEmpty && emptyTimeout) {
2752
- clearTimeout(emptyTimeout);
2753
- queue.timeouts.delete(`empty_${oldState.guild.id}`);
2754
- }
2755
- }
2756
- if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId) {
2757
- if (newState.member?.id === newState.guild.members.me?.id) {
2758
- if (queue.connection && newState.member?.id === newState.guild.members.me?.id)
2759
- queue.channel = newState.channel;
2760
- const emptyTimeout = queue.timeouts.get(`empty_${oldState.guild.id}`);
2761
- const channelEmpty = Util.isVoiceEmpty(queue.channel);
2762
- if (!channelEmpty && emptyTimeout) {
2763
- clearTimeout(emptyTimeout);
2764
- queue.timeouts.delete(`empty_${oldState.guild.id}`);
2765
- } else {
2766
- const timeout = setTimeout(() => {
2767
- if (queue.connection && !Util.isVoiceEmpty(queue.channel))
2768
- return;
2769
- if (!this.nodes.has(queue.guild.id))
2770
- return;
2771
- if (queue.options.leaveOnEmpty)
2772
- queue.delete();
2773
- this.events.emit("emptyChannel", queue);
2774
- }, queue.options.leaveOnEmptyCooldown || 0).unref();
2775
- queue.timeouts.set(`empty_${oldState.guild.id}`, timeout);
2776
- }
2777
- } else {
2778
- if (newState.channelId !== queue.channel.id) {
2779
- if (!Util.isVoiceEmpty(queue.channel))
2780
- return;
2781
- if (queue.timeouts.has(`empty_${oldState.guild.id}`))
2782
- return;
2783
- const timeout = setTimeout(() => {
2784
- if (!Util.isVoiceEmpty(queue.channel))
2785
- return;
2786
- if (!this.nodes.has(queue.guild.id))
2787
- return;
2788
- if (queue.options.leaveOnEmpty)
2789
- queue.delete();
2790
- this.events.emit("emptyChannel", queue);
2791
- }, queue.options.leaveOnEmptyCooldown || 0).unref();
2792
- queue.timeouts.set(`empty_${oldState.guild.id}`, timeout);
2793
- } else {
2794
- const emptyTimeout = queue.timeouts.get(`empty_${oldState.guild.id}`);
2795
- const channelEmpty = Util.isVoiceEmpty(queue.channel);
2796
- if (!channelEmpty && emptyTimeout) {
2797
- clearTimeout(emptyTimeout);
2798
- queue.timeouts.delete(`empty_${oldState.guild.id}`);
2799
- }
2800
- }
2801
- }
2802
- }
2803
- }
2804
- handleVoiceState(oldState, newState) {
2805
- this._handleVoiceState(oldState, newState);
2806
- }
2807
- lockVoiceStateHandler() {
2808
- this.options.lockVoiceStateHandler = true;
2809
- }
2810
- unlockVoiceStateHandler() {
2811
- this.options.lockVoiceStateHandler = false;
2812
- }
2813
- isVoiceStateHandlerLocked() {
2814
- return !!this.options.lockVoiceStateHandler;
2815
- }
2816
- async play(channel, query, options = {}) {
2817
- const vc = this.client.channels.resolve(channel);
2818
- if (!vc?.isVoiceBased())
2819
- throw new Error("Expected a voice channel");
2820
- const originalResult = query instanceof SearchResult ? query : await this.search(query, options);
2821
- const result = await options.afterSearch?.(originalResult) || originalResult;
2822
- if (result.isEmpty()) {
2823
- throw new Error(`No results found for "${query}" (Extractor: ${result.extractor?.identifier || "N/A"})`);
2824
- }
2825
- const queue = this.nodes.create(vc.guild, options.nodeOptions);
2826
- this.debug(`[AsyncQueue] Acquiring an entry...`);
2827
- const entry = queue.tasksQueue.acquire();
2828
- this.debug(`[AsyncQueue] Entry ${entry.id} was acquired successfully!`);
2829
- this.debug(`[AsyncQueue] Waiting for the queue to resolve...`);
2830
- await entry.getTask();
2831
- this.debug(`[AsyncQueue] Entry ${entry.id} was resolved!`);
2832
- try {
2833
- if (!queue.channel)
2834
- await queue.connect(vc, options.connectionOptions);
2835
- if (!result.playlist) {
2836
- queue.addTrack(result.tracks[0]);
2837
- } else {
2838
- queue.addTrack(result.playlist);
2839
- }
2840
- if (!queue.isPlaying())
2841
- await queue.node.play();
2842
- } finally {
2843
- this.debug(`[AsyncQueue] Releasing an entry from the queue...`);
2844
- queue.tasksQueue.release();
2845
- }
2846
- return {
2847
- track: result.tracks[0],
2848
- extractor: result.extractor,
2849
- searchResult: result,
2850
- queue
2851
- };
2852
- }
2853
- async search(query, options = {}) {
2854
- if (query instanceof SearchResult)
2855
- return query;
2856
- if (options.requestedBy != null)
2857
- options.requestedBy = this.client.users.resolve(options.requestedBy);
2858
- options.blockExtractors ?? (options.blockExtractors = this.options.blockExtractors);
2859
- options.fallbackSearchEngine ?? (options.fallbackSearchEngine = QueryType.AUTO_SEARCH);
2860
- if (query instanceof Track) {
2861
- return new SearchResult(this, {
2862
- playlist: query.playlist || null,
2863
- tracks: [query],
2864
- query: query.title,
2865
- extractor: query.extractor,
2866
- queryType: query.queryType,
2867
- requestedBy: options.requestedBy
2868
- });
2869
- }
2870
- if (query instanceof Playlist) {
2871
- return new SearchResult(this, {
2872
- playlist: query,
2873
- tracks: query.tracks,
2874
- query: query.title,
2875
- extractor: query.tracks[0]?.extractor,
2876
- queryType: QueryType.AUTO,
2877
- requestedBy: options.requestedBy
2878
- });
2879
- }
2880
- if (Array.isArray(query)) {
2881
- const tracks = query.filter((t) => t instanceof Track);
2882
- return new SearchResult(this, {
2883
- playlist: null,
2884
- tracks,
2885
- query: "@@#%{{UserLoadedContent}}%#@@",
2886
- extractor: null,
2887
- queryType: QueryType.AUTO,
2888
- requestedBy: options.requestedBy
2889
- });
2890
- }
2891
- this.debug(`Searching ${query}`);
2892
- let extractor = null;
2893
- options.searchEngine ?? (options.searchEngine = QueryType.AUTO);
2894
- this.debug(`Search engine set to ${options.searchEngine}`);
2895
- const queryType = options.searchEngine === QueryType.AUTO ? QueryResolver.resolve(query, options.fallbackSearchEngine) : options.searchEngine;
2896
- this.debug(`Query type identified as ${queryType}`);
2897
- if (options.searchEngine.startsWith("ext:")) {
2898
- extractor = this.extractors.get(options.searchEngine.substring(4));
2899
- if (!extractor)
2900
- return new SearchResult(this, {
2901
- query,
2902
- queryType,
2903
- extractor,
2904
- requestedBy: options.requestedBy
2905
- });
2906
- }
2907
- if (!extractor) {
2908
- if (!options.ignoreCache) {
2909
- this.debug(`Checking cache...`);
2910
- const res2 = await this.queryCache?.resolve({
2911
- query,
2912
- queryType,
2913
- requestedBy: options.requestedBy
2914
- });
2915
- if (res2?.hasTracks()) {
2916
- this.debug(`Cache hit for query ${query}`);
2917
- return res2;
2918
- }
2919
- this.debug(`Cache miss for query ${query}`);
2920
- }
2921
- this.debug(`Executing extractors...`);
2922
- extractor = (await this.extractors.run(async (ext) => {
2923
- if (options.blockExtractors?.includes(ext.identifier))
2924
- return false;
2925
- return ext.validate(query, queryType);
2926
- }))?.extractor || null;
2927
- }
2928
- if (!extractor) {
2929
- this.debug("Failed to find appropriate extractor");
2930
- return new SearchResult(this, {
2931
- query,
2932
- queryType,
2933
- requestedBy: options.requestedBy
2934
- });
2935
- }
2936
- this.debug(`Executing metadata query using ${extractor.identifier} extractor...`);
2937
- const res = await extractor.handle(query, {
2938
- type: queryType,
2939
- requestedBy: options.requestedBy
2940
- }).catch(() => null);
2941
- if (res) {
2942
- this.debug("Metadata query was successful!");
2943
- const result2 = new SearchResult(this, {
2944
- query,
2945
- queryType,
2946
- playlist: res.playlist,
2947
- tracks: res.tracks,
2948
- extractor,
2949
- requestedBy: options.requestedBy
2950
- });
2951
- if (!options.ignoreCache) {
2952
- this.debug(`Adding data to cache...`);
2953
- await this.queryCache?.addData(result2);
2954
- }
2955
- return result2;
2956
- }
2957
- this.debug("Failed to find result using appropriate extractor. Querying all extractors...");
2958
- const result = await this.extractors.run(
2959
- async (ext) => !options.blockExtractors?.includes(ext.identifier) && await ext.validate(query) && ext.handle(query, {
2960
- type: queryType,
2961
- requestedBy: options.requestedBy
2962
- })
2963
- );
2964
- if (!result?.result) {
2965
- this.debug(`Failed to query metadata query using ${result?.extractor.identifier || "N/A"} extractor.`);
2966
- return new SearchResult(this, {
2967
- query,
2968
- queryType,
2969
- requestedBy: options.requestedBy,
2970
- extractor: result?.extractor
2971
- });
2972
- }
2973
- this.debug(`Metadata query was successful using ${result.extractor.identifier}!`);
2974
- const data = new SearchResult(this, {
2975
- query,
2976
- queryType,
2977
- playlist: result.result.playlist,
2978
- tracks: result.result.tracks,
2979
- extractor: result.extractor,
2980
- requestedBy: options.requestedBy
2981
- });
2982
- if (!options.ignoreCache) {
2983
- this.debug(`Adding data to cache...`);
2984
- await this.queryCache?.addData(data);
2985
- }
2986
- return data;
2987
- }
2988
- scanDeps() {
2989
- const line = "-".repeat(50);
2990
- const depsReport = generateDependencyReport();
2991
- const extractorReport = this.extractors.store.map((m) => {
2992
- return m.identifier;
2993
- }).join("\n");
2994
- return `${depsReport}
2995
- Loaded Extractors:
2996
- ${extractorReport || "None"}
2997
- ${line}`;
2998
- }
2999
- *[Symbol.iterator]() {
3000
- yield* this.nodes.cache.values();
3001
- }
3002
- createPlaylist(data) {
3003
- return new Playlist(this, data);
3004
- }
3005
- };
3006
- var Player = _Player;
3007
- __name(Player, "Player");
3008
- _lastLatency = new WeakMap();
3009
- _voiceStateUpdateListener = new WeakMap();
3010
- _lagMonitorTimeout = new WeakMap();
3011
- _lagMonitorInterval = new WeakMap();
3012
- Player._singletonKey = kSingleton;
3013
-
3014
- // src/hooks/common.ts
3015
- var getPlayer = /* @__PURE__ */ __name(() => {
3016
- return instances.first() || null;
3017
- }, "getPlayer");
3018
- var getQueue = /* @__PURE__ */ __name((node) => {
3019
- const player = getPlayer();
3020
- if (!player)
3021
- return null;
3022
- return player.nodes.resolve(node) || null;
3023
- }, "getQueue");
3024
-
3025
- // src/hooks/useHistory.ts
3026
- function useHistory(node) {
3027
- const queue = getQueue(node);
3028
- if (!queue)
3029
- return null;
3030
- return queue.history;
3031
- }
3032
- __name(useHistory, "useHistory");
3033
-
3034
- // src/hooks/usePlayer.ts
3035
- function usePlayer(node) {
3036
- const queue = getQueue(node);
3037
- if (!queue)
3038
- return null;
3039
- return queue.node;
3040
- }
3041
- __name(usePlayer, "usePlayer");
3042
-
3043
- // src/hooks/useQueue.ts
3044
- function useQueue(node) {
3045
- const queue = getQueue(node);
3046
- if (!queue)
3047
- return null;
3048
- return queue;
3049
- }
3050
- __name(useQueue, "useQueue");
3051
-
3052
- // src/hooks/useMasterPlayer.ts
3053
- function useMasterPlayer() {
3054
- return getPlayer();
3055
- }
3056
- __name(useMasterPlayer, "useMasterPlayer");
3057
-
3058
- // src/hooks/useMetadata.ts
3059
- function useMetadata(node) {
3060
- const queue = getQueue(node);
3061
- const setter = /* @__PURE__ */ __name((metadata) => {
3062
- if (queue) {
3063
- if (TypeUtil.isFunction(metadata))
3064
- return queue.setMetadata(metadata(queue.metadata));
3065
- return queue.setMetadata(metadata);
3066
- }
3067
- }, "setter");
3068
- const getter = /* @__PURE__ */ __name(() => {
3069
- return queue?.metadata;
3070
- }, "getter");
3071
- return [getter, setter];
3072
- }
3073
- __name(useMetadata, "useMetadata");
3074
-
3075
- // src/hooks/useTimestamp.ts
3076
- function useTimeline(node, options) {
3077
- const queue = getQueue(node);
3078
- if (!queue)
3079
- return null;
3080
- return Object.preventExtensions({
3081
- get timestamp() {
3082
- return queue.node.getTimestamp(options?.ignoreFilters);
3083
- },
3084
- get volume() {
3085
- return queue.node.volume;
3086
- },
3087
- get paused() {
3088
- return queue.node.isPaused();
3089
- },
3090
- pause() {
3091
- return queue.node.pause();
3092
- },
3093
- resume() {
3094
- return queue.node.resume();
3095
- },
3096
- setVolume(vol) {
3097
- return queue.node.setVolume(vol);
3098
- },
3099
- async setPosition(time) {
3100
- return queue.node.seek(time);
3101
- }
3102
- });
3103
- }
3104
- __name(useTimeline, "useTimeline");
3105
-
3106
- // src/hooks/stream/onAfterCreateStream.ts
3107
- function onAfterCreateStream(handler) {
3108
- getGlobalRegistry().set("@[onAfterCreateStream]", handler);
3109
- }
3110
- __name(onAfterCreateStream, "onAfterCreateStream");
3111
-
3112
- // src/hooks/stream/onBeforeCreateStream.ts
3113
- function onBeforeCreateStream(handler) {
3114
- getGlobalRegistry().set("@[onBeforeCreateStream]", handler);
3115
- }
3116
- __name(onBeforeCreateStream, "onBeforeCreateStream");
3117
-
3118
- // src/index.ts
3119
- import {
3120
- AudioFilters as AudioFilters2,
3121
- FilterType,
3122
- Q_BUTTERWORTH,
3123
- VolumeTransformer,
3124
- BASS_EQ_BANDS,
3125
- AF_NIGHTCORE_RATE,
3126
- AF_VAPORWAVE_RATE,
3127
- FiltersChain as FiltersChain2
3128
- } from "@discord-player/equalizer";
3129
- import { createAudioPlayer as createAudioPlayer2, AudioPlayer as AudioPlayer3, CreateAudioPlayerOptions } from "@discordjs/voice";
3130
- var version2 = "6.2.0";
3131
- if (!djsVersion.startsWith("14")) {
3132
- process.emitWarning(`Discord.js v${djsVersion} is incompatible with Discord Player v${version2}! Please use >=v14.x of Discord.js`);
3133
- }
3134
63
  export {
3135
- AF_NIGHTCORE_RATE,
3136
- AF_VAPORWAVE_RATE,
3137
- AFilterGraph,
3138
- AsyncQueue,
3139
- AsyncQueueEntry,
3140
- AudioFilters,
3141
- AudioPlayer3 as AudioPlayer,
3142
- BASS_EQ_BANDS,
3143
- BaseExtractor,
3144
- FilterType as BiquadFilterType,
3145
- CreateAudioPlayerOptions,
3146
- DiscordPlayerQueryResultCache,
3147
- EqualizerConfigurationPreset,
3148
- ErrorStatusCode,
3149
- ExtractorExecutionContext,
3150
- FFMPEG_ARGS_PIPED,
3151
- FFMPEG_ARGS_STRING,
3152
- FFMPEG_SRATE_REGEX,
3153
- FFmpegFilterer,
3154
- FiltersChain2 as FiltersChain,
3155
- GuildNodeManager,
3156
- GuildQueue,
3157
- GuildQueueAudioFilters,
3158
- GuildQueueEvent,
3159
- GuildQueueHistory,
3160
- GuildQueuePlayerNode,
3161
- AudioFilters2 as PCMAudioFilters,
3162
- Player,
3163
- PlayerError,
3164
- PlayerEvent,
3165
- PlayerEventsEmitter,
3166
- Playlist,
3167
- Q_BUTTERWORTH,
3168
- QueryCache,
3169
- QueryResolver,
3170
- QueryType,
3171
- QueueRepeatMode,
3172
- SearchResult,
3173
- StreamDispatcher,
3174
- Track,
3175
- TypeUtil,
3176
- Util,
3177
- VoiceReceiverNode,
3178
- VoiceUtils,
3179
- VolumeTransformer,
3180
- createAudioPlayer2 as createAudioPlayer,
3181
- createFFmpegStream,
3182
- onAfterCreateStream,
3183
- onBeforeCreateStream,
3184
- useHistory,
3185
- useMasterPlayer,
3186
- useMetadata,
3187
- usePlayer,
3188
- useQueue,
3189
- useTimeline,
3190
- version2 as version
3191
- };
3192
- //# sourceMappingURL=index.mjs.map
64
+ AF_NIGHTCORE_RATE,
65
+ AF_VAPORWAVE_RATE,
66
+ AFilterGraph,
67
+ AsyncQueue,
68
+ AsyncQueueEntry,
69
+ AudioFilters,
70
+ AudioPlayer,
71
+ BASS_EQ_BANDS,
72
+ BaseExtractor,
73
+ BiquadFilterType,
74
+ DiscordPlayerQueryResultCache,
75
+ EqualizerConfigurationPreset,
76
+ ErrorStatusCode,
77
+ ExtractorExecutionContext,
78
+ FFMPEG_ARGS_PIPED,
79
+ FFMPEG_ARGS_STRING,
80
+ FFMPEG_SRATE_REGEX,
81
+ FFmpeg,
82
+ FFmpegFilterer,
83
+ FiltersChain,
84
+ GuildNodeManager,
85
+ GuildQueue,
86
+ GuildQueueAudioFilters,
87
+ GuildQueueEvent,
88
+ GuildQueueHistory,
89
+ GuildQueuePlayerNode,
90
+ PCMAudioFilters,
91
+ Player,
92
+ PlayerError,
93
+ PlayerEvent,
94
+ PlayerEventsEmitter,
95
+ Playlist,
96
+ Q_BUTTERWORTH,
97
+ QueryCache,
98
+ QueryResolver,
99
+ QueryType,
100
+ QueueRepeatMode,
101
+ SearchResult,
102
+ StreamDispatcher,
103
+ Track,
104
+ TypeUtil,
105
+ Util,
106
+ VoiceReceiverNode,
107
+ VoiceUtils,
108
+ VolumeTransformer,
109
+ createAudioPlayer,
110
+ createFFmpegStream,
111
+ findFFmpeg,
112
+ onAfterCreateStream,
113
+ onBeforeCreateStream,
114
+ useHistory,
115
+ useMasterPlayer,
116
+ useMetadata,
117
+ usePlayer,
118
+ useQueue,
119
+ useTimeline,
120
+ version
121
+ };