discord-player 6.0.0-dev.2 → 6.0.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -57,11 +57,13 @@ __export(src_exports, {
57
57
  BaseExtractor: () => BaseExtractor,
58
58
  BiquadFilterType: () => import_equalizer3.FilterType,
59
59
  BiquadFilters: () => import_equalizer3.BiquadFilters,
60
+ DiscordPlayerQueryResultCache: () => DiscordPlayerQueryResultCache,
60
61
  EqualizerConfigurationPreset: () => EqualizerConfigurationPreset,
61
62
  ErrorStatusCode: () => ErrorStatusCode,
62
63
  ExtractorExecutionContext: () => ExtractorExecutionContext,
63
64
  FFMPEG_ARGS_PIPED: () => FFMPEG_ARGS_PIPED,
64
65
  FFMPEG_ARGS_STRING: () => FFMPEG_ARGS_STRING,
66
+ FFMPEG_SRATE_REGEX: () => FFMPEG_SRATE_REGEX,
65
67
  FFmpegFilterer: () => FFmpegFilterer,
66
68
  FiltersChain: () => import_equalizer3.FiltersChain,
67
69
  GuildNodeManager: () => GuildNodeManager,
@@ -75,10 +77,10 @@ __export(src_exports, {
75
77
  PlayerError: () => PlayerError,
76
78
  Playlist: () => Playlist,
77
79
  Q_BUTTERWORTH: () => import_equalizer3.Q_BUTTERWORTH,
78
- QueryResolver: () => QueryResolver,
80
+ QueryCache: () => QueryCache,
79
81
  QueryType: () => QueryType,
80
- Queue: () => Queue,
81
82
  QueueRepeatMode: () => QueueRepeatMode,
83
+ SearchResult: () => SearchResult,
82
84
  StreamDispatcher: () => StreamDispatcher,
83
85
  Track: () => Track,
84
86
  Util: () => Util,
@@ -88,7 +90,7 @@ __export(src_exports, {
88
90
  version: () => version
89
91
  });
90
92
  module.exports = __toCommonJS(src_exports);
91
- var import_discord5 = require("discord.js");
93
+ var import_discord4 = require("discord.js");
92
94
 
93
95
  // src/utils/AudioFilters.ts
94
96
  var bass = /* @__PURE__ */ __name((g) => `bass=g=${g}:f=110:w=0.3`, "bass");
@@ -137,6 +139,7 @@ AudioFilters.filters = {
137
139
  "8D": "apulsator=hz=0.09",
138
140
  vaporwave: "aresample=48000,asetrate=48000*0.8",
139
141
  nightcore: "aresample=48000,asetrate=48000*1.25",
142
+ lofi: "aresample=48000,asetrate=48000*0.9,extrastereo=m=2.5:c=disabled",
140
143
  phaser: "aphaser=in_gain=0.4",
141
144
  tremolo: "tremolo",
142
145
  vibrato: "vibrato=f=6.5",
@@ -196,6 +199,9 @@ var BaseExtractor = class {
196
199
  emit(event, ...args) {
197
200
  return this.context.player.emit(event, ...args);
198
201
  }
202
+ createResponse(playlist, tracks = playlist?.tracks || []) {
203
+ return { playlist: playlist || null, tracks };
204
+ }
199
205
  };
200
206
  __name(BaseExtractor, "BaseExtractor");
201
207
  BaseExtractor.identifier = "com.discord-player.extractor";
@@ -249,8 +255,11 @@ var ExtractorExecutionContext = class {
249
255
  } catch {
250
256
  }
251
257
  }
252
- async run(fn) {
258
+ async run(fn, filterBlocked = true) {
259
+ const blocked = this.player.options.blockExtractors ?? [];
253
260
  for (const ext of this.store.values()) {
261
+ if (filterBlocked && blocked.some((e) => e === ext.identifier))
262
+ continue;
254
263
  const result = await fn(ext).catch(() => {
255
264
  return false;
256
265
  });
@@ -265,48 +274,12 @@ var ExtractorExecutionContext = class {
265
274
  };
266
275
  __name(ExtractorExecutionContext, "ExtractorExecutionContext");
267
276
 
268
- // src/Structures/Playlist.ts
269
- var Playlist = class {
270
- constructor(player, data) {
271
- this.player = player;
272
- this.tracks = data.tracks ?? [];
273
- this.author = data.author;
274
- this.description = data.description;
275
- this.thumbnail = data.thumbnail;
276
- this.type = data.type;
277
- this.source = data.source;
278
- this.id = data.id;
279
- this.url = data.url;
280
- this.title = data.title;
281
- }
282
- *[Symbol.iterator]() {
283
- yield* this.tracks;
284
- }
285
- toJSON(withTracks = true) {
286
- const payload = {
287
- id: this.id,
288
- url: this.url,
289
- title: this.title,
290
- description: this.description,
291
- thumbnail: this.thumbnail,
292
- type: this.type,
293
- source: this.source,
294
- author: this.author,
295
- tracks: []
296
- };
297
- if (withTracks)
298
- payload.tracks = this.tracks.map((m) => m.toJSON(true));
299
- return payload;
300
- }
301
- };
302
- __name(Playlist, "Playlist");
303
-
304
- // src/Player.ts
305
- var import_discord4 = require("discord.js");
306
- var import_utils8 = require("@discord-player/utils");
277
+ // src/Structures/GuildNodeManager.ts
278
+ var import_utils4 = require("@discord-player/utils");
307
279
 
308
- // src/Structures/Queue.ts
280
+ // src/Structures/GuildQueue.ts
309
281
  var import_discord2 = require("discord.js");
282
+ var import_utils3 = require("@discord-player/utils");
310
283
 
311
284
  // src/Structures/Track.ts
312
285
  var import_discord = require("discord.js");
@@ -332,7 +305,7 @@ var Track = class {
332
305
  Object.defineProperty(this, "raw", { value: Object.assign({}, { source: data.raw?.source ?? data.source }, data.raw ?? data), enumerable: false });
333
306
  }
334
307
  get queue() {
335
- return this.player.queues.find((q) => q.tracks.some((ab) => ab.id === this.id));
308
+ return this.player.nodes.cache.find((q) => q.tracks.some((ab) => ab.id === this.id));
336
309
  }
337
310
  get durationMS() {
338
311
  const times = /* @__PURE__ */ __name((n, t) => {
@@ -367,39 +340,8 @@ var Track = class {
367
340
  };
368
341
  __name(Track, "Track");
369
342
 
370
- // src/types/types.ts
371
- var QueryType = {
372
- AUTO: "auto",
373
- YOUTUBE: "youtube",
374
- YOUTUBE_PLAYLIST: "youtubePlaylist",
375
- SOUNDCLOUD_TRACK: "soundcloudTrack",
376
- SOUNDCLOUD_PLAYLIST: "soundcloudPlaylist",
377
- SOUNDCLOUD: "soundcloud",
378
- SPOTIFY_SONG: "spotifySong",
379
- SPOTIFY_ALBUM: "spotifyAlbum",
380
- SPOTIFY_PLAYLIST: "spotifyPlaylist",
381
- FACEBOOK: "facebook",
382
- VIMEO: "vimeo",
383
- ARBITRARY: "arbitrary",
384
- REVERBNATION: "reverbnation",
385
- YOUTUBE_SEARCH: "youtubeSearch",
386
- YOUTUBE_VIDEO: "youtubeVideo",
387
- SOUNDCLOUD_SEARCH: "soundcloudSearch",
388
- APPLE_MUSIC_SONG: "appleMusicSong",
389
- APPLE_MUSIC_ALBUM: "appleMusicAlbum",
390
- APPLE_MUSIC_PLAYLIST: "appleMusicPlaylist",
391
- FILE: "file"
392
- };
393
- var QueueRepeatMode = /* @__PURE__ */ ((QueueRepeatMode2) => {
394
- QueueRepeatMode2[QueueRepeatMode2["OFF"] = 0] = "OFF";
395
- QueueRepeatMode2[QueueRepeatMode2["TRACK"] = 1] = "TRACK";
396
- QueueRepeatMode2[QueueRepeatMode2["QUEUE"] = 2] = "QUEUE";
397
- QueueRepeatMode2[QueueRepeatMode2["AUTOPLAY"] = 3] = "AUTOPLAY";
398
- return QueueRepeatMode2;
399
- })(QueueRepeatMode || {});
400
-
401
- // src/Structures/Queue.ts
402
- var import_voice = require("@discordjs/voice");
343
+ // src/Structures/GuildQueue.ts
344
+ var import_voice2 = require("@discordjs/voice");
403
345
 
404
346
  // src/utils/Util.ts
405
347
  var import_promises = require("timers/promises");
@@ -472,128 +414,138 @@ var Util = class {
472
414
  };
473
415
  __name(Util, "Util");
474
416
 
475
- // src/Structures/PlayerError.ts
476
- var ErrorStatusCode = /* @__PURE__ */ ((ErrorStatusCode2) => {
477
- ErrorStatusCode2["STREAM_ERROR"] = "StreamError";
478
- ErrorStatusCode2["AUDIO_PLAYER_ERROR"] = "AudioPlayerError";
479
- ErrorStatusCode2["PLAYER_ERROR"] = "PlayerError";
480
- ErrorStatusCode2["NO_AUDIO_RESOURCE"] = "NoAudioResource";
481
- ErrorStatusCode2["UNKNOWN_GUILD"] = "UnknownGuild";
482
- ErrorStatusCode2["INVALID_ARG_TYPE"] = "InvalidArgType";
483
- ErrorStatusCode2["UNKNOWN_EXTRACTOR"] = "UnknownExtractor";
484
- ErrorStatusCode2["INVALID_EXTRACTOR"] = "InvalidExtractor";
485
- ErrorStatusCode2["INVALID_CHANNEL_TYPE"] = "InvalidChannelType";
486
- ErrorStatusCode2["INVALID_TRACK"] = "InvalidTrack";
487
- ErrorStatusCode2["UNKNOWN_REPEAT_MODE"] = "UnknownRepeatMode";
488
- ErrorStatusCode2["TRACK_NOT_FOUND"] = "TrackNotFound";
489
- ErrorStatusCode2["NO_CONNECTION"] = "NoConnection";
490
- ErrorStatusCode2["DESTROYED_QUEUE"] = "DestroyedQueue";
491
- return ErrorStatusCode2;
492
- })(ErrorStatusCode || {});
493
- var PlayerError = class extends Error {
494
- constructor(message, code = "PlayerError" /* PLAYER_ERROR */) {
495
- super();
496
- this.createdAt = new Date();
497
- this.message = `[${code}] ${message}`;
498
- this.statusCode = code;
499
- this.name = code;
500
- Error.captureStackTrace(this);
501
- }
502
- get createdTimestamp() {
503
- return this.createdAt.getTime();
417
+ // src/Structures/Playlist.ts
418
+ var Playlist = class {
419
+ constructor(player, data) {
420
+ this.player = player;
421
+ this.tracks = data.tracks ?? [];
422
+ this.author = data.author;
423
+ this.description = data.description;
424
+ this.thumbnail = data.thumbnail;
425
+ this.type = data.type;
426
+ this.source = data.source;
427
+ this.id = data.id;
428
+ this.url = data.url;
429
+ this.title = data.title;
504
430
  }
505
- valueOf() {
506
- return this.statusCode;
431
+ *[Symbol.iterator]() {
432
+ yield* this.tracks;
507
433
  }
508
- toJSON() {
509
- return {
510
- stack: this.stack,
511
- code: this.statusCode,
512
- message: this.message,
513
- created: this.createdTimestamp
434
+ toJSON(withTracks = true) {
435
+ const payload = {
436
+ id: this.id,
437
+ url: this.url,
438
+ title: this.title,
439
+ description: this.description,
440
+ thumbnail: this.thumbnail,
441
+ type: this.type,
442
+ source: this.source,
443
+ author: this.author,
444
+ tracks: []
514
445
  };
515
- }
516
- toString() {
517
- return this.stack;
446
+ if (withTracks)
447
+ payload.tracks = this.tracks.map((m) => m.toJSON(true));
448
+ return payload;
518
449
  }
519
450
  };
520
- __name(PlayerError, "PlayerError");
451
+ __name(Playlist, "Playlist");
521
452
 
522
- // src/utils/FFmpegStream.ts
523
- var import_prism_media = require("prism-media");
524
- function FFMPEG_ARGS_STRING(stream, fmt) {
525
- return [
526
- "-reconnect",
527
- "1",
528
- "-reconnect_streamed",
529
- "1",
530
- "-reconnect_delay_max",
531
- "5",
532
- "-i",
533
- stream,
534
- "-analyzeduration",
535
- "0",
536
- "-loglevel",
537
- "0",
538
- "-f",
539
- `${typeof fmt === "string" ? fmt : "s16le"}`,
540
- "-ar",
541
- "48000",
542
- "-ac",
543
- "2"
544
- ];
545
- }
546
- __name(FFMPEG_ARGS_STRING, "FFMPEG_ARGS_STRING");
547
- function FFMPEG_ARGS_PIPED(fmt) {
548
- return [
549
- "-analyzeduration",
550
- "0",
551
- "-loglevel",
552
- "0",
553
- "-f",
554
- `${typeof fmt === "string" ? fmt : "s16le"}`,
555
- "-ar",
556
- "48000",
557
- "-ac",
558
- "2"
559
- ];
560
- }
561
- __name(FFMPEG_ARGS_PIPED, "FFMPEG_ARGS_PIPED");
562
- function createFFmpegStream(stream, options) {
563
- if (options?.skip && typeof stream !== "string")
564
- return stream;
565
- options ?? (options = {});
566
- const args = typeof stream === "string" ? FFMPEG_ARGS_STRING(stream, options.fmt) : FFMPEG_ARGS_PIPED(options.fmt);
567
- if (!Number.isNaN(options.seek))
568
- args.unshift("-ss", String(options.seek));
569
- if (Array.isArray(options.encoderArgs))
570
- args.push(...options.encoderArgs);
571
- const transcoder = new import_prism_media.FFmpeg({ shell: false, args });
572
- transcoder.on("close", () => transcoder.destroy());
573
- if (typeof stream !== "string") {
574
- stream.on("error", () => transcoder.destroy());
575
- stream.pipe(transcoder);
453
+ // src/Structures/GuildQueueHistory.ts
454
+ var import_utils2 = require("@discord-player/utils");
455
+ var GuildQueueHistory = class {
456
+ constructor(queue) {
457
+ this.queue = queue;
458
+ this.tracks = new import_utils2.Queue("LIFO");
576
459
  }
577
- return transcoder;
578
- }
579
- __name(createFFmpegStream, "createFFmpegStream");
460
+ get currentTrack() {
461
+ return this.queue.dispatcher?.audioResource?.metadata || this.queue.__current;
462
+ }
463
+ get nextTrack() {
464
+ return this.queue.tracks.at(0) || null;
465
+ }
466
+ get previousTrack() {
467
+ return this.tracks.at(0) || null;
468
+ }
469
+ get disabled() {
470
+ return this.queue.options.disableHistory;
471
+ }
472
+ isEmpty() {
473
+ return this.tracks.size < 1;
474
+ }
475
+ push(track) {
476
+ if (this.disabled)
477
+ return false;
478
+ this.tracks.add(track);
479
+ return true;
480
+ }
481
+ clear() {
482
+ this.tracks.clear();
483
+ }
484
+ next() {
485
+ const track = this.nextTrack;
486
+ if (!track) {
487
+ throw new Error("No next track in the queue");
488
+ }
489
+ this.queue.node.skip();
490
+ }
491
+ previous() {
492
+ const track = this.previousTrack;
493
+ if (!track) {
494
+ throw new Error("No previous track in the queue");
495
+ }
496
+ this.queue.node.play(track, { queue: true });
497
+ this.queue.node.skip();
498
+ }
499
+ };
500
+ __name(GuildQueueHistory, "GuildQueueHistory");
580
501
 
581
- // src/Structures/Queue.ts
582
- var import_os = __toESM(require("os"));
583
- var import_worker_threads = require("worker_threads");
584
- var import_utils2 = require("@discord-player/utils");
502
+ // src/Structures/GuildQueuePlayerNode.ts
503
+ var import_voice = require("@discordjs/voice");
585
504
 
586
505
  // src/utils/QueryResolver.ts
587
506
  var import_youtube_sr = require("youtube-sr");
588
- var import_soundcloud_scraper = require("soundcloud-scraper");
589
- var spotifySongRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})(\?si=.+)?$/;
590
- var spotifyPlaylistRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})(\?si=.+)?$/;
591
- var spotifyAlbumRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})(\?si=.+)?$/;
592
- var vimeoRegex = /^(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)$/;
593
- var reverbnationRegex = /^https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)$/;
594
- var attachmentRegex = /^https?:\/\/.+$/;
595
- var appleMusicSongRegex = /^https?:\/\/music\.apple\.com\/.+?\/(song|album)\/.+?(\/.+?\?i=|\/)([0-9]+)$/;
596
- var appleMusicPlaylistRegex = /^https?:\/\/music\.apple\.com\/.+?\/playlist\/.+\/pl\.[a-f0-9]+$/;
507
+
508
+ // src/types/types.ts
509
+ var QueryType = {
510
+ AUTO: "auto",
511
+ YOUTUBE: "youtube",
512
+ YOUTUBE_PLAYLIST: "youtubePlaylist",
513
+ SOUNDCLOUD_TRACK: "soundcloudTrack",
514
+ SOUNDCLOUD_PLAYLIST: "soundcloudPlaylist",
515
+ SOUNDCLOUD: "soundcloud",
516
+ SPOTIFY_SONG: "spotifySong",
517
+ SPOTIFY_ALBUM: "spotifyAlbum",
518
+ SPOTIFY_PLAYLIST: "spotifyPlaylist",
519
+ FACEBOOK: "facebook",
520
+ VIMEO: "vimeo",
521
+ ARBITRARY: "arbitrary",
522
+ REVERBNATION: "reverbnation",
523
+ YOUTUBE_SEARCH: "youtubeSearch",
524
+ YOUTUBE_VIDEO: "youtubeVideo",
525
+ SOUNDCLOUD_SEARCH: "soundcloudSearch",
526
+ APPLE_MUSIC_SONG: "appleMusicSong",
527
+ APPLE_MUSIC_ALBUM: "appleMusicAlbum",
528
+ APPLE_MUSIC_PLAYLIST: "appleMusicPlaylist",
529
+ FILE: "file"
530
+ };
531
+ var QueueRepeatMode = /* @__PURE__ */ ((QueueRepeatMode2) => {
532
+ QueueRepeatMode2[QueueRepeatMode2["OFF"] = 0] = "OFF";
533
+ QueueRepeatMode2[QueueRepeatMode2["TRACK"] = 1] = "TRACK";
534
+ QueueRepeatMode2[QueueRepeatMode2["QUEUE"] = 2] = "QUEUE";
535
+ QueueRepeatMode2[QueueRepeatMode2["AUTOPLAY"] = 3] = "AUTOPLAY";
536
+ return QueueRepeatMode2;
537
+ })(QueueRepeatMode || {});
538
+
539
+ // src/utils/QueryResolver.ts
540
+ var import_soundcloud_scraper = require("soundcloud-scraper");
541
+ var spotifySongRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})(\?si=.+)?$/;
542
+ var spotifyPlaylistRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})(\?si=.+)?$/;
543
+ var spotifyAlbumRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})(\?si=.+)?$/;
544
+ var vimeoRegex = /^(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)$/;
545
+ var reverbnationRegex = /^https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)$/;
546
+ var attachmentRegex = /^https?:\/\/.+$/;
547
+ var appleMusicSongRegex = /^https?:\/\/music\.apple\.com\/.+?\/(song|album)\/.+?(\/.+?\?i=|\/)([0-9]+)$/;
548
+ var appleMusicPlaylistRegex = /^https?:\/\/music\.apple\.com\/.+?\/playlist\/.+\/pl\.(u-)?[a-zA-Z0-9]+$/;
597
549
  var appleMusicAlbumRegex = /^https?:\/\/music\.apple\.com\/.+?\/album\/.+\/([0-9]+)$/;
598
550
  var QueryResolver = class {
599
551
  constructor() {
@@ -653,237 +605,123 @@ var QueryResolver = class {
653
605
  };
654
606
  __name(QueryResolver, "QueryResolver");
655
607
 
656
- // src/Structures/Queue.ts
657
- var import_youtube_sr2 = require("youtube-sr");
658
- var OBCS_DEFAULT = /* @__PURE__ */ __name(async () => {
659
- return void 0;
660
- }, "OBCS_DEFAULT");
661
- var _destroyed, _watchDestroyed, watchDestroyed_fn, _getBufferingTimeout, getBufferingTimeout_fn;
662
- var Queue = class {
663
- constructor(player, guild, options = {}) {
664
- __privateAdd(this, _watchDestroyed);
665
- __privateAdd(this, _getBufferingTimeout);
666
- this.tracks = [];
667
- this.previousTracks = [];
668
- this.playing = false;
669
- this.metadata = null;
670
- this.repeatMode = 0;
671
- this.id = import_discord2.SnowflakeUtil.generate().toString();
672
- this._streamTime = 0;
673
- this._cooldownsTimeout = new import_utils2.Collection();
674
- this._activeFilters = [];
675
- this._filtersUpdate = false;
676
- this._lastEQBands = [];
677
- this._lastAudioFilters = [];
678
- __privateAdd(this, _destroyed, false);
679
- this.onBeforeCreateStream = OBCS_DEFAULT;
680
- this.player = player;
681
- this.guild = guild;
682
- this.options = {};
683
- Object.assign(
684
- this.options,
685
- {
686
- leaveOnEnd: true,
687
- leaveOnStop: true,
688
- leaveOnEmpty: true,
689
- leaveOnEndCooldown: 1e3,
690
- leaveOnEmptyCooldown: 1e3,
691
- autoSelfDeaf: true,
692
- ytdlOptions: {
693
- highWaterMark: 1 << 25
694
- },
695
- initialVolume: 100,
696
- bufferingTimeout: 3e3,
697
- spotifyBridge: true,
698
- disableVolume: false,
699
- disableEqualizer: false,
700
- equalizerBands: [],
701
- disableBiquad: false,
702
- disableFilters: false,
703
- defaultFilters: []
704
- },
705
- options
706
- );
707
- if (Array.isArray(options.equalizerBands))
708
- this._lastEQBands = options.equalizerBands;
709
- if (Array.isArray(options.defaultFilters))
710
- this._lastAudioFilters = options.defaultFilters;
711
- if (options.biquadFilter != null)
712
- this._lastBiquadFilter = options.biquadFilter;
713
- if ("onBeforeCreateStream" in this.options)
714
- this.onBeforeCreateStream = this.options.onBeforeCreateStream;
715
- this.player.emit("debug", this, `Queue initialized:
716
-
717
- ${this.player.scanDeps()}`);
608
+ // src/Structures/GuildQueuePlayerNode.ts
609
+ var import_promises2 = require("timers/promises");
610
+ var FFMPEG_SRATE_REGEX = /asetrate=\d+\*(\d(\.\d)?)/;
611
+ var _progress, _performPlay, performPlay_fn, _createGenericStream, createGenericStream_fn, _createFFmpegStream, createFFmpegStream_fn;
612
+ var GuildQueuePlayerNode = class {
613
+ constructor(queue) {
614
+ this.queue = queue;
615
+ __privateAdd(this, _performPlay);
616
+ __privateAdd(this, _createGenericStream);
617
+ __privateAdd(this, _createFFmpegStream);
618
+ __privateAdd(this, _progress, 0);
718
619
  }
719
- get filters() {
720
- return this.connection.filters;
620
+ isIdle() {
621
+ return !!this.queue.dispatcher?.isIdle();
721
622
  }
722
- get equalizer() {
723
- return this.connection.equalizer;
623
+ isBuffering() {
624
+ return !!this.queue.dispatcher?.isBuffering();
724
625
  }
725
- get biquad() {
726
- return this.connection.biquad;
626
+ isPlaying() {
627
+ return !!this.queue.dispatcher?.isPlaying();
727
628
  }
728
- async forceNext() {
729
- if (this.connection.audioResource) {
730
- this.connection.emit("finish", this.connection.audioResource);
731
- } else if (this.tracks.length) {
732
- await this.play();
733
- }
629
+ isPaused() {
630
+ return !!this.queue.dispatcher?.isPaused();
734
631
  }
735
- get current() {
736
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
737
- return;
738
- return this.connection.audioResource?.metadata ?? this.tracks[0];
632
+ resetProgress() {
633
+ __privateSet(this, _progress, 0);
739
634
  }
740
- get destroyed() {
741
- return __privateGet(this, _destroyed);
635
+ get streamTime() {
636
+ return this.queue.dispatcher?.streamTime ?? 0;
742
637
  }
743
- nowPlaying() {
744
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
745
- return;
746
- return this.current;
638
+ get playbackTime() {
639
+ const dur = __privateGet(this, _progress) + this.streamTime;
640
+ return dur;
747
641
  }
748
- async connect(channel) {
749
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
750
- return;
751
- const _channel = this.guild.channels.resolve(channel);
752
- if (![import_discord2.ChannelType.GuildStageVoice, import_discord2.ChannelType.GuildVoice].includes(_channel?.type))
753
- throw new PlayerError(`Channel type must be GuildVoice or GuildStageVoice, got ${_channel?.type}!`, "InvalidArgType" /* INVALID_ARG_TYPE */);
754
- const connection = await this.player.voiceUtils.connect(_channel, {
755
- deaf: this.options.autoSelfDeaf
756
- });
757
- this.connection = connection;
758
- if (_channel.type === import_discord2.ChannelType.GuildStageVoice) {
759
- await _channel.guild.members.me.voice.setSuppressed(false).catch(async () => {
760
- return await _channel.guild.members.me.voice.setRequestToSpeak(true).catch(Util.noop);
761
- });
762
- }
763
- this.connection.on("dsp", (filters) => {
764
- this._lastAudioFilters = filters;
765
- });
766
- this.connection.on("eqBands", (filters) => {
767
- this._lastEQBands = filters;
768
- });
769
- this.connection.on("biquad", (filters) => {
770
- this._lastBiquadFilter = filters;
771
- });
772
- this.connection.on("volume", (vol) => {
773
- this.options.initialVolume = vol;
774
- });
775
- this.connection.on("error", (err) => {
776
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this, false))
777
- return;
778
- this.player.emit("connectionError", this, err);
779
- });
780
- this.connection.on("debug", (msg) => {
781
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this, false))
782
- return;
783
- this.player.emit("debug", this, msg);
784
- });
785
- this.player.emit("connectionCreate", this, this.connection);
786
- this.connection.on("start", (resource) => {
787
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this, false))
788
- return;
789
- this.playing = true;
790
- if (!this._filtersUpdate)
791
- this.player.emit("trackStart", this, resource?.metadata ?? this.current);
792
- this._filtersUpdate = false;
793
- });
794
- this.connection.on("finish", async (resource) => {
795
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this, false))
796
- return;
797
- this.playing = false;
798
- if (this._filtersUpdate)
799
- return;
800
- this._streamTime = 0;
801
- this.player.emit("trackEnd", this, resource.metadata);
802
- if (!this.tracks.length && this.repeatMode === 0 /* OFF */) {
803
- this.emitEnd();
804
- } else if (!this.tracks.length && this.repeatMode === 3 /* AUTOPLAY */) {
805
- this._handleAutoplay(Util.last(this.previousTracks));
642
+ getDurationMultiplier() {
643
+ const srateFilters = this.queue.filters.ffmpeg.toArray().filter((ff) => FFMPEG_SRATE_REGEX.test(ff));
644
+ const multipliers = srateFilters.map((m) => {
645
+ return parseFloat(FFMPEG_SRATE_REGEX.exec(m)?.[1]);
646
+ }).filter((f) => !isNaN(f));
647
+ return !multipliers.length ? 1 : multipliers.reduce((accumulator, current) => current + accumulator);
648
+ }
649
+ get estimatedPlaybackTime() {
650
+ const dur = this.playbackTime;
651
+ return Math.round(this.getDurationMultiplier() * dur);
652
+ }
653
+ get estimatedDuration() {
654
+ const dur = this.queue.currentTrack?.durationMS ?? 0;
655
+ return Math.round(dur / this.getDurationMultiplier());
656
+ }
657
+ getTimestamp(ignoreFilters = false) {
658
+ if (!this.queue.currentTrack)
659
+ return null;
660
+ const current = ignoreFilters ? this.playbackTime : this.estimatedPlaybackTime;
661
+ const total = ignoreFilters ? this.queue.currentTrack.durationMS : this.estimatedDuration;
662
+ return {
663
+ current: {
664
+ label: Util.buildTimeCode(Util.parseMS(current)),
665
+ value: current
666
+ },
667
+ total: {
668
+ label: Util.buildTimeCode(Util.parseMS(total)),
669
+ value: total
670
+ },
671
+ progress: Math.round(current / total * 100)
672
+ };
673
+ }
674
+ createProgressBar(options) {
675
+ const timestamp = this.getTimestamp();
676
+ if (!timestamp)
677
+ return null;
678
+ const { indicator = "\u{1F518}", length = 15, line = "\u25AC", timecodes = true } = options || {};
679
+ if (isNaN(length) || length < 0 || !Number.isFinite(length))
680
+ throw new Error("invalid progressbar length");
681
+ const index = Math.round(timestamp.current.value / timestamp.total.value * length);
682
+ if (index >= 1 && index <= length) {
683
+ const bar = line.repeat(length - 1).split("");
684
+ bar.splice(index, 0, indicator);
685
+ if (timecodes) {
686
+ return `${timestamp.current.label} \u2503 ${bar.join("")} \u2503 ${timestamp.total.label}`;
806
687
  } else {
807
- if (this.repeatMode === 1 /* TRACK */)
808
- return void this.play(Util.last(this.previousTracks), { immediate: true });
809
- if (this.repeatMode === 2 /* QUEUE */)
810
- this.tracks.push(Util.last(this.previousTracks));
811
- const nextTrack = this.tracks.shift();
812
- this.play(nextTrack, { immediate: true });
813
- return;
688
+ return `${bar.join("")}`;
689
+ }
690
+ } else {
691
+ if (timecodes) {
692
+ return `${timestamp.current.label} \u2503 ${indicator}${line.repeat(length - 1)} \u2503 ${timestamp.total.label}`;
693
+ } else {
694
+ return `${indicator}${line.repeat(length - 1)}`;
814
695
  }
815
- });
816
- return this;
817
- }
818
- emitEnd() {
819
- const timeout = setTimeout(() => {
820
- if (!this.player.queues.has(this.guild.id))
821
- return;
822
- if (this.tracks.length || this.current)
823
- return;
824
- if (this.options.leaveOnEnd)
825
- this.destroy();
826
- this.player.emit("queueEnd", this);
827
- }, this.options.leaveOnEndCooldown || 0).unref();
828
- this._cooldownsTimeout.set(`queueEnd_${this.guild.id}`, timeout);
829
- }
830
- refreshEndCooldown() {
831
- const existingTimeout = this._cooldownsTimeout.get(`queueEnd_${this.guild.id}`);
832
- if (this.tracks.length || this.current) {
833
- clearTimeout(existingTimeout);
834
- this._cooldownsTimeout.delete(`queueEnd_${this.guild.id}`);
835
696
  }
836
697
  }
837
- destroy(disconnect = this.options.leaveOnStop) {
838
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
839
- return;
840
- if (this.connection)
841
- this.connection.end();
842
- if (disconnect)
843
- this.connection?.disconnect();
844
- this.player.queues.delete(this.guild.id);
845
- this.player.voiceUtils.cache.delete(this.guild.id);
846
- __privateSet(this, _destroyed, true);
847
- }
848
- skip() {
849
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
850
- return;
851
- if (!this.connection)
698
+ async seek(duration) {
699
+ if (!this.queue.currentTrack)
852
700
  return false;
853
- this._filtersUpdate = false;
854
- this.connection.end();
701
+ await this.play(this.queue.currentTrack, {
702
+ seek: duration,
703
+ transitionMode: true
704
+ });
855
705
  return true;
856
706
  }
857
- addTrack(track) {
858
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
859
- return;
860
- if (!(track instanceof Track))
861
- throw new PlayerError("invalid track", "InvalidTrack" /* INVALID_TRACK */);
862
- this.tracks.push(track);
863
- this.refreshEndCooldown();
864
- this.player.emit("trackAdd", this, track);
707
+ get volume() {
708
+ return this.queue.dispatcher?.volume ?? 100;
865
709
  }
866
- addTracks(tracks) {
867
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
868
- return;
869
- if (!tracks.every((y) => y instanceof Track))
870
- throw new PlayerError("invalid track", "InvalidTrack" /* INVALID_TRACK */);
871
- this.tracks.push(...tracks);
872
- this.refreshEndCooldown();
873
- this.player.emit("tracksAdd", this, tracks);
874
- }
875
- setPaused(paused) {
876
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
877
- return false;
878
- if (!this.connection)
710
+ setVolume(vol) {
711
+ if (!this.queue.dispatcher)
879
712
  return false;
880
- return paused ? this.connection.pause(true) : this.connection.resume();
713
+ const res = this.queue.dispatcher.setVolume(vol);
714
+ if (res)
715
+ this.queue.filters._lastFiltersCache.volume = vol;
716
+ return res;
881
717
  }
882
- get paused() {
883
- return this.connection.paused;
718
+ setBitrate(rate) {
719
+ this.queue.dispatcher?.audioResource?.encoder?.setBitrate(rate === "auto" ? this.queue.channel?.bitrate ?? 64e3 : rate);
884
720
  }
885
- set paused(val) {
886
- this.setPaused(val);
721
+ setPaused(state) {
722
+ if (state)
723
+ return this.queue.dispatcher?.pause(true) || false;
724
+ return this.queue.dispatcher?.resume() || false;
887
725
  }
888
726
  pause() {
889
727
  return this.setPaused(true);
@@ -891,1640 +729,1402 @@ ${this.player.scanDeps()}`);
891
729
  resume() {
892
730
  return this.setPaused(false);
893
731
  }
894
- setBitrate(bitrate) {
895
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
896
- return;
897
- if (!this.connection?.audioResource?.encoder)
898
- return;
899
- if (bitrate === "auto")
900
- bitrate = this.connection.channel?.bitrate ?? 64e3;
901
- this.connection.audioResource.encoder.setBitrate(bitrate);
902
- }
903
- setVolume(amount) {
904
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
905
- return;
906
- if (!this.connection)
907
- return false;
908
- this.options.initialVolume = amount;
909
- return this.connection.setVolume(amount);
910
- }
911
- setRepeatMode(mode) {
912
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
913
- return;
914
- if (![0 /* OFF */, 2 /* QUEUE */, 1 /* TRACK */, 3 /* AUTOPLAY */].includes(mode))
915
- throw new PlayerError(`Unknown repeat mode "${mode}"!`, "UnknownRepeatMode" /* UNKNOWN_REPEAT_MODE */);
916
- if (mode === this.repeatMode)
732
+ skip() {
733
+ if (!this.queue.dispatcher)
917
734
  return false;
918
- this.repeatMode = mode;
735
+ this.queue.setTransitioning(false);
736
+ this.queue.dispatcher.end();
919
737
  return true;
920
738
  }
921
- get volume() {
922
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
923
- return 100;
924
- if (!this.connection)
925
- return 100;
926
- return this.connection.volume;
927
- }
928
- set volume(amount) {
929
- this.setVolume(amount);
930
- }
931
- get streamTime() {
932
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
933
- return 0;
934
- if (!this.connection)
935
- return 0;
936
- const playbackTime = this._streamTime + this.connection.streamTime;
937
- const NC = this._activeFilters.includes("nightcore") ? 1.25 : null;
938
- const VW = this._activeFilters.includes("vaporwave") ? 0.8 : null;
939
- if (NC && VW)
940
- return playbackTime * (NC + VW);
941
- return NC ? playbackTime * NC : VW ? playbackTime * VW : playbackTime;
942
- }
943
- set streamTime(time) {
944
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
945
- return;
946
- this.seek(time);
947
- }
948
- getFiltersEnabled() {
949
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
950
- return;
951
- return AudioFilters_default.names.filter((x) => this._activeFilters.includes(x));
952
- }
953
- getFiltersDisabled() {
954
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
955
- return;
956
- return AudioFilters_default.names.filter((x) => !this._activeFilters.includes(x));
957
- }
958
- async setFilters(filters) {
959
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
960
- return;
961
- if (!filters || !Object.keys(filters).length) {
962
- const streamTime2 = this.streamTime;
963
- this._activeFilters = [];
964
- return await this.play(this.current, {
965
- immediate: true,
966
- filtersUpdate: true,
967
- seek: streamTime2,
968
- encoderArgs: []
969
- });
970
- }
971
- const _filters = [];
972
- for (const filter in filters) {
973
- if (filters[filter] === true)
974
- _filters.push(filter);
975
- }
976
- if (this._activeFilters.join("") === _filters.join(""))
977
- return;
978
- const newFilters = AudioFilters_default.create(_filters).trim();
979
- const streamTime = this.streamTime;
980
- this._activeFilters = _filters;
981
- return await this.play(this.current, {
982
- immediate: true,
983
- filtersUpdate: true,
984
- seek: streamTime,
985
- encoderArgs: !_filters.length ? void 0 : ["-af", newFilters]
739
+ remove(track) {
740
+ const foundTrack = this.queue.tracks.find((t, idx) => {
741
+ if (track instanceof Track || typeof track === "string") {
742
+ return (typeof track === "string" ? track : track.id) === t.id;
743
+ }
744
+ if (typeof track === "string")
745
+ return track === t.id;
746
+ return idx === track;
986
747
  });
748
+ if (!foundTrack)
749
+ return null;
750
+ this.queue.tracks.removeOne((t) => t.id === foundTrack.id);
751
+ return foundTrack;
987
752
  }
988
- async seek(position) {
989
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
990
- return;
991
- if (!this.playing || !this.current)
753
+ jump(track) {
754
+ const removed = this.remove(track);
755
+ if (!removed)
992
756
  return false;
993
- if (position < 1)
994
- position = 0;
995
- if (position >= this.current.durationMS)
996
- return this.skip();
997
- await this.play(this.current, {
998
- immediate: true,
999
- filtersUpdate: true,
1000
- seek: position
1001
- });
1002
- return true;
757
+ this.queue.tracks.store.unshift(removed);
758
+ return this.skip();
1003
759
  }
1004
- async back() {
1005
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1006
- return;
1007
- const prev = this.previousTracks[this.previousTracks.length - 2];
1008
- if (!prev)
1009
- throw new PlayerError("Could not find previous track", "TrackNotFound" /* TRACK_NOT_FOUND */);
1010
- return await this.play(prev, { immediate: true });
760
+ getTrackPosition(track) {
761
+ return this.queue.tracks.toArray().findIndex((t, idx) => {
762
+ if (track instanceof Track || typeof track === "string") {
763
+ return (typeof track === "string" ? track : track.id) === t.id;
764
+ }
765
+ if (typeof track === "string")
766
+ return track === t.id;
767
+ return idx === track;
768
+ });
1011
769
  }
1012
- clear() {
1013
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1014
- return;
1015
- this.tracks = [];
1016
- this.previousTracks = [];
770
+ skipTo(track) {
771
+ const idx = this.getTrackPosition(track);
772
+ if (idx < 0)
773
+ return false;
774
+ const removed = this.remove(idx);
775
+ if (!removed)
776
+ return false;
777
+ this.queue.tracks.store.splice(0, idx, removed);
778
+ return this.skip();
1017
779
  }
1018
- stop() {
1019
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1020
- return;
1021
- return this.destroy();
780
+ insert(track, index = 0) {
781
+ if (!(track instanceof Track))
782
+ throw new Error("invalid track");
783
+ this.queue.tracks.store.splice(index, 0, track);
1022
784
  }
1023
- shuffle() {
1024
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1025
- return;
1026
- if (!this.tracks.length || this.tracks.length < 2)
785
+ stop(force = false) {
786
+ if (!this.queue.dispatcher)
1027
787
  return false;
1028
- for (let i = this.tracks.length - 1; i > 0; i--) {
1029
- const j = Math.floor(Math.random() * (i + 1));
1030
- [this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
788
+ this.queue.dispatcher.end();
789
+ if (force) {
790
+ this.queue.dispatcher.disconnect();
791
+ return true;
792
+ }
793
+ if (this.queue.options.leaveOnStop) {
794
+ const tm = setTimeout(() => {
795
+ if (this.isPlaying() || this.queue.tracks.size)
796
+ return clearTimeout(tm);
797
+ this.queue.dispatcher?.disconnect();
798
+ }, this.queue.options.leaveOnStopCooldown).unref();
1031
799
  }
1032
800
  return true;
1033
801
  }
1034
- remove(track) {
1035
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1036
- return;
1037
- let trackFound = null;
1038
- if (typeof track === "number") {
1039
- trackFound = this.tracks[track];
1040
- if (trackFound) {
1041
- this.tracks = this.tracks.filter((t) => t.id !== trackFound.id);
802
+ async play(res, options) {
803
+ if (!this.queue.dispatcher?.voiceConnection) {
804
+ throw new Error("No voice connection available");
805
+ }
806
+ this.queue.debug(`Received play request from guild ${this.queue.guild.name} (ID: ${this.queue.guild.id})`);
807
+ options = Object.assign(
808
+ {},
809
+ {
810
+ queue: this.queue.currentTrack != null,
811
+ transitionMode: false,
812
+ seek: 0
813
+ },
814
+ options
815
+ );
816
+ if (res && options.queue) {
817
+ this.queue.debug("Requested option requires to queue the track, adding the given track to queue instead...");
818
+ return this.queue.tracks.add(res);
819
+ }
820
+ const track = res || this.queue.tracks.dispatch();
821
+ if (!track) {
822
+ throw new Error("Play request received but track was not provided");
823
+ }
824
+ this.queue.debug("Requested option requires to play the track, initializing...");
825
+ this.queue.initializing = true;
826
+ try {
827
+ this.queue.debug(`Initiating stream extraction process...`);
828
+ const qt = track.queryType || (track.raw.source === "spotify" ? "spotifySong" : track.raw.source === "apple_music" ? "appleMusicSong" : track.raw.source) || "arbitrary";
829
+ this.queue.debug(`Executing onBeforeCreateStream hook (QueryType: ${qt})...`);
830
+ let stream = await this.queue.onBeforeCreateStream?.(track, qt, this.queue).catch(() => null);
831
+ if (!stream) {
832
+ this.queue.debug("Failed to get stream from onBeforeCreateStream!");
833
+ stream = await __privateMethod(this, _createGenericStream, createGenericStream_fn).call(this, track).catch(() => null);
1042
834
  }
1043
- } else {
1044
- trackFound = this.tracks.find((s) => s.id === (track instanceof Track ? track.id : track));
1045
- if (trackFound) {
1046
- this.tracks = this.tracks.filter((s) => s.id !== trackFound.id);
835
+ if (!stream) {
836
+ const error = new Error("Could not extract stream for this track");
837
+ this.queue.initializing = false;
838
+ if (this.queue.options.skipOnNoStream) {
839
+ this.queue.player.events.emit("playerSkip", this.queue, track);
840
+ this.queue.player.events.emit("playerError", this.queue, error, track);
841
+ this.play(this.queue.tracks.dispatch());
842
+ return;
843
+ }
844
+ throw error;
845
+ }
846
+ if (typeof options.seek === "number" && options.seek >= 0) {
847
+ __privateSet(this, _progress, options.seek);
848
+ } else {
849
+ __privateSet(this, _progress, 0);
850
+ }
851
+ const cookies = track.source === "youtube" ? this.queue.player.options.ytdlOptions?.requestOptions?.headers?.cookie : void 0;
852
+ const pcmStream = __privateMethod(this, _createFFmpegStream, createFFmpegStream_fn).call(this, stream, track, options.seek ?? 0, cookies);
853
+ if (options.transitionMode) {
854
+ this.queue.debug(`Transition mode detected, player will wait for buffering timeout to expire (Timeout: ${this.queue.options.bufferingTimeout}ms)`);
855
+ await (0, import_promises2.setTimeout)(this.queue.options.bufferingTimeout);
856
+ this.queue.debug("Buffering timeout has expired!");
1047
857
  }
858
+ this.queue.debug(
859
+ `Preparing final stream config: ${JSON.stringify(
860
+ {
861
+ disableBiquad: this.queue.options.biquad === false,
862
+ disableEqualizer: this.queue.options.equalizer === false,
863
+ disableVolume: this.queue.options.volume === false,
864
+ disableFilters: this.queue.options.filterer === false,
865
+ disableResampler: this.queue.options.resampler === false,
866
+ sampleRate: typeof this.queue.options.resampler === "number" && this.queue.options.resampler > 0 ? this.queue.options.resampler : void 0,
867
+ biquadFilter: this.queue.filters._lastFiltersCache.biquad || void 0,
868
+ eq: this.queue.filters._lastFiltersCache.equalizer,
869
+ defaultFilters: this.queue.filters._lastFiltersCache.filters,
870
+ volume: this.queue.filters._lastFiltersCache.volume,
871
+ transitionMode: !!options.transitionMode,
872
+ ffmpegFilters: this.queue.filters.ffmpeg.toString(),
873
+ seek: options.seek
874
+ },
875
+ null,
876
+ 2
877
+ )}`
878
+ );
879
+ const resource = await this.queue.dispatcher.createStream(pcmStream, {
880
+ disableBiquad: this.queue.options.biquad === false,
881
+ disableEqualizer: this.queue.options.equalizer === false,
882
+ disableVolume: this.queue.options.volume === false,
883
+ disableFilters: this.queue.options.filterer === false,
884
+ disableResampler: this.queue.options.resampler === false,
885
+ sampleRate: typeof this.queue.options.resampler === "number" && this.queue.options.resampler > 0 ? this.queue.options.resampler : void 0,
886
+ biquadFilter: this.queue.filters._lastFiltersCache.biquad || void 0,
887
+ eq: this.queue.filters._lastFiltersCache.equalizer,
888
+ defaultFilters: this.queue.filters._lastFiltersCache.filters,
889
+ volume: this.queue.filters._lastFiltersCache.volume,
890
+ data: track,
891
+ type: import_voice.StreamType.Raw
892
+ });
893
+ this.queue.setTransitioning(!!options.transitionMode);
894
+ await __privateMethod(this, _performPlay, performPlay_fn).call(this, resource);
895
+ } catch (e) {
896
+ this.queue.debug(`Failed to initialize audio player: ${e}`);
897
+ this.queue.initializing = false;
898
+ throw e;
1048
899
  }
1049
- return trackFound;
1050
900
  }
1051
- getTrackPosition(track) {
1052
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1053
- return;
1054
- if (typeof track === "number")
1055
- return this.tracks[track] != null ? track : -1;
1056
- return this.tracks.findIndex((pred) => pred.id === (track instanceof Track ? track.id : track));
901
+ };
902
+ __name(GuildQueuePlayerNode, "GuildQueuePlayerNode");
903
+ _progress = new WeakMap();
904
+ _performPlay = new WeakSet();
905
+ performPlay_fn = /* @__PURE__ */ __name(async function(resource) {
906
+ this.queue.debug("Initializing audio player...");
907
+ await this.queue.dispatcher.playStream(resource);
908
+ this.queue.debug("Dispatching audio...");
909
+ }, "#performPlay");
910
+ _createGenericStream = new WeakSet();
911
+ createGenericStream_fn = /* @__PURE__ */ __name(async function(track) {
912
+ this.queue.debug(`Attempting to extract stream for Track { title: ${track.title}, url: ${track.url} } using registered extractors`);
913
+ const streamInfo = await this.queue.player.extractors.run(async (extractor) => {
914
+ if (this.queue.player.options.blockStreamFrom?.some((ext) => ext === extractor.identifier))
915
+ return false;
916
+ const canStream = await extractor.validate(track.url, track.queryType || QueryResolver.resolve(track.url));
917
+ if (!canStream)
918
+ return false;
919
+ return await extractor.stream(track);
920
+ }, false);
921
+ if (!streamInfo || !streamInfo.result) {
922
+ this.queue.debug(`Failed to extract stream for Track { title: ${track.title}, url: ${track.url} } using registered extractors`);
923
+ return null;
1057
924
  }
1058
- jump(track) {
1059
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
925
+ this.queue.debug(`Stream extraction was successful for Track { title: ${track.title}, url: ${track.url} } (Extractor: ${streamInfo.extractor.identifier})`);
926
+ const stream = streamInfo.result;
927
+ return stream;
928
+ }, "#createGenericStream");
929
+ _createFFmpegStream = new WeakSet();
930
+ createFFmpegStream_fn = /* @__PURE__ */ __name(function(stream, track, seek = 0, cookies) {
931
+ const ffmpegStream = this.queue.filters.ffmpeg.createStream(stream, {
932
+ encoderArgs: this.queue.filters.ffmpeg.filters.length ? ["-af", this.queue.filters.ffmpeg.toString()] : [],
933
+ seek: seek / 1e3,
934
+ fmt: "s16le",
935
+ cookies
936
+ }).on("error", (err) => {
937
+ const m = `${err}`.toLowerCase();
938
+ this.queue.debug(`Stream closed due to an error from FFmpeg stream: ${err.stack || err.message || err}`);
939
+ if (m.includes("premature close") || m.includes("epipe"))
1060
940
  return;
1061
- const foundTrack = this.remove(track);
1062
- if (!foundTrack)
1063
- throw new PlayerError("Track not found", "TrackNotFound" /* TRACK_NOT_FOUND */);
1064
- this.tracks.splice(0, 0, foundTrack);
1065
- return void this.skip();
941
+ this.queue.player.events.emit("playerError", this.queue, err, track);
942
+ });
943
+ return ffmpegStream;
944
+ }, "#createFFmpegStream");
945
+
946
+ // src/Structures/GuildQueueAudioFilters.ts
947
+ var import_equalizer = require("@discord-player/equalizer");
948
+
949
+ // src/utils/FFmpegStream.ts
950
+ var import_prism_media = require("prism-media");
951
+ function FFMPEG_ARGS_STRING(stream, fmt, cookies) {
952
+ const args = [
953
+ "-reconnect",
954
+ "1",
955
+ "-reconnect_streamed",
956
+ "1",
957
+ "-reconnect_delay_max",
958
+ "5",
959
+ "-i",
960
+ stream,
961
+ "-analyzeduration",
962
+ "0",
963
+ "-loglevel",
964
+ "0",
965
+ "-f",
966
+ `${typeof fmt === "string" ? fmt : "s16le"}`,
967
+ "-ar",
968
+ "48000",
969
+ "-ac",
970
+ "2"
971
+ ];
972
+ if (typeof cookies === "string") {
973
+ args.push("-cookies", cookies.startsWith('"') ? cookies : `"${cookies}"`);
1066
974
  }
1067
- skipTo(track) {
1068
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1069
- return;
1070
- const trackIndex = this.getTrackPosition(track);
1071
- const removedTrack = this.remove(track);
1072
- if (!removedTrack)
1073
- throw new PlayerError("Track not found", "TrackNotFound" /* TRACK_NOT_FOUND */);
1074
- this.tracks.splice(0, trackIndex, removedTrack);
1075
- return void this.skip();
975
+ return args;
976
+ }
977
+ __name(FFMPEG_ARGS_STRING, "FFMPEG_ARGS_STRING");
978
+ function FFMPEG_ARGS_PIPED(fmt) {
979
+ return [
980
+ "-analyzeduration",
981
+ "0",
982
+ "-loglevel",
983
+ "0",
984
+ "-f",
985
+ `${typeof fmt === "string" ? fmt : "s16le"}`,
986
+ "-ar",
987
+ "48000",
988
+ "-ac",
989
+ "2"
990
+ ];
991
+ }
992
+ __name(FFMPEG_ARGS_PIPED, "FFMPEG_ARGS_PIPED");
993
+ function createFFmpegStream(stream, options) {
994
+ if (options?.skip && typeof stream !== "string")
995
+ return stream;
996
+ options ?? (options = {});
997
+ const args = typeof stream === "string" ? FFMPEG_ARGS_STRING(stream, options.fmt, options.cookies) : FFMPEG_ARGS_PIPED(options.fmt);
998
+ if (!Number.isNaN(options.seek))
999
+ args.unshift("-ss", String(options.seek));
1000
+ if (Array.isArray(options.encoderArgs))
1001
+ args.push(...options.encoderArgs);
1002
+ const transcoder = new import_prism_media.FFmpeg({ shell: false, args });
1003
+ transcoder.on("close", () => transcoder.destroy());
1004
+ if (typeof stream !== "string") {
1005
+ stream.on("error", () => transcoder.destroy());
1006
+ stream.pipe(transcoder);
1076
1007
  }
1077
- insert(track, index = 0) {
1078
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1079
- return;
1080
- if (!track || !(track instanceof Track))
1081
- throw new PlayerError("track must be the instance of Track", "InvalidTrack" /* INVALID_TRACK */);
1082
- if (typeof index !== "number" || index < 0 || !Number.isFinite(index))
1083
- throw new PlayerError(`Invalid index "${index}"`, "InvalidArgType" /* INVALID_ARG_TYPE */);
1084
- this.tracks.splice(index, 0, track);
1085
- this.player.emit("trackAdd", this, track);
1086
- }
1087
- getPlayerTimestamp() {
1088
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1089
- return;
1090
- const currentStreamTime = this.streamTime;
1091
- const totalTime = this.current.durationMS;
1092
- const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime));
1093
- const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime));
1094
- return {
1095
- current: currentTimecode,
1096
- end: endTimecode,
1097
- progress: Math.round(currentStreamTime / totalTime * 100)
1098
- };
1008
+ return transcoder;
1009
+ }
1010
+ __name(createFFmpegStream, "createFFmpegStream");
1011
+
1012
+ // src/Structures/GuildQueueAudioFilters.ts
1013
+ var makeBands = /* @__PURE__ */ __name((arr) => {
1014
+ return Array.from(
1015
+ {
1016
+ length: import_equalizer.Equalizer.BAND_COUNT
1017
+ },
1018
+ (_, i) => ({
1019
+ band: i,
1020
+ gain: arr[i] ? arr[i] / 30 : 0
1021
+ })
1022
+ );
1023
+ }, "makeBands");
1024
+ var EqualizerConfigurationPreset = {
1025
+ Flat: makeBands([]),
1026
+ Classical: makeBands([-111022e-20, -111022e-20, -111022e-20, -111022e-20, -111022e-20, -111022e-20, -7.2, -7.2, -7.2, -9.6]),
1027
+ Club: makeBands([-111022e-20, -111022e-20, 8, 5.6, 5.6, 5.6, 3.2, -111022e-20, -111022e-20, -111022e-20]),
1028
+ Dance: makeBands([9.6, 7.2, 2.4, -111022e-20, -111022e-20, -5.6, -7.2, -7.2, -111022e-20, -111022e-20]),
1029
+ FullBass: makeBands([-8, 9.6, 9.6, 5.6, 1.6, -4, -8, -10.4, -11.2, -11.2]),
1030
+ FullBassTreble: makeBands([7.2, 5.6, -111022e-20, -7.2, -4.8, 1.6, 8, 11.2, 12, 12]),
1031
+ FullTreble: makeBands([-9.6, -9.6, -9.6, -4, 2.4, 11.2, 16, 16, 16, 16.8]),
1032
+ Headphones: makeBands([4.8, 11.2, 5.6, -3.2, -2.4, 1.6, 4.8, 9.6, 12.8, 14.4]),
1033
+ LargeHall: makeBands([10.4, 10.4, 5.6, 5.6, -111022e-20, -4.8, -4.8, -4.8, -111022e-20, -111022e-20]),
1034
+ Live: makeBands([-4.8, -111022e-20, 4, 5.6, 5.6, 5.6, 4, 2.4, 2.4, 2.4]),
1035
+ Party: makeBands([7.2, 7.2, -111022e-20, -111022e-20, -111022e-20, -111022e-20, -111022e-20, -111022e-20, 7.2, 7.2]),
1036
+ Pop: makeBands([-1.6, 4.8, 7.2, 8, 5.6, -111022e-20, -2.4, -2.4, -1.6, -1.6]),
1037
+ Reggae: makeBands([-111022e-20, -111022e-20, -111022e-20, -5.6, -111022e-20, 6.4, 6.4, -111022e-20, -111022e-20, -111022e-20]),
1038
+ Rock: makeBands([8, 4.8, -5.6, -8, -3.2, 4, 8.8, 11.2, 11.2, 11.2]),
1039
+ Ska: makeBands([-2.4, -4.8, -4, -111022e-20, 4, 5.6, 8.8, 9.6, 11.2, 9.6]),
1040
+ Soft: makeBands([4.8, 1.6, -111022e-20, -2.4, -111022e-20, 4, 8, 9.6, 11.2, 12]),
1041
+ SoftRock: makeBands([4, 4, 2.4, -111022e-20, -4, -5.6, -3.2, -111022e-20, 2.4, 8.8]),
1042
+ Techno: makeBands([8, 5.6, -111022e-20, -5.6, -4.8, -111022e-20, 8, 9.6, 9.6, 8.8])
1043
+ };
1044
+ var _ffmpegFilters, _setFilters, setFilters_fn;
1045
+ var FFmpegFilterer = class {
1046
+ constructor(af) {
1047
+ this.af = af;
1048
+ __privateAdd(this, _setFilters);
1049
+ __privateAdd(this, _ffmpegFilters, []);
1099
1050
  }
1100
- createProgressBar(options = { timecodes: true }) {
1101
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1102
- return;
1103
- const length = typeof options.length === "number" ? options.length <= 0 || options.length === Infinity ? 15 : options.length : 15;
1104
- const index = Math.round(this.streamTime / this.current.durationMS * length);
1105
- const indicator = typeof options.indicator === "string" && options.indicator.length > 0 ? options.indicator : "\u{1F518}";
1106
- const line = typeof options.line === "string" && options.line.length > 0 ? options.line : "\u25AC";
1107
- if (index >= 1 && index <= length) {
1108
- const bar = line.repeat(length - 1).split("");
1109
- bar.splice(index, 0, indicator);
1110
- if (options.timecodes) {
1111
- const timestamp = this.getPlayerTimestamp();
1112
- return `${timestamp.current} \u2503 ${bar.join("")} \u2503 ${timestamp.end}`;
1113
- } else {
1114
- return `${bar.join("")}`;
1115
- }
1051
+ createStream(source, options) {
1052
+ return createFFmpegStream(source, options);
1053
+ }
1054
+ setFilters(filters) {
1055
+ let _filters = [];
1056
+ if (typeof filters === "boolean") {
1057
+ _filters = !filters ? [] : Object.keys(AudioFilters_default.filters);
1058
+ } else if (Array.isArray(filters)) {
1059
+ _filters = filters;
1116
1060
  } else {
1117
- if (options.timecodes) {
1118
- const timestamp = this.getPlayerTimestamp();
1119
- return `${timestamp.current} \u2503 ${indicator}${line.repeat(length - 1)} \u2503 ${timestamp.end}`;
1120
- } else {
1121
- return `${indicator}${line.repeat(length - 1)}`;
1122
- }
1061
+ _filters = Object.entries(filters).filter((res) => res[1] === true).map((m) => m[0]);
1123
1062
  }
1063
+ return __privateMethod(this, _setFilters, setFilters_fn).call(this, _filters);
1124
1064
  }
1125
- get totalTime() {
1126
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1127
- return 0;
1128
- return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0;
1129
- }
1130
- generateStatistics() {
1131
- return {
1132
- guild: this.guild.id,
1133
- memory: process.memoryUsage(),
1134
- tracks: this.tracks.length,
1135
- os: {
1136
- cpuCount: import_os.default.cpus().length,
1137
- totalMem: import_os.default.totalmem(),
1138
- freeMem: import_os.default.freemem(),
1139
- platform: process.platform
1140
- },
1141
- isShard: typeof process.send === "function" || import_worker_threads.parentPort != null,
1142
- latency: {
1143
- client: this.player.client.ws.ping,
1144
- udp: this.connection.voiceConnection.ping.udp,
1145
- ws: this.connection.voiceConnection.ping.ws,
1146
- eventLoop: this.player.eventLoopLag
1147
- },
1148
- subscribers: this.player.queues.size,
1149
- connections: this.player.queues.filter((x) => x.connection?.voiceConnection != null).size,
1150
- extractors: this.player.extractors.size
1151
- };
1065
+ get filters() {
1066
+ return __privateGet(this, _ffmpegFilters);
1152
1067
  }
1153
- get ping() {
1154
- return this.connection.voiceConnection.ping.udp;
1068
+ set filters(filters) {
1069
+ this.setFilters(filters);
1155
1070
  }
1156
- async play(src, options = {}) {
1157
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this, false))
1158
- return;
1159
- if (!this.connection || !this.connection.voiceConnection)
1160
- throw new PlayerError("Voice connection is not available, use <Queue>.connect()!", "NoConnection" /* NO_CONNECTION */);
1161
- if (src && (this.playing || this.tracks.length) && !options.immediate)
1162
- return this.addTrack(src);
1163
- const track = options.filtersUpdate && !options.immediate ? src || this.current : src ?? this.tracks.shift();
1164
- if (!track)
1165
- return;
1166
- this.player.emit("debug", this, "Received play request");
1167
- if (!options.filtersUpdate) {
1168
- this.previousTracks = this.previousTracks.filter((x) => x.id !== track.id);
1169
- this.previousTracks.push(track);
1170
- }
1171
- let stream = null;
1172
- const hasCustomDownloader = typeof this.onBeforeCreateStream === "function";
1173
- if (hasCustomDownloader) {
1174
- const qt = track.queryType || (track.raw.source === "spotify" ? "spotifySong" : track.raw.source === "apple_music" ? "appleMusicSong" : track.raw.source) || "arbitrary";
1175
- stream = await this.onBeforeCreateStream(track, qt, this) || null;
1176
- }
1177
- if (!stream) {
1178
- const streamInfo = await this.player.extractors.run(async (extractor) => {
1179
- const canStream = await extractor.validate(track.url, track.queryType || QueryResolver.resolve(track.url));
1180
- if (!canStream)
1181
- return false;
1182
- return await extractor.stream(track);
1183
- });
1184
- if (!streamInfo || !streamInfo.result) {
1185
- this.player.emit("error", this, new Error("No stream extractors are available for this track"));
1186
- return void this.play(this.tracks.shift(), { immediate: true });
1187
- }
1188
- stream = streamInfo.result;
1189
- }
1190
- const ffmpegStream = createFFmpegStream(stream, {
1191
- encoderArgs: options.encoderArgs || this._activeFilters.length ? ["-af", AudioFilters_default.create(this._activeFilters)] : [],
1192
- seek: options.seek ? options.seek / 1e3 : 0,
1193
- fmt: "s16le"
1194
- }).on("error", (err) => {
1195
- if (!`${err}`.toLowerCase().includes("premature close"))
1196
- this.player.emit("error", this, err);
1197
- });
1198
- const resource = this.connection.createStream(ffmpegStream, {
1199
- type: import_voice.StreamType.Raw,
1200
- data: track,
1201
- disableVolume: Boolean(this.options.disableVolume),
1202
- disableEqualizer: Boolean(this.options.disableEqualizer),
1203
- eq: this._lastEQBands,
1204
- disableBiquad: Boolean(this.options.disableBiquad),
1205
- biquadFilter: this._lastBiquadFilter,
1206
- defaultFilters: this._lastAudioFilters,
1207
- disableFilters: Boolean(this.options.disableFilters),
1208
- volume: this.options.initialVolume,
1209
- disableResampler: false
1210
- });
1211
- if (options.seek)
1212
- this._streamTime = options.seek;
1213
- this._filtersUpdate = options.filtersUpdate;
1214
- setTimeout(() => {
1215
- this.connection.playStream(resource);
1216
- }, __privateMethod(this, _getBufferingTimeout, getBufferingTimeout_fn).call(this)).unref();
1217
- }
1218
- async _handleAutoplay(track) {
1219
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1220
- return;
1221
- if (!track || ![track.source, track.raw?.source].includes("youtube")) {
1222
- return this.emitEnd();
1223
- }
1224
- let info = await import_youtube_sr2.YouTube.getVideo(track.url).then((x) => x.videos[0]).catch(Util.noop);
1225
- if (!info)
1226
- info = await import_youtube_sr2.YouTube.search(track.author).then((x) => x[0]).catch(Util.noop);
1227
- if (!info) {
1228
- return this.emitEnd();
1229
- }
1230
- const nextTrack = new Track(this.player, {
1231
- title: info.title,
1232
- url: `https://www.youtube.com/watch?v=${info.id}`,
1233
- duration: info.durationFormatted || Util.buildTimeCode(Util.parseMS(info.duration * 1e3)),
1234
- description: "",
1235
- thumbnail: typeof info.thumbnail === "string" ? info.thumbnail : info.thumbnail.url,
1236
- views: info.views,
1237
- author: info.channel.name,
1238
- requestedBy: track.requestedBy,
1239
- source: "youtube",
1240
- queryType: "youtubeVideo"
1071
+ toggle(filters) {
1072
+ if (!Array.isArray(filters))
1073
+ filters = [filters];
1074
+ const fresh = [];
1075
+ filters.forEach((f) => {
1076
+ if (this.filters.includes(f))
1077
+ return;
1078
+ fresh.push(f);
1241
1079
  });
1242
- this.play(nextTrack, { immediate: true });
1080
+ return __privateMethod(this, _setFilters, setFilters_fn).call(this, __privateGet(this, _ffmpegFilters).filter((r) => !filters.includes(r)).concat(fresh));
1243
1081
  }
1244
- *[Symbol.iterator]() {
1245
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1246
- return;
1247
- yield* this.tracks;
1082
+ setDefaults(ff) {
1083
+ __privateSet(this, _ffmpegFilters, ff);
1084
+ }
1085
+ getFiltersEnabled() {
1086
+ return __privateGet(this, _ffmpegFilters);
1087
+ }
1088
+ getFiltersDisabled() {
1089
+ return AudioFilters_default.names.filter((f) => !__privateGet(this, _ffmpegFilters).includes(f));
1090
+ }
1091
+ isEnabled(filter) {
1092
+ return __privateGet(this, _ffmpegFilters).includes(filter);
1093
+ }
1094
+ isDisabled(filter) {
1095
+ return !this.isEnabled(filter);
1096
+ }
1097
+ isValidFilter(filter) {
1098
+ return AudioFilters_default.has(filter);
1099
+ }
1100
+ toArray() {
1101
+ return this.filters.map((filter) => AudioFilters_default.get(filter));
1248
1102
  }
1249
1103
  toJSON() {
1250
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1251
- return;
1252
- return {
1253
- id: this.id,
1254
- guild: this.guild.id,
1255
- voiceChannel: this.connection?.channel?.id,
1256
- options: this.options,
1257
- tracks: this.tracks.map((m) => m.toJSON())
1258
- };
1104
+ const obj = {};
1105
+ this.filters.forEach((filter) => obj[filter] = AudioFilters_default.get(filter));
1106
+ return obj;
1259
1107
  }
1260
1108
  toString() {
1261
- if (__privateMethod(this, _watchDestroyed, watchDestroyed_fn).call(this))
1262
- return;
1263
- if (!this.tracks.length)
1264
- return "No songs available to display!";
1265
- return `**Upcoming Songs:**
1266
- ${this.tracks.map((m, i) => `${i + 1}. **${m.title}**`).join("\n")}`;
1109
+ return AudioFilters_default.create(this.filters);
1267
1110
  }
1268
1111
  };
1269
- __name(Queue, "Queue");
1270
- _destroyed = new WeakMap();
1271
- _watchDestroyed = new WeakSet();
1272
- watchDestroyed_fn = /* @__PURE__ */ __name(function(emit = true) {
1273
- if (__privateGet(this, _destroyed)) {
1274
- if (emit)
1275
- this.player.emit("error", this, new PlayerError("Cannot use destroyed queue", "DestroyedQueue" /* DESTROYED_QUEUE */));
1276
- return true;
1277
- }
1278
- return false;
1279
- }, "#watchDestroyed");
1280
- _getBufferingTimeout = new WeakSet();
1281
- getBufferingTimeout_fn = /* @__PURE__ */ __name(function() {
1282
- const timeout = this.options.bufferingTimeout;
1283
- if (isNaN(timeout) || timeout < 0 || !Number.isFinite(timeout))
1284
- return 1e3;
1285
- return timeout;
1286
- }, "#getBufferingTimeout");
1287
-
1288
- // src/VoiceInterface/VoiceUtils.ts
1289
- var import_voice3 = require("@discordjs/voice");
1290
-
1291
- // src/VoiceInterface/StreamDispatcher.ts
1292
- var import_voice2 = require("@discordjs/voice");
1293
- var import_utils3 = require("@discord-player/utils");
1294
- var import_equalizer = require("@discord-player/equalizer");
1295
- var StreamDispatcher = class extends import_utils3.EventEmitter {
1296
- constructor(connection, channel, connectionTimeout = 2e4) {
1297
- super();
1298
- this.connectionTimeout = connectionTimeout;
1299
- this.readyLock = false;
1300
- this.dsp = new import_equalizer.FiltersChain();
1301
- this.voiceConnection = connection;
1302
- this.audioPlayer = (0, import_voice2.createAudioPlayer)();
1303
- this.channel = channel;
1304
- this.dsp.onUpdate = () => {
1305
- if (!this.dsp)
1306
- return;
1307
- if (this.dsp.filters?.filters)
1308
- this.emit("dsp", this.dsp.filters?.filters);
1309
- if (this.dsp.biquad?.filter)
1310
- this.emit("biquad", this.dsp.biquad?.filter);
1311
- if (this.dsp.equalizer)
1312
- this.emit("eqBands", this.dsp.equalizer.getEQ());
1313
- if (this.dsp.volume)
1314
- this.emit("volume", this.dsp.volume.volume);
1315
- if (this.dsp.resampler)
1316
- this.emit("sampleRate", this.dsp.resampler.targetSampleRate);
1112
+ __name(FFmpegFilterer, "FFmpegFilterer");
1113
+ _ffmpegFilters = new WeakMap();
1114
+ _setFilters = new WeakSet();
1115
+ setFilters_fn = /* @__PURE__ */ __name(function(filters) {
1116
+ const ignoreFilters = this.filters.some((ff) => ff === "nightcore" || ff === "vaporwave") && !filters.some((ff) => ff === "nightcore" || ff === "vaporwave");
1117
+ const seekTime = this.af.queue.node.getTimestamp(ignoreFilters)?.current.value || 0;
1118
+ __privateSet(this, _ffmpegFilters, [...new Set(filters)]);
1119
+ return this.af.triggerReplay(seekTime);
1120
+ }, "#setFilters");
1121
+ var GuildQueueAudioFilters = class {
1122
+ constructor(queue) {
1123
+ this.queue = queue;
1124
+ this.graph = new AFilterGraph(this);
1125
+ this.ffmpeg = new FFmpegFilterer(this);
1126
+ this.equalizerPresets = EqualizerConfigurationPreset;
1127
+ this._lastFiltersCache = {
1128
+ biquad: null,
1129
+ equalizer: [],
1130
+ filters: [],
1131
+ volume: 100,
1132
+ sampleRate: -1
1317
1133
  };
1318
- this.dsp.onError = (e) => this.emit("error", e);
1319
- this.voiceConnection.on("stateChange", async (_, newState) => {
1320
- if (newState.status === import_voice2.VoiceConnectionStatus.Disconnected) {
1321
- if (newState.reason === import_voice2.VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
1322
- try {
1323
- await (0, import_voice2.entersState)(this.voiceConnection, import_voice2.VoiceConnectionStatus.Connecting, this.connectionTimeout);
1324
- } catch {
1325
- try {
1326
- this.voiceConnection.destroy();
1327
- } catch (err) {
1328
- this.emit("error", err);
1329
- }
1330
- }
1331
- } else if (this.voiceConnection.rejoinAttempts < 5) {
1332
- await Util.wait((this.voiceConnection.rejoinAttempts + 1) * 5e3);
1333
- this.voiceConnection.rejoin();
1334
- } else {
1335
- try {
1336
- this.voiceConnection.destroy();
1337
- } catch (err) {
1338
- this.emit("error", err);
1339
- }
1340
- }
1341
- } else if (newState.status === import_voice2.VoiceConnectionStatus.Destroyed) {
1342
- this.end();
1343
- } else if (!this.readyLock && (newState.status === import_voice2.VoiceConnectionStatus.Connecting || newState.status === import_voice2.VoiceConnectionStatus.Signalling)) {
1344
- this.readyLock = true;
1345
- try {
1346
- await (0, import_voice2.entersState)(this.voiceConnection, import_voice2.VoiceConnectionStatus.Ready, this.connectionTimeout);
1347
- } catch {
1348
- if (this.voiceConnection.state.status !== import_voice2.VoiceConnectionStatus.Destroyed) {
1349
- try {
1350
- this.voiceConnection.destroy();
1351
- } catch (err) {
1352
- this.emit("error", err);
1353
- }
1354
- }
1355
- } finally {
1356
- this.readyLock = false;
1357
- }
1358
- }
1359
- });
1360
- this.audioPlayer.on("stateChange", (oldState, newState) => {
1361
- if (newState.status === import_voice2.AudioPlayerStatus.Playing) {
1362
- if (!this.paused)
1363
- return void this.emit("start", this.audioResource);
1364
- } else if (newState.status === import_voice2.AudioPlayerStatus.Idle && oldState.status !== import_voice2.AudioPlayerStatus.Idle) {
1365
- if (!this.paused) {
1366
- void this.emit("finish", this.audioResource);
1367
- this.dsp.destroy();
1368
- this.audioResource = null;
1369
- }
1370
- }
1371
- });
1372
- this.audioPlayer.on("debug", (m) => void this.emit("debug", m));
1373
- this.audioPlayer.on("error", (error) => void this.emit("error", error));
1374
- this.voiceConnection.subscribe(this.audioPlayer);
1375
- }
1376
- get paused() {
1377
- return this.audioPlayer.state.status === import_voice2.AudioPlayerStatus.Paused;
1378
- }
1379
- set paused(val) {
1380
- val ? this.pause(true) : this.resume();
1381
- }
1382
- isPaused() {
1383
- return this.paused || this.audioPlayer.state.status === import_voice2.AudioPlayerStatus.AutoPaused;
1384
- }
1385
- isBuffering() {
1386
- return this.audioPlayer.state.status === import_voice2.AudioPlayerStatus.Buffering;
1387
- }
1388
- isPlaying() {
1389
- return this.audioPlayer.state.status === import_voice2.AudioPlayerStatus.Playing;
1390
- }
1391
- isIdle() {
1392
- return this.audioPlayer.state.status === import_voice2.AudioPlayerStatus.Idle;
1393
- }
1394
- createStream(src, ops) {
1395
- const stream = !ops?.disableFilters && typeof src !== "string" ? this.dsp.create(src, {
1396
- dsp: {
1397
- filters: ops?.defaultFilters,
1398
- disabled: ops?.disableFilters
1399
- },
1400
- biquad: ops?.biquadFilter ? {
1401
- filter: ops.biquadFilter,
1402
- disabled: ops?.disableBiquad
1403
- } : void 0,
1404
- resampler: {
1405
- targetSampleRate: ops?.sampleRate,
1406
- disabled: ops?.disableResampler
1407
- },
1408
- equalizer: {
1409
- bandMultiplier: ops?.eq,
1410
- disabled: ops?.disableEqualizer
1411
- },
1412
- volume: {
1413
- volume: ops?.volume,
1414
- disabled: ops?.disableVolume
1415
- }
1416
- }) : src;
1417
- this.audioResource = (0, import_voice2.createAudioResource)(stream, {
1418
- inputType: ops?.type ?? import_voice2.StreamType.Arbitrary,
1419
- metadata: ops?.data,
1420
- inlineVolume: false
1421
- });
1422
- return this.audioResource;
1134
+ if (typeof this.queue.options.volume === "number") {
1135
+ this._lastFiltersCache.volume = this.queue.options.volume;
1136
+ }
1423
1137
  }
1424
- get resampler() {
1425
- return this.dsp?.resampler;
1138
+ get volume() {
1139
+ return this.queue.dispatcher?.dsp?.volume || null;
1426
1140
  }
1427
- get filters() {
1428
- return this.dsp?.filters;
1141
+ get equalizer() {
1142
+ return this.queue.dispatcher?.equalizer || null;
1429
1143
  }
1430
1144
  get biquad() {
1431
- return this.dsp?.biquad || null;
1145
+ return this.queue.dispatcher?.biquad || null;
1432
1146
  }
1433
- get equalizer() {
1434
- return this.dsp?.equalizer || null;
1147
+ get filters() {
1148
+ return this.queue.dispatcher?.filters || null;
1435
1149
  }
1436
- get status() {
1437
- return this.audioPlayer.state.status;
1150
+ get resampler() {
1151
+ return this.queue.dispatcher?.resampler || null;
1438
1152
  }
1439
- disconnect() {
1153
+ async triggerReplay(seek = 0) {
1154
+ if (!this.queue.currentTrack)
1155
+ return false;
1440
1156
  try {
1441
- this.audioPlayer.stop(true);
1442
- this.voiceConnection.destroy();
1157
+ await this.queue.node.play(this.queue.currentTrack, {
1158
+ queue: false,
1159
+ seek,
1160
+ transitionMode: true
1161
+ });
1162
+ return true;
1443
1163
  } catch {
1164
+ return false;
1444
1165
  }
1445
1166
  }
1446
- end() {
1447
- this.audioPlayer.stop();
1167
+ };
1168
+ __name(GuildQueueAudioFilters, "GuildQueueAudioFilters");
1169
+ var AFilterGraph = class {
1170
+ constructor(af) {
1171
+ this.af = af;
1448
1172
  }
1449
- pause(interpolateSilence) {
1450
- const success = this.audioPlayer.pause(interpolateSilence);
1451
- return success;
1173
+ get ffmpeg() {
1174
+ return this.af.ffmpeg.filters;
1452
1175
  }
1453
- resume() {
1454
- const success = this.audioPlayer.unpause();
1455
- return success;
1176
+ get equalizer() {
1177
+ return (this.af.equalizer?.bandMultipliers || []).map((m, i) => ({
1178
+ band: i,
1179
+ gain: m
1180
+ }));
1456
1181
  }
1457
- async playStream(resource = this.audioResource) {
1458
- if (!resource)
1459
- throw new PlayerError("Audio resource is not available!", "NoAudioResource" /* NO_AUDIO_RESOURCE */);
1460
- if (resource.ended) {
1461
- return void this.emit("finish", resource);
1462
- }
1463
- if (!this.audioResource)
1464
- this.audioResource = resource;
1465
- if (this.voiceConnection.state.status !== import_voice2.VoiceConnectionStatus.Ready) {
1466
- try {
1467
- await (0, import_voice2.entersState)(this.voiceConnection, import_voice2.VoiceConnectionStatus.Ready, this.connectionTimeout);
1468
- } catch (err) {
1469
- return void this.emit("error", err);
1470
- }
1471
- }
1472
- try {
1473
- this.audioPlayer.play(resource);
1474
- } catch (e) {
1475
- this.emit("error", e);
1476
- }
1477
- return this;
1182
+ get biquad() {
1183
+ return null;
1478
1184
  }
1479
- setVolume(value) {
1480
- if (!this.dsp.volume)
1481
- return false;
1482
- return this.dsp.volume.setVolume(value);
1185
+ get filters() {
1186
+ return this.af.filters?.filters || [];
1483
1187
  }
1484
1188
  get volume() {
1485
- if (!this.dsp.volume)
1486
- return 100;
1487
- return this.dsp.volume.volume;
1189
+ return this.af.volume;
1488
1190
  }
1489
- get streamTime() {
1490
- if (!this.audioResource)
1491
- return 0;
1492
- return this.audioResource.playbackDuration;
1191
+ get resampler() {
1192
+ return this.af.resampler;
1193
+ }
1194
+ dump() {
1195
+ return {
1196
+ ffmpeg: this.ffmpeg,
1197
+ equalizer: this.equalizer,
1198
+ biquad: this.biquad,
1199
+ filters: this.filters,
1200
+ sampleRate: this.resampler?.targetSampleRate || this.resampler?.sampleRate || 48e3,
1201
+ volume: this.volume?.volume ?? 100
1202
+ };
1493
1203
  }
1494
1204
  };
1495
- __name(StreamDispatcher, "StreamDispatcher");
1205
+ __name(AFilterGraph, "AFilterGraph");
1496
1206
 
1497
- // src/VoiceInterface/VoiceUtils.ts
1498
- var import_utils4 = require("@discord-player/utils");
1499
- var VoiceUtils = class {
1500
- constructor() {
1501
- this.cache = new import_utils4.Collection();
1502
- }
1503
- async connect(channel, options) {
1504
- const conn = await this.join(channel, options);
1505
- const sub = new StreamDispatcher(conn, channel, options?.maxTime);
1506
- this.cache.set(channel.guild.id, sub);
1507
- return sub;
1508
- }
1509
- async join(channel, options) {
1510
- const conn = (0, import_voice3.joinVoiceChannel)({
1511
- guildId: channel.guild.id,
1512
- channelId: channel.id,
1513
- adapterCreator: channel.guild.voiceAdapterCreator,
1514
- selfDeaf: Boolean(options?.deaf)
1515
- });
1516
- return conn;
1517
- }
1518
- disconnect(connection) {
1519
- if (connection instanceof StreamDispatcher)
1520
- return connection.voiceConnection.destroy();
1521
- return connection.destroy();
1207
+ // src/Structures/GuildQueue.ts
1208
+ var import_timers = require("timers");
1209
+ var import_youtube_sr2 = require("youtube-sr");
1210
+
1211
+ // src/Structures/GuildQueueStatistics.ts
1212
+ var GuildQueueStatistics = class {
1213
+ constructor(queue) {
1214
+ this.queue = queue;
1522
1215
  }
1523
- getConnection(guild) {
1524
- return this.cache.get(guild) || (0, import_voice3.getVoiceConnection)(guild);
1216
+ generate() {
1217
+ return {
1218
+ latency: {
1219
+ eventLoop: this.queue.player.eventLoopLag,
1220
+ voiceConnection: this.queue.ping
1221
+ },
1222
+ status: {
1223
+ buffering: this.queue.node.isBuffering(),
1224
+ playing: this.queue.node.isPlaying(),
1225
+ paused: this.queue.node.isPaused(),
1226
+ idle: this.queue.node.isIdle()
1227
+ },
1228
+ tracksCount: this.queue.tracks.size,
1229
+ historySize: this.queue.history.tracks.size,
1230
+ extractors: this.queue.player.extractors.size,
1231
+ listeners: this.queue.guild.members.me?.voice.channel?.members.filter((m) => !m.user.bot).size || 0,
1232
+ memoryUsage: process.memoryUsage(),
1233
+ versions: {
1234
+ node: process.version,
1235
+ player: "6.0.0-dev.3"
1236
+ }
1237
+ };
1525
1238
  }
1526
1239
  };
1527
- __name(VoiceUtils, "VoiceUtils");
1240
+ __name(GuildQueueStatistics, "GuildQueueStatistics");
1528
1241
 
1529
- // src/Player.ts
1530
- var import_voice5 = require("@discordjs/voice");
1531
- var import_utils9 = require("@discord-player/utils");
1532
-
1533
- // src/Structures/SearchResult.ts
1534
- var SearchResult = class {
1535
- constructor(player, _data) {
1242
+ // src/Structures/GuildQueue.ts
1243
+ var _transitioning, _initializing, _deleted, _initializingPromises, _attachListeners, attachListeners_fn, _removeListeners, removeListeners_fn, _performStart, performStart_fn, _performFinish, performFinish_fn, _emitEnd, emitEnd_fn, _handleAutoplay, handleAutoplay_fn, _resolveInitializerAwaiters, resolveInitializerAwaiters_fn, _warnIfDeleted, warnIfDeleted_fn;
1244
+ var GuildQueue = class {
1245
+ constructor(player, options) {
1536
1246
  this.player = player;
1537
- this._data = _data;
1247
+ this.options = options;
1248
+ __privateAdd(this, _attachListeners);
1249
+ __privateAdd(this, _removeListeners);
1250
+ __privateAdd(this, _performStart);
1251
+ __privateAdd(this, _performFinish);
1252
+ __privateAdd(this, _emitEnd);
1253
+ __privateAdd(this, _handleAutoplay);
1254
+ __privateAdd(this, _resolveInitializerAwaiters);
1255
+ __privateAdd(this, _warnIfDeleted);
1256
+ __privateAdd(this, _transitioning, false);
1257
+ __privateAdd(this, _initializing, false);
1258
+ __privateAdd(this, _deleted, false);
1259
+ __privateAdd(this, _initializingPromises, []);
1260
+ this.__current = null;
1261
+ this.history = new GuildQueueHistory(this);
1262
+ this.dispatcher = null;
1263
+ this.node = new GuildQueuePlayerNode(this);
1264
+ this.filters = new GuildQueueAudioFilters(this);
1265
+ this.onBeforeCreateStream = /* @__PURE__ */ __name(async () => null, "onBeforeCreateStream");
1266
+ this.onAfterCreateStream = /* @__PURE__ */ __name(async (stream) => ({
1267
+ stream,
1268
+ type: import_voice2.StreamType.Raw
1269
+ }), "onAfterCreateStream");
1270
+ this.repeatMode = 0 /* OFF */;
1271
+ this.timeouts = new import_utils3.Collection();
1272
+ this.stats = new GuildQueueStatistics(this);
1273
+ this.tracks = new import_utils3.Queue(options.queueStrategy);
1274
+ if (typeof options.onBeforeCreateStream === "function")
1275
+ this.onBeforeCreateStream = options.onBeforeCreateStream;
1276
+ if (typeof options.onAfterCreateStream === "function")
1277
+ this.onAfterCreateStream = options.onAfterCreateStream;
1278
+ if (options.repeatMode != null)
1279
+ this.repeatMode = options.repeatMode;
1280
+ options.selfDeaf ?? (options.selfDeaf = true);
1281
+ if (this.options.biquad != null && typeof this.options.biquad !== "boolean") {
1282
+ this.filters._lastFiltersCache.biquad = this.options.biquad;
1283
+ }
1284
+ if (Array.isArray(this.options.equalizer)) {
1285
+ this.filters._lastFiltersCache.equalizer = this.options.equalizer;
1286
+ }
1287
+ if (Array.isArray(this.options.filterer)) {
1288
+ this.filters._lastFiltersCache.filters = this.options.filterer;
1289
+ }
1290
+ if (typeof this.options.resampler === "number") {
1291
+ this.filters._lastFiltersCache.sampleRate = this.options.resampler;
1292
+ }
1293
+ if (Array.isArray(this.options.ffmpegFilters)) {
1294
+ this.filters.ffmpeg.setDefaults(this.options.ffmpegFilters);
1295
+ }
1296
+ this.debug(`GuildQueue initialized for guild ${this.options.guild.name} (ID: ${this.options.guild.id})`);
1538
1297
  }
1539
- get query() {
1540
- return this._data.query;
1298
+ debug(m) {
1299
+ this.player.events.emit("debug", this, m);
1541
1300
  }
1542
- get queryType() {
1543
- return this._data.queryType || QueryType.AUTO;
1301
+ get metadata() {
1302
+ return this.options.metadata;
1544
1303
  }
1545
- get extractor() {
1546
- return this._data.extractor || null;
1304
+ set metadata(m) {
1305
+ this.options.metadata = m;
1547
1306
  }
1548
- get playlist() {
1549
- return this._data.playlist;
1307
+ setMetadata(m) {
1308
+ __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
1309
+ this.options.metadata = m;
1550
1310
  }
1551
- get tracks() {
1552
- return this._data.tracks || [];
1311
+ get initializing() {
1312
+ return __privateGet(this, _initializing);
1553
1313
  }
1554
- get requestedBy() {
1555
- return this._data.requestedBy || null;
1314
+ set initializing(v) {
1315
+ __privateSet(this, _initializing, v);
1316
+ if (v)
1317
+ __privateMethod(this, _resolveInitializerAwaiters, resolveInitializerAwaiters_fn).call(this);
1556
1318
  }
1557
- async execute() {
1558
- return this.player.search(this.query, {
1559
- searchEngine: this.queryType,
1560
- requestedBy: this.requestedBy
1561
- });
1319
+ get currentTrack() {
1320
+ return this.dispatcher?.audioResource?.metadata || this.__current;
1562
1321
  }
1563
- isEmpty() {
1564
- return !this.tracks.length;
1322
+ get deleted() {
1323
+ return __privateGet(this, _deleted);
1565
1324
  }
1566
- hasPlaylist() {
1567
- return this.playlist != null;
1325
+ get channel() {
1326
+ return this.dispatcher?.channel || null;
1568
1327
  }
1569
- hasTracks() {
1570
- return this.tracks.length > 0;
1328
+ set channel(c) {
1329
+ if (this.dispatcher) {
1330
+ if (c) {
1331
+ this.dispatcher.channel = c;
1332
+ } else {
1333
+ this.delete();
1334
+ }
1335
+ }
1571
1336
  }
1572
- toJSON() {
1573
- return {
1574
- query: this.query,
1575
- queryType: this.queryType,
1576
- playlist: this.playlist?.toJSON(false) || null,
1577
- tracks: this.tracks.map((m) => m.toJSON(true)),
1578
- extractor: this.extractor?.identifier || null,
1579
- requestedBy: this.requestedBy?.toJSON() || null
1580
- };
1337
+ get connection() {
1338
+ return this.dispatcher?.voiceConnection || null;
1581
1339
  }
1582
- };
1583
- __name(SearchResult, "SearchResult");
1584
-
1585
- // src/Structures/GuildQueue/GuildNodeManager.ts
1586
- var import_utils7 = require("@discord-player/utils");
1587
-
1588
- // src/Structures/GuildQueue/GuildQueue.ts
1589
- var import_discord3 = require("discord.js");
1590
- var import_utils6 = require("@discord-player/utils");
1591
-
1592
- // src/Structures/GuildQueue/GuildQueueHistory.ts
1593
- var import_utils5 = require("@discord-player/utils");
1594
- var GuildQueueHistory = class {
1595
- constructor(queue) {
1596
- this.queue = queue;
1597
- this.tracks = new import_utils5.Queue("LIFO");
1340
+ get guild() {
1341
+ return this.options.guild;
1598
1342
  }
1599
- get currentTrack() {
1600
- return this.queue.dispatcher?.audioResource?.metadata || this.queue.__current;
1343
+ get id() {
1344
+ return this.guild.id;
1601
1345
  }
1602
- get nextTrack() {
1603
- return this.queue.tracks.at(0) || null;
1346
+ setTransitioning(state) {
1347
+ __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
1348
+ __privateSet(this, _transitioning, state);
1604
1349
  }
1605
- get previousTrack() {
1606
- return this.tracks.at(0) || null;
1350
+ isTransitioning() {
1351
+ return __privateGet(this, _transitioning);
1607
1352
  }
1608
- get disabled() {
1609
- return this.queue.options.disableHistory;
1353
+ setRepeatMode(mode) {
1354
+ __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
1355
+ this.repeatMode = mode;
1610
1356
  }
1611
1357
  isEmpty() {
1358
+ __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
1612
1359
  return this.tracks.size < 1;
1613
1360
  }
1614
- push(track) {
1615
- if (this.disabled)
1616
- return false;
1617
- this.tracks.add(track);
1618
- return true;
1619
- }
1620
- clear() {
1621
- this.tracks.clear();
1361
+ isPlaying() {
1362
+ __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
1363
+ return this.dispatcher?.audioResource != null;
1622
1364
  }
1623
- next() {
1624
- const track = this.nextTrack;
1625
- if (!track) {
1626
- throw new Error("No next track in the queue");
1365
+ addTrack(track) {
1366
+ __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
1367
+ const toAdd = track instanceof Playlist ? track.tracks : track;
1368
+ this.tracks.add(toAdd);
1369
+ const isMulti = Array.isArray(toAdd);
1370
+ if (isMulti) {
1371
+ this.player.events.emit("audioTrackAdd", this, toAdd[0]);
1372
+ this.player.events.emit("audioTracksAdd", this, toAdd);
1373
+ } else {
1374
+ this.player.events.emit("audioTrackAdd", this, toAdd);
1627
1375
  }
1628
- this.queue.node.skip();
1629
1376
  }
1630
- previous() {
1631
- const track = this.previousTrack;
1632
- if (!track) {
1633
- throw new Error("No previous track in the queue");
1377
+ async connect(channelResolvable, options = {}) {
1378
+ __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
1379
+ const channel = this.player.client.channels.resolve(channelResolvable);
1380
+ if (!channel || !channel.isVoiceBased()) {
1381
+ throw new Error(`Expected a voice based channel (type ${import_discord2.ChannelType.GuildVoice}/${import_discord2.ChannelType.GuildStageVoice}), received ${channel?.type}`);
1634
1382
  }
1635
- this.queue.node.play(track, { queue: true });
1636
- this.queue.node.skip();
1637
- }
1638
- };
1639
- __name(GuildQueueHistory, "GuildQueueHistory");
1640
-
1641
- // src/Structures/GuildQueue/GuildQueuePlayerNode.ts
1642
- var import_voice4 = require("@discordjs/voice");
1643
- var _progress, _createGenericStream, createGenericStream_fn, _createFFmpegStream, createFFmpegStream_fn;
1644
- var GuildQueuePlayerNode = class {
1645
- constructor(queue) {
1646
- this.queue = queue;
1647
- __privateAdd(this, _createGenericStream);
1648
- __privateAdd(this, _createFFmpegStream);
1649
- __privateAdd(this, _progress, 0);
1650
- }
1651
- isIdle() {
1652
- return !!this.queue.dispatcher?.isIdle();
1653
- }
1654
- isBuffering() {
1655
- return !!this.queue.dispatcher?.isBuffering();
1656
- }
1657
- isPlaying() {
1658
- return !!this.queue.dispatcher?.isPlaying();
1659
- }
1660
- isPaused() {
1661
- return !!this.queue.dispatcher?.isPaused();
1662
- }
1663
- resetProgress() {
1664
- __privateSet(this, _progress, 0);
1383
+ this.debug(`Connecting to ${channel.type === import_discord2.ChannelType.GuildStageVoice ? "stage" : "voice"} channel ${channel.name} (ID: ${channel.id})`);
1384
+ if (this.dispatcher) {
1385
+ this.debug("Destroying old connection");
1386
+ __privateMethod(this, _removeListeners, removeListeners_fn).call(this, this.dispatcher);
1387
+ this.dispatcher.disconnect();
1388
+ }
1389
+ this.dispatcher = await this.player.voiceUtils.connect(channel, {
1390
+ deaf: options.deaf ?? this.options.selfDeaf ?? true,
1391
+ maxTime: options?.timeout ?? this.options.connectionTimeout ?? 12e4,
1392
+ queue: this
1393
+ });
1394
+ this.player.events.emit("connection", this);
1395
+ if (this.channel.type === import_discord2.ChannelType.GuildStageVoice) {
1396
+ await this.channel.guild.members.me.voice.setSuppressed(false).catch(async () => {
1397
+ return await this.channel.guild.members.me.voice.setRequestToSpeak(true).catch(Util.noop);
1398
+ });
1399
+ }
1400
+ __privateMethod(this, _attachListeners, attachListeners_fn).call(this, this.dispatcher);
1401
+ return this;
1665
1402
  }
1666
- get playbackTime() {
1667
- if (this.queue.dispatcher?.streamTime == null)
1668
- return 0;
1669
- const dur = __privateGet(this, _progress) + this.queue.dispatcher.streamTime;
1670
- const hasNightcore = this.queue.filters.ffmpeg.filters.includes("nightcore");
1671
- const hasVwave = this.queue.filters.ffmpeg.filters.includes("vaporwave");
1672
- if (hasNightcore && hasVwave)
1673
- return dur * (1.25 + 0.8);
1674
- return hasNightcore ? dur * 1.25 : hasVwave ? dur * 0.8 : dur;
1675
- }
1676
- getTimestamp() {
1677
- if (!this.queue.currentTrack)
1678
- return null;
1679
- const current = this.playbackTime;
1680
- const total = this.queue.currentTrack.durationMS;
1681
- return {
1682
- current: {
1683
- label: Util.buildTimeCode(Util.parseMS(current)),
1684
- value: current
1685
- },
1686
- total: {
1687
- label: Util.buildTimeCode(Util.parseMS(total)),
1688
- value: total
1689
- },
1690
- progress: Math.round(current / total * 100)
1691
- };
1403
+ get ping() {
1404
+ return this.connection?.ping.udp ?? -1;
1692
1405
  }
1693
- createProgressBar(options) {
1694
- const timestamp = this.getTimestamp();
1695
- if (!timestamp)
1696
- return null;
1697
- const { indicator = "\u{1F518}", length = 15, line = "\u25AC", timecodes = true } = options || {};
1698
- if (isNaN(length) || length < 0 || !Number.isFinite(length))
1699
- throw new Error("invalid progressbar length");
1700
- const index = Math.round(timestamp.current.value / timestamp.total.value * length);
1701
- if (index >= 1 && index <= length) {
1702
- const bar = line.repeat(length - 1).split("");
1703
- bar.splice(index, 0, indicator);
1704
- if (timecodes) {
1705
- return `${timestamp.current.label} \u2503 ${bar.join("")} \u2503 ${timestamp.total.label}`;
1706
- } else {
1707
- return `${bar.join("")}`;
1708
- }
1709
- } else {
1710
- if (timecodes) {
1711
- return `${timestamp.current.label} \u2503 ${indicator}${line.repeat(length - 1)} \u2503 ${timestamp.total.label}`;
1712
- } else {
1713
- return `${indicator}${line.repeat(length - 1)}`;
1714
- }
1406
+ delete() {
1407
+ if (this.player.nodes.delete(this.id)) {
1408
+ __privateSet(this, _deleted, true);
1715
1409
  }
1716
1410
  }
1717
- async seek(duration) {
1718
- if (!this.queue.currentTrack)
1719
- return false;
1720
- await this.play(this.queue.currentTrack, {
1721
- seek: duration,
1722
- transitionMode: true
1723
- });
1724
- return true;
1725
- }
1726
- get volume() {
1727
- return this.queue.dispatcher?.volume ?? 100;
1728
- }
1729
- setVolume(vol) {
1730
- if (!this.queue.dispatcher)
1731
- return false;
1732
- const res = this.queue.dispatcher.setVolume(vol);
1733
- if (res)
1734
- this.queue.filters._lastFiltersCache.volume = vol;
1735
- return res;
1736
- }
1737
- setBitrate(rate) {
1738
- this.queue.dispatcher?.audioResource?.encoder?.setBitrate(rate === "auto" ? this.queue.channel?.bitrate ?? 64e3 : rate);
1739
- }
1740
- setPaused(state) {
1741
- if (state)
1742
- return this.queue.dispatcher?.pause(true) || false;
1743
- return this.queue.dispatcher?.resume() || false;
1744
- }
1745
- pause() {
1746
- return this.setPaused(true);
1747
- }
1748
- resume() {
1749
- return this.setPaused(false);
1750
- }
1751
- skip() {
1752
- if (!this.queue.dispatcher)
1753
- return false;
1754
- this.queue.setTransitioning(false);
1755
- this.queue.dispatcher.end();
1756
- return true;
1757
- }
1758
- remove(track) {
1759
- const foundTrack = this.queue.tracks.find((t, idx) => {
1760
- if (track instanceof Track || typeof track === "string") {
1761
- return (typeof track === "string" ? track : track.id) === t.id;
1762
- }
1763
- if (typeof track === "string")
1764
- return track === t.id;
1765
- return idx === track;
1411
+ awaitInitialization() {
1412
+ return new Promise((r) => {
1413
+ if (!__privateGet(this, _initializing))
1414
+ return r(true);
1415
+ __privateGet(this, _initializingPromises).push(r);
1766
1416
  });
1767
- if (!foundTrack)
1768
- return null;
1769
- this.queue.tracks.removeOne((t) => t.id === foundTrack.id);
1770
- return foundTrack;
1771
- }
1772
- jump(track) {
1773
- const removed = this.remove(track);
1774
- if (!removed)
1775
- return false;
1776
- this.queue.tracks.store.unshift(removed);
1777
- return this.skip();
1778
1417
  }
1779
- getTrackPosition(track) {
1780
- return this.queue.tracks.toArray().findIndex((t, idx) => {
1781
- if (track instanceof Track || typeof track === "string") {
1782
- return (typeof track === "string" ? track : track.id) === t.id;
1418
+ };
1419
+ __name(GuildQueue, "GuildQueue");
1420
+ _transitioning = new WeakMap();
1421
+ _initializing = new WeakMap();
1422
+ _deleted = new WeakMap();
1423
+ _initializingPromises = new WeakMap();
1424
+ _attachListeners = new WeakSet();
1425
+ attachListeners_fn = /* @__PURE__ */ __name(function(dispatcher) {
1426
+ dispatcher.on("error", (e) => this.player.events.emit("error", this, e));
1427
+ dispatcher.on("debug", (m) => this.player.events.emit("debug", this, m));
1428
+ dispatcher.on("finish", (r) => __privateMethod(this, _performFinish, performFinish_fn).call(this, r));
1429
+ dispatcher.on("start", (r) => __privateMethod(this, _performStart, performStart_fn).call(this, r));
1430
+ dispatcher.on("dsp", (f) => {
1431
+ this.filters._lastFiltersCache.filters = f;
1432
+ });
1433
+ dispatcher.on("biquad", (f) => {
1434
+ this.filters._lastFiltersCache.biquad = f;
1435
+ });
1436
+ dispatcher.on("eqBands", (f) => {
1437
+ this.filters._lastFiltersCache.equalizer = f;
1438
+ });
1439
+ dispatcher.on("volume", (f) => {
1440
+ this.filters._lastFiltersCache.volume = f;
1441
+ });
1442
+ }, "#attachListeners");
1443
+ _removeListeners = new WeakSet();
1444
+ removeListeners_fn = /* @__PURE__ */ __name(function(dispatcher) {
1445
+ dispatcher.removeAllListeners();
1446
+ }, "#removeListeners");
1447
+ _performStart = new WeakSet();
1448
+ performStart_fn = /* @__PURE__ */ __name(function(resource) {
1449
+ const track = resource?.metadata || this.currentTrack;
1450
+ this.player.events.emit("playerTrigger", this, track, this.isTransitioning() ? "filters" : "normal");
1451
+ if (track && !this.isTransitioning())
1452
+ this.player.events.emit("playerStart", this, track);
1453
+ this.setTransitioning(false);
1454
+ this.initializing = false;
1455
+ }, "#performStart");
1456
+ _performFinish = new WeakSet();
1457
+ performFinish_fn = /* @__PURE__ */ __name(function(resource) {
1458
+ const track = resource?.metadata || this.currentTrack;
1459
+ if (track && !this.isTransitioning()) {
1460
+ this.history.push(track);
1461
+ this.node.resetProgress();
1462
+ this.player.events.emit("playerFinish", this, track);
1463
+ if (this.tracks.size < 1 && this.repeatMode === 0 /* OFF */) {
1464
+ __privateMethod(this, _emitEnd, emitEnd_fn).call(this);
1465
+ } else {
1466
+ if (this.repeatMode === 1 /* TRACK */) {
1467
+ this.__current = this.history.tracks.dispatch() || track;
1468
+ return this.node.play(this.__current);
1783
1469
  }
1784
- if (typeof track === "string")
1785
- return track === t.id;
1786
- return idx === track;
1787
- });
1788
- }
1789
- skipTo(track) {
1790
- const idx = this.getTrackPosition(track);
1791
- if (idx < 0)
1792
- return false;
1793
- const removed = this.remove(idx);
1794
- if (!removed)
1795
- return false;
1796
- this.queue.tracks.store.splice(0, idx, removed);
1797
- return this.skip();
1798
- }
1799
- insert(track, index = 0) {
1800
- if (!(track instanceof Track))
1801
- throw new Error("invalid track");
1802
- this.queue.tracks.store.splice(index, 0, track);
1803
- }
1804
- stop(force = false) {
1805
- if (!this.queue.dispatcher)
1806
- return false;
1807
- this.queue.dispatcher.end();
1808
- if (force) {
1809
- this.queue.dispatcher.disconnect();
1810
- return true;
1811
- }
1812
- if (this.queue.options.leaveOnStop) {
1813
- const tm = setTimeout(() => {
1814
- if (this.isPlaying() || this.queue.tracks.size)
1815
- return clearTimeout(tm);
1816
- this.queue.dispatcher?.disconnect();
1817
- }, this.queue.options.leaveOnStopCooldown).unref();
1818
- }
1819
- return true;
1820
- }
1821
- async play(res, options) {
1822
- if (!this.queue.dispatcher?.voiceConnection) {
1823
- throw new Error("No voice connection available");
1824
- }
1825
- options = Object.assign(
1826
- {},
1827
- {
1828
- queue: this.queue.currentTrack != null,
1829
- transitionMode: false,
1830
- seek: 0
1831
- },
1832
- options
1833
- );
1834
- if (res && options.queue) {
1835
- return this.queue.tracks.add(res);
1836
- }
1837
- this.queue.debug(`Received play request from guild ${this.queue.guild.name} (ID: ${this.queue.guild.id})`);
1838
- const track = res || this.queue.tracks.dispatch();
1839
- if (!track) {
1840
- throw new Error("Play request received but track was not provided");
1841
- }
1842
- this.queue.initializing = true;
1843
- try {
1844
- const qt = track.queryType || (track.raw.source === "spotify" ? "spotifySong" : track.raw.source === "apple_music" ? "appleMusicSong" : track.raw.source) || "arbitrary";
1845
- const stream = await this.queue.onBeforeCreateStream?.(track, qt, this.queue).catch(() => null) || await __privateMethod(this, _createGenericStream, createGenericStream_fn).call(this, track).catch(() => null);
1846
- if (!stream) {
1847
- const error = new Error("Could not extract stream for this track");
1848
- this.queue.initializing = false;
1849
- if (this.queue.options.skipOnNoStream) {
1850
- this.queue.player.events.emit("playerSkip", this.queue, track);
1851
- this.queue.player.events.emit("playerError", this.queue, error, track);
1852
- this.play(this.queue.tracks.dispatch());
1470
+ if (this.repeatMode === 2 /* QUEUE */)
1471
+ this.tracks.add(this.history.tracks.dispatch() || track);
1472
+ if (!this.tracks.size) {
1473
+ if (this.repeatMode === 3 /* AUTOPLAY */) {
1474
+ __privateMethod(this, _handleAutoplay, handleAutoplay_fn).call(this, track);
1853
1475
  return;
1854
1476
  }
1855
- throw error;
1856
- }
1857
- if (typeof options.seek === "number" && options.seek >= 0) {
1858
- __privateSet(this, _progress, options.seek);
1859
1477
  } else {
1860
- __privateSet(this, _progress, 0);
1478
+ this.__current = this.tracks.dispatch();
1479
+ this.node.play(this.__current, {
1480
+ queue: false
1481
+ });
1861
1482
  }
1862
- const pcmStream = __privateMethod(this, _createFFmpegStream, createFFmpegStream_fn).call(this, stream, track, options.seek ?? 0);
1863
- const resource = this.queue.dispatcher.createStream(pcmStream, {
1864
- disableBiquad: this.queue.options.biquad === false,
1865
- disableEqualizer: this.queue.options.equalizer === false,
1866
- disableVolume: this.queue.options.volume === false,
1867
- disableFilters: this.queue.options.filterer === false,
1868
- disableResampler: this.queue.options.resampler === false,
1869
- sampleRate: typeof this.queue.options.resampler === "number" && this.queue.options.resampler > 0 ? this.queue.options.resampler : void 0,
1870
- biquadFilter: this.queue.filters._lastFiltersCache.biquad || void 0,
1871
- eq: this.queue.filters._lastFiltersCache.equalizer,
1872
- defaultFilters: this.queue.filters._lastFiltersCache.filters,
1873
- volume: this.queue.filters._lastFiltersCache.volume,
1874
- data: track,
1875
- type: import_voice4.StreamType.Raw
1876
- });
1877
- this.queue.setTransitioning(!!options.transitionMode);
1878
- await this.queue.dispatcher.playStream(resource);
1879
- } catch (e) {
1880
- this.queue.initializing = false;
1881
- throw e;
1882
1483
  }
1883
1484
  }
1884
- };
1885
- __name(GuildQueuePlayerNode, "GuildQueuePlayerNode");
1886
- _progress = new WeakMap();
1887
- _createGenericStream = new WeakSet();
1888
- createGenericStream_fn = /* @__PURE__ */ __name(async function(track) {
1889
- const streamInfo = await this.queue.player.extractors.run(async (extractor) => {
1890
- const canStream = await extractor.validate(track.url, track.queryType || QueryResolver.resolve(track.url));
1891
- if (!canStream)
1892
- return false;
1893
- return await extractor.stream(track);
1894
- });
1895
- if (!streamInfo || !streamInfo.result) {
1896
- return null;
1485
+ }, "#performFinish");
1486
+ _emitEnd = new WeakSet();
1487
+ emitEnd_fn = /* @__PURE__ */ __name(function() {
1488
+ this.__current = null;
1489
+ this.player.events.emit("emptyQueue", this);
1490
+ if (this.options.leaveOnEnd) {
1491
+ const tm = (0, import_timers.setTimeout)(() => {
1492
+ if (this.tracks.size)
1493
+ return clearTimeout(tm);
1494
+ this.dispatcher?.disconnect();
1495
+ }, this.options.leaveOnEndCooldown).unref();
1897
1496
  }
1898
- const stream = streamInfo.result;
1899
- return stream;
1900
- }, "#createGenericStream");
1901
- _createFFmpegStream = new WeakSet();
1902
- createFFmpegStream_fn = /* @__PURE__ */ __name(function(stream, track, seek = 0) {
1903
- const ffmpegStream = createFFmpegStream(stream, {
1904
- encoderArgs: this.queue.filters.ffmpeg.filters.length ? ["-af", AudioFilters_default.create(this.queue.filters.ffmpeg.filters)] : [],
1905
- seek: seek / 1e3,
1906
- fmt: "s16le"
1907
- }).on("error", (err) => {
1908
- if (!`${err}`.toLowerCase().includes("premature close"))
1909
- this.queue.player.events.emit("playerError", this.queue, err, track);
1497
+ }, "#emitEnd");
1498
+ _handleAutoplay = new WeakSet();
1499
+ handleAutoplay_fn = /* @__PURE__ */ __name(async function(track) {
1500
+ let info = await import_youtube_sr2.YouTube.getVideo(track.url).then((x) => x.videos[0]).catch(Util.noop);
1501
+ if (!info)
1502
+ info = await import_youtube_sr2.YouTube.search(track.author).then((x) => x[0]).catch(Util.noop);
1503
+ if (!info) {
1504
+ return __privateMethod(this, _emitEnd, emitEnd_fn).call(this);
1505
+ }
1506
+ const nextTrack = new Track(this.player, {
1507
+ title: info.title,
1508
+ url: `https://www.youtube.com/watch?v=${info.id}`,
1509
+ duration: info.durationFormatted || Util.buildTimeCode(Util.parseMS(info.duration * 1e3)),
1510
+ description: info.title,
1511
+ thumbnail: typeof info.thumbnail === "string" ? info.thumbnail : info.thumbnail.url,
1512
+ views: info.views,
1513
+ author: info.channel.name,
1514
+ requestedBy: track.requestedBy,
1515
+ source: "youtube",
1516
+ queryType: "youtubeVideo"
1910
1517
  });
1911
- return ffmpegStream;
1912
- }, "#createFFmpegStream");
1518
+ this.node.play(nextTrack, {
1519
+ queue: false,
1520
+ seek: 0,
1521
+ transitionMode: false
1522
+ });
1523
+ }, "#handleAutoplay");
1524
+ _resolveInitializerAwaiters = new WeakSet();
1525
+ resolveInitializerAwaiters_fn = /* @__PURE__ */ __name(function() {
1526
+ __privateGet(this, _initializingPromises).forEach((p) => {
1527
+ p(!__privateGet(this, _initializing));
1528
+ });
1529
+ __privateSet(this, _initializingPromises, []);
1530
+ }, "#resolveInitializerAwaiters");
1531
+ _warnIfDeleted = new WeakSet();
1532
+ warnIfDeleted_fn = /* @__PURE__ */ __name(function() {
1533
+ if (!this.deleted)
1534
+ return;
1535
+ Util.warn("Deleted queue usage detected! Please remove references to deleted queues in order to prevent memory leaks.", "DiscordPlayerWarning");
1536
+ }, "#warnIfDeleted");
1913
1537
 
1914
- // src/Structures/GuildQueue/GuildQueueAudioFilters.ts
1915
- var import_equalizer2 = require("@discord-player/equalizer");
1916
- var EqualizerConfigurationPreset = {
1917
- Jazz: Array.from({ length: 15 }, (_, i) => ({
1918
- band: i,
1919
- gain: i > 2 && i < 6 ? 0.5 : i > 6 && i < 14 ? -0.75 : 0
1920
- })),
1921
- EDM: Array.from(
1922
- {
1923
- length: import_equalizer2.Equalizer.BAND_COUNT
1924
- },
1925
- (_, i) => ({
1926
- band: i,
1927
- gain: i > 3 && i < 7 ? 0.75 : i > 9 && i < 13 ? -0.75 : 0
1928
- })
1929
- ),
1930
- HipHop: Array.from(
1931
- {
1932
- length: import_equalizer2.Equalizer.BAND_COUNT
1933
- },
1934
- (_, i) => ({
1935
- band: i,
1936
- gain: i > 4 && i < 8 ? 0.75 : i > 10 && i < 14 ? -0.5 : 0
1937
- })
1938
- ),
1939
- Rock: Array.from(
1940
- {
1941
- length: import_equalizer2.Equalizer.BAND_COUNT
1942
- },
1943
- (_, i) => ({
1944
- band: i,
1945
- gain: i > 2 && i < 6 ? 0.75 : i > 8 && i < 12 ? -0.75 : 0
1946
- })
1947
- ),
1948
- Metal: Array.from(
1949
- {
1950
- length: import_equalizer2.Equalizer.BAND_COUNT
1951
- },
1952
- (_, i) => ({
1953
- band: i,
1954
- gain: i > 4 && i < 8 ? 0.75 : i > 9 && i < 14 ? -0.75 : 0
1955
- })
1956
- ),
1957
- Folk: Array.from(
1958
- {
1959
- length: import_equalizer2.Equalizer.BAND_COUNT
1960
- },
1961
- (_, i) => ({
1962
- band: i,
1963
- gain: i > 3 && i < 7 ? 0.5 : i > 9 && i < 14 ? -0.5 : 0
1964
- })
1965
- ),
1966
- RnB: Array.from(
1967
- {
1968
- length: import_equalizer2.Equalizer.BAND_COUNT
1969
- },
1970
- (_, i) => ({
1971
- band: i,
1972
- gain: i > 4 && i < 8 ? 0.5 : i > 9 && i < 14 ? -0.5 : 0
1973
- })
1974
- ),
1975
- Country: Array.from(
1976
- {
1977
- length: import_equalizer2.Equalizer.BAND_COUNT
1978
- },
1979
- (_, i) => ({
1980
- band: i,
1981
- gain: i > 2 && i < 6 ? 0.5 : i > 9 && i < 13 ? -0.5 : 0
1982
- })
1983
- ),
1984
- Classical: Array.from(
1985
- {
1986
- length: import_equalizer2.Equalizer.BAND_COUNT
1987
- },
1988
- (_, i) => ({
1989
- band: i,
1990
- gain: i > 4 && i < 8 ? 0.5 : i > 10 && i < 14 ? -0.5 : 0
1991
- })
1992
- )
1993
- };
1994
- var _ffmpegFilters, _setFilters, setFilters_fn;
1995
- var FFmpegFilterer = class {
1996
- constructor(af) {
1997
- this.af = af;
1998
- __privateAdd(this, _setFilters);
1999
- __privateAdd(this, _ffmpegFilters, []);
1538
+ // src/Structures/GuildNodeManager.ts
1539
+ var GuildNodeManager = class {
1540
+ constructor(player) {
1541
+ this.player = player;
1542
+ this.cache = new import_utils4.Collection();
2000
1543
  }
2001
- setFilters(filters) {
2002
- let _filters = [];
2003
- if (typeof filters === "boolean") {
2004
- _filters = !filters ? [] : Object.keys(AudioFilters_default.filters);
2005
- } else if (Array.isArray(filters)) {
2006
- _filters = filters;
2007
- } else {
2008
- _filters = Object.entries(filters).filter((res) => res[1] === true).map((m) => m[0]);
1544
+ create(guild, options = {}) {
1545
+ const server = this.player.client.guilds.resolve(guild);
1546
+ if (!server) {
1547
+ throw new Error("Invalid or unknown guild");
2009
1548
  }
2010
- return __privateMethod(this, _setFilters, setFilters_fn).call(this, _filters);
2011
- }
2012
- get filters() {
2013
- return __privateGet(this, _ffmpegFilters);
2014
- }
2015
- set filters(filters) {
2016
- this.setFilters(filters);
2017
- }
2018
- toggle(filters) {
2019
- if (!Array.isArray(filters))
2020
- filters = [filters];
2021
- const fresh = [];
2022
- this.filters.forEach((f) => {
2023
- if (this.filters.includes(f))
2024
- return;
2025
- fresh.push(f);
1549
+ if (this.cache.has(server.id)) {
1550
+ return this.cache.get(server.id);
1551
+ }
1552
+ options.strategy ?? (options.strategy = "FIFO");
1553
+ options.volume ?? (options.volume = 100);
1554
+ options.equalizer ?? (options.equalizer = []);
1555
+ options.a_filter ?? (options.a_filter = []);
1556
+ options.disableHistory ?? (options.disableHistory = false);
1557
+ options.skipOnNoStream ?? (options.skipOnNoStream = false);
1558
+ options.leaveOnEmpty ?? (options.leaveOnEmpty = true);
1559
+ options.leaveOnEmptyCooldown ?? (options.leaveOnEmptyCooldown = 0);
1560
+ options.leaveOnEnd ?? (options.leaveOnEnd = true);
1561
+ options.leaveOnEndCooldown ?? (options.leaveOnEndCooldown = 0);
1562
+ options.leaveOnStop ?? (options.leaveOnStop = true);
1563
+ options.leaveOnStopCooldown ?? (options.leaveOnStopCooldown = 0);
1564
+ options.resampler ?? (options.resampler = 48e3);
1565
+ options.selfDeaf ?? (options.selfDeaf = true);
1566
+ options.connectionTimeout ?? (options.connectionTimeout = this.player.options.connectionTimeout);
1567
+ options.bufferingTimeout ?? (options.bufferingTimeout = 1e3);
1568
+ const queue = new GuildQueue(this.player, {
1569
+ guild: server,
1570
+ queueStrategy: options.strategy,
1571
+ volume: options.volume,
1572
+ equalizer: options.equalizer,
1573
+ filterer: options.a_filter,
1574
+ biquad: options.biquad,
1575
+ resampler: options.resampler,
1576
+ disableHistory: options.disableHistory,
1577
+ skipOnNoStream: options.skipOnNoStream,
1578
+ onBeforeCreateStream: options.onBeforeCreateStream,
1579
+ onAfterCreateStream: options.onAfterCreateStream,
1580
+ repeatMode: options.repeatMode,
1581
+ leaveOnEmpty: options.leaveOnEmpty,
1582
+ leaveOnEmptyCooldown: options.leaveOnEmptyCooldown,
1583
+ leaveOnEnd: options.leaveOnEnd,
1584
+ leaveOnEndCooldown: options.leaveOnEndCooldown,
1585
+ leaveOnStop: options.leaveOnStop,
1586
+ leaveOnStopCooldown: options.leaveOnStopCooldown,
1587
+ metadata: options.metadata,
1588
+ connectionTimeout: options.connectionTimeout ?? 12e4,
1589
+ selfDeaf: options.selfDeaf,
1590
+ ffmpegFilters: options.defaultFFmpegFilters ?? [],
1591
+ bufferingTimeout: options.bufferingTimeout
2026
1592
  });
2027
- return __privateMethod(this, _setFilters, setFilters_fn).call(this, __privateGet(this, _ffmpegFilters).filter((r) => !filters.includes(r)).concat(fresh));
2028
- }
2029
- getFiltersEnabled() {
2030
- return __privateGet(this, _ffmpegFilters);
2031
- }
2032
- getFiltersDisabled() {
2033
- return AudioFilters_default.names.filter((f) => !__privateGet(this, _ffmpegFilters).includes(f));
1593
+ this.cache.set(server.id, queue);
1594
+ return queue;
2034
1595
  }
2035
- isEnabled(filter) {
2036
- return __privateGet(this, _ffmpegFilters).includes(filter);
1596
+ get(node) {
1597
+ const queue = this.resolve(node);
1598
+ if (!queue)
1599
+ return null;
1600
+ return this.cache.get(queue.id) || null;
2037
1601
  }
2038
- isDisabled(filter) {
2039
- return !this.isEnabled(filter);
1602
+ has(node) {
1603
+ const id = node instanceof GuildQueue ? node.id : this.player.client.guilds.resolveId(node);
1604
+ return this.cache.has(id);
2040
1605
  }
2041
- isValidFilter(filter) {
2042
- return AudioFilters_default.has(filter);
1606
+ delete(node) {
1607
+ const queue = this.resolve(node);
1608
+ if (!queue)
1609
+ throw new Error("Cannot delete non-existing queue");
1610
+ queue.node.stop(true);
1611
+ queue.connection?.removeAllListeners();
1612
+ queue.dispatcher?.removeAllListeners();
1613
+ queue.dispatcher?.disconnect();
1614
+ queue.timeouts.forEach((tm) => clearTimeout(tm));
1615
+ queue.history.clear();
1616
+ queue.tracks.clear();
1617
+ return this.cache.delete(queue.id);
2043
1618
  }
2044
- };
2045
- __name(FFmpegFilterer, "FFmpegFilterer");
2046
- _ffmpegFilters = new WeakMap();
2047
- _setFilters = new WeakSet();
2048
- setFilters_fn = /* @__PURE__ */ __name(function(filters) {
2049
- __privateSet(this, _ffmpegFilters, [...new Set(filters)]);
2050
- return this.af.triggerReplay(this.af.queue.node.getTimestamp()?.current.value || 0);
2051
- }, "#setFilters");
2052
- var GuildQueueAudioFilters = class {
2053
- constructor(queue) {
2054
- this.queue = queue;
2055
- this.graph = new AFilterGraph(this);
2056
- this.ffmpeg = new FFmpegFilterer(this);
2057
- this.equalizerPresets = EqualizerConfigurationPreset;
2058
- this._lastFiltersCache = {
2059
- biquad: null,
2060
- equalizer: [],
2061
- filters: [],
2062
- volume: 100,
2063
- sampleRate: -1
2064
- };
2065
- if (typeof this.queue.options.volume === "number") {
2066
- this._lastFiltersCache.volume = this.queue.options.volume;
1619
+ resolve(node) {
1620
+ if (node instanceof GuildQueue) {
1621
+ return node;
2067
1622
  }
1623
+ return this.cache.get(this.player.client.guilds.resolveId(node));
2068
1624
  }
2069
- get volume() {
2070
- return this.queue.dispatcher?.dsp?.volume || null;
2071
- }
2072
- get equalizer() {
2073
- return this.queue.dispatcher?.equalizer || null;
1625
+ resolveId(node) {
1626
+ const q = this.resolve(node);
1627
+ return q?.id || null;
2074
1628
  }
2075
- get biquad() {
2076
- return this.queue.dispatcher?.biquad || null;
1629
+ };
1630
+ __name(GuildNodeManager, "GuildNodeManager");
1631
+
1632
+ // src/Structures/SearchResult.ts
1633
+ var SearchResult = class {
1634
+ constructor(player, _data) {
1635
+ this.player = player;
1636
+ this._data = _data;
2077
1637
  }
2078
- get filters() {
2079
- return this.queue.dispatcher?.filters || null;
1638
+ get query() {
1639
+ return this._data.query;
2080
1640
  }
2081
- get resampler() {
2082
- return this.queue.dispatcher?.resampler || null;
1641
+ get queryType() {
1642
+ return this._data.queryType || QueryType.AUTO;
2083
1643
  }
2084
- async triggerReplay(seek = 0) {
2085
- if (!this.queue.currentTrack)
2086
- return false;
2087
- try {
2088
- await this.queue.node.play(this.queue.currentTrack, {
2089
- queue: false,
2090
- seek,
2091
- transitionMode: true
2092
- });
2093
- return true;
2094
- } catch {
2095
- return false;
2096
- }
1644
+ get extractor() {
1645
+ return this._data.extractor || null;
2097
1646
  }
2098
- };
2099
- __name(GuildQueueAudioFilters, "GuildQueueAudioFilters");
2100
- var AFilterGraph = class {
2101
- constructor(af) {
2102
- this.af = af;
1647
+ get playlist() {
1648
+ return this._data.playlist;
2103
1649
  }
2104
- get ffmpeg() {
2105
- return this.af.ffmpeg.filters;
1650
+ get tracks() {
1651
+ return this._data.tracks || [];
2106
1652
  }
2107
- get equalizer() {
2108
- return (this.af.equalizer?.bandMultipliers || []).map((m, i) => ({
2109
- band: i,
2110
- gain: m
2111
- }));
1653
+ get requestedBy() {
1654
+ return this._data.requestedBy || null;
2112
1655
  }
2113
- get biquad() {
2114
- return null;
1656
+ async execute() {
1657
+ return this.player.search(this.query, {
1658
+ searchEngine: this.queryType,
1659
+ requestedBy: this.requestedBy
1660
+ });
2115
1661
  }
2116
- get filters() {
2117
- return this.af.filters?.filters || [];
1662
+ isEmpty() {
1663
+ return !this.tracks.length;
2118
1664
  }
2119
- get volume() {
2120
- return this.af.volume;
1665
+ hasPlaylist() {
1666
+ return this.playlist != null;
2121
1667
  }
2122
- get resampler() {
2123
- return this.af.resampler;
1668
+ hasTracks() {
1669
+ return this.tracks.length > 0;
2124
1670
  }
2125
- dump() {
1671
+ toJSON() {
2126
1672
  return {
2127
- ffmpeg: this.ffmpeg,
2128
- equalizer: this.equalizer,
2129
- biquad: this.biquad,
2130
- filters: this.filters,
2131
- sampleRate: this.resampler?.targetSampleRate || this.resampler?.sampleRate || 48e3,
2132
- volume: this.volume?.volume ?? 100
1673
+ query: this.query,
1674
+ queryType: this.queryType,
1675
+ playlist: this.playlist?.toJSON(false) || null,
1676
+ tracks: this.tracks.map((m) => m.toJSON(true)),
1677
+ extractor: this.extractor?.identifier || null,
1678
+ requestedBy: this.requestedBy?.toJSON() || null
2133
1679
  };
2134
1680
  }
2135
1681
  };
2136
- __name(AFilterGraph, "AFilterGraph");
1682
+ __name(SearchResult, "SearchResult");
2137
1683
 
2138
- // src/Structures/GuildQueue/GuildQueue.ts
2139
- var import_timers = require("timers");
2140
- var import_youtube_sr3 = require("youtube-sr");
2141
- var _transitioning, _initializing, _deleted, _initializingPromises, _attachListeners, attachListeners_fn, _removeListeners, removeListeners_fn, _performStart, performStart_fn, _performFinish, performFinish_fn, _emitEnd, emitEnd_fn, _handleAutoplay, handleAutoplay_fn, _resolveInitializerAwaiters, resolveInitializerAwaiters_fn, _warnIfDeleted, warnIfDeleted_fn;
2142
- var GuildQueue = class {
2143
- constructor(player, options) {
2144
- this.player = player;
2145
- this.options = options;
2146
- __privateAdd(this, _attachListeners);
2147
- __privateAdd(this, _removeListeners);
2148
- __privateAdd(this, _performStart);
2149
- __privateAdd(this, _performFinish);
2150
- __privateAdd(this, _emitEnd);
2151
- __privateAdd(this, _handleAutoplay);
2152
- __privateAdd(this, _resolveInitializerAwaiters);
2153
- __privateAdd(this, _warnIfDeleted);
2154
- __privateAdd(this, _transitioning, false);
2155
- __privateAdd(this, _initializing, false);
2156
- __privateAdd(this, _deleted, false);
2157
- __privateAdd(this, _initializingPromises, []);
2158
- this.__current = null;
2159
- this.history = new GuildQueueHistory(this);
2160
- this.dispatcher = null;
2161
- this.node = new GuildQueuePlayerNode(this);
2162
- this.filters = new GuildQueueAudioFilters(this);
2163
- this.onBeforeCreateStream = /* @__PURE__ */ __name(async () => null, "onBeforeCreateStream");
2164
- this.repeatMode = 0 /* OFF */;
2165
- this.timeouts = new import_utils6.Collection();
2166
- this.tracks = new import_utils6.Queue(options.queueStrategy);
2167
- if (typeof options.onBeforeCreateStream === "function")
2168
- this.onBeforeCreateStream = options.onBeforeCreateStream;
2169
- if (options.repeatMode != null)
2170
- this.repeatMode = options.repeatMode;
2171
- if (this.options.biquad != null && typeof this.options.biquad !== "boolean") {
2172
- this.filters._lastFiltersCache.biquad = this.options.biquad;
2173
- }
2174
- if (Array.isArray(this.options.equalizer)) {
2175
- this.filters._lastFiltersCache.equalizer = this.options.equalizer;
2176
- }
2177
- if (Array.isArray(this.options.filterer)) {
2178
- this.filters._lastFiltersCache.filters = this.options.filterer;
2179
- }
2180
- if (typeof this.options.resampler === "number") {
2181
- this.filters._lastFiltersCache.sampleRate = this.options.resampler;
2182
- }
2183
- this.debug(`GuildQueue initialized for guild ${this.options.guild.name} (ID: ${this.options.guild.id})`);
1684
+ // src/Structures/PlayerError.ts
1685
+ var ErrorStatusCode = /* @__PURE__ */ ((ErrorStatusCode2) => {
1686
+ ErrorStatusCode2["STREAM_ERROR"] = "StreamError";
1687
+ ErrorStatusCode2["AUDIO_PLAYER_ERROR"] = "AudioPlayerError";
1688
+ ErrorStatusCode2["PLAYER_ERROR"] = "PlayerError";
1689
+ ErrorStatusCode2["NO_AUDIO_RESOURCE"] = "NoAudioResource";
1690
+ ErrorStatusCode2["UNKNOWN_GUILD"] = "UnknownGuild";
1691
+ ErrorStatusCode2["INVALID_ARG_TYPE"] = "InvalidArgType";
1692
+ ErrorStatusCode2["UNKNOWN_EXTRACTOR"] = "UnknownExtractor";
1693
+ ErrorStatusCode2["INVALID_EXTRACTOR"] = "InvalidExtractor";
1694
+ ErrorStatusCode2["INVALID_CHANNEL_TYPE"] = "InvalidChannelType";
1695
+ ErrorStatusCode2["INVALID_TRACK"] = "InvalidTrack";
1696
+ ErrorStatusCode2["UNKNOWN_REPEAT_MODE"] = "UnknownRepeatMode";
1697
+ ErrorStatusCode2["TRACK_NOT_FOUND"] = "TrackNotFound";
1698
+ ErrorStatusCode2["NO_CONNECTION"] = "NoConnection";
1699
+ ErrorStatusCode2["DESTROYED_QUEUE"] = "DestroyedQueue";
1700
+ return ErrorStatusCode2;
1701
+ })(ErrorStatusCode || {});
1702
+ var PlayerError = class extends Error {
1703
+ constructor(message, code = "PlayerError" /* PLAYER_ERROR */) {
1704
+ super();
1705
+ this.createdAt = new Date();
1706
+ this.message = `[${code}] ${message}`;
1707
+ this.statusCode = code;
1708
+ this.name = code;
1709
+ Error.captureStackTrace(this);
2184
1710
  }
2185
- debug(m) {
2186
- this.player.events.emit("debug", this, m);
1711
+ get createdTimestamp() {
1712
+ return this.createdAt.getTime();
2187
1713
  }
2188
- get metadata() {
2189
- return this.options.metadata;
1714
+ valueOf() {
1715
+ return this.statusCode;
2190
1716
  }
2191
- set metadata(m) {
2192
- this.options.metadata = m;
1717
+ toJSON() {
1718
+ return {
1719
+ stack: this.stack,
1720
+ code: this.statusCode,
1721
+ message: this.message,
1722
+ created: this.createdTimestamp
1723
+ };
1724
+ }
1725
+ toString() {
1726
+ return this.stack;
1727
+ }
1728
+ };
1729
+ __name(PlayerError, "PlayerError");
1730
+
1731
+ // src/VoiceInterface/VoiceUtils.ts
1732
+ var import_voice4 = require("@discordjs/voice");
1733
+
1734
+ // src/VoiceInterface/StreamDispatcher.ts
1735
+ var import_voice3 = require("@discordjs/voice");
1736
+ var import_utils5 = require("@discord-player/utils");
1737
+ var import_equalizer2 = require("@discord-player/equalizer");
1738
+ var StreamDispatcher = class extends import_utils5.EventEmitter {
1739
+ constructor(connection, channel, queue, connectionTimeout = 2e4) {
1740
+ super();
1741
+ this.queue = queue;
1742
+ this.connectionTimeout = connectionTimeout;
1743
+ this.readyLock = false;
1744
+ this.dsp = new import_equalizer2.FiltersChain();
1745
+ this.voiceConnection = connection;
1746
+ this.audioPlayer = (0, import_voice3.createAudioPlayer)();
1747
+ this.channel = channel;
1748
+ this.dsp.onUpdate = () => {
1749
+ if (!this.dsp)
1750
+ return;
1751
+ if (this.dsp.filters?.filters)
1752
+ this.emit("dsp", this.dsp.filters?.filters);
1753
+ if (this.dsp.biquad?.filter)
1754
+ this.emit("biquad", this.dsp.biquad?.filter);
1755
+ if (this.dsp.equalizer)
1756
+ this.emit("eqBands", this.dsp.equalizer.getEQ());
1757
+ if (this.dsp.volume)
1758
+ this.emit("volume", this.dsp.volume.volume);
1759
+ if (this.dsp.resampler)
1760
+ this.emit("sampleRate", this.dsp.resampler.targetSampleRate);
1761
+ };
1762
+ this.dsp.onError = (e) => this.emit("error", e);
1763
+ this.voiceConnection.on("stateChange", async (_, newState) => {
1764
+ if (newState.status === import_voice3.VoiceConnectionStatus.Disconnected) {
1765
+ if (newState.reason === import_voice3.VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
1766
+ try {
1767
+ await (0, import_voice3.entersState)(this.voiceConnection, import_voice3.VoiceConnectionStatus.Connecting, this.connectionTimeout);
1768
+ } catch {
1769
+ try {
1770
+ this.voiceConnection.destroy();
1771
+ } catch (err) {
1772
+ this.emit("error", err);
1773
+ }
1774
+ }
1775
+ } else if (this.voiceConnection.rejoinAttempts < 5) {
1776
+ await Util.wait((this.voiceConnection.rejoinAttempts + 1) * 5e3);
1777
+ this.voiceConnection.rejoin();
1778
+ } else {
1779
+ try {
1780
+ this.voiceConnection.destroy();
1781
+ } catch (err) {
1782
+ this.emit("error", err);
1783
+ }
1784
+ }
1785
+ } else if (newState.status === import_voice3.VoiceConnectionStatus.Destroyed) {
1786
+ this.end();
1787
+ } else if (!this.readyLock && (newState.status === import_voice3.VoiceConnectionStatus.Connecting || newState.status === import_voice3.VoiceConnectionStatus.Signalling)) {
1788
+ this.readyLock = true;
1789
+ try {
1790
+ await (0, import_voice3.entersState)(this.voiceConnection, import_voice3.VoiceConnectionStatus.Ready, this.connectionTimeout);
1791
+ } catch {
1792
+ if (this.voiceConnection.state.status !== import_voice3.VoiceConnectionStatus.Destroyed) {
1793
+ try {
1794
+ this.voiceConnection.destroy();
1795
+ } catch (err) {
1796
+ this.emit("error", err);
1797
+ }
1798
+ }
1799
+ } finally {
1800
+ this.readyLock = false;
1801
+ }
1802
+ }
1803
+ });
1804
+ this.audioPlayer.on("stateChange", (oldState, newState) => {
1805
+ if (newState.status === import_voice3.AudioPlayerStatus.Playing) {
1806
+ if (oldState.status === import_voice3.AudioPlayerStatus.Idle || oldState.status === import_voice3.AudioPlayerStatus.Buffering) {
1807
+ return this.emit("start", this.audioResource);
1808
+ }
1809
+ } else if (newState.status === import_voice3.AudioPlayerStatus.Idle && oldState.status !== import_voice3.AudioPlayerStatus.Idle) {
1810
+ this.emit("finish", this.audioResource);
1811
+ this.dsp.destroy();
1812
+ this.audioResource = null;
1813
+ }
1814
+ });
1815
+ this.audioPlayer.on("debug", (m) => void this.emit("debug", m));
1816
+ this.audioPlayer.on("error", (error) => void this.emit("error", error));
1817
+ this.voiceConnection.subscribe(this.audioPlayer);
2193
1818
  }
2194
- setMetadata(m) {
2195
- __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
2196
- this.options.metadata = m;
1819
+ get paused() {
1820
+ return this.audioPlayer.state.status === import_voice3.AudioPlayerStatus.Paused;
2197
1821
  }
2198
- get initializing() {
2199
- return __privateGet(this, _initializing);
1822
+ set paused(val) {
1823
+ val ? this.pause(true) : this.resume();
2200
1824
  }
2201
- set initializing(v) {
2202
- __privateSet(this, _initializing, v);
2203
- if (v)
2204
- __privateMethod(this, _resolveInitializerAwaiters, resolveInitializerAwaiters_fn).call(this);
1825
+ isPaused() {
1826
+ return this.paused || this.audioPlayer.state.status === import_voice3.AudioPlayerStatus.AutoPaused;
2205
1827
  }
2206
- get currentTrack() {
2207
- return this.dispatcher?.audioResource?.metadata || this.__current;
1828
+ isBuffering() {
1829
+ return this.audioPlayer.state.status === import_voice3.AudioPlayerStatus.Buffering;
2208
1830
  }
2209
- get deleted() {
2210
- return __privateGet(this, _deleted);
1831
+ isPlaying() {
1832
+ return this.audioPlayer.state.status === import_voice3.AudioPlayerStatus.Playing;
2211
1833
  }
2212
- get channel() {
2213
- return this.dispatcher?.channel || null;
1834
+ isIdle() {
1835
+ return this.audioPlayer.state.status === import_voice3.AudioPlayerStatus.Idle;
2214
1836
  }
2215
- set channel(c) {
2216
- if (this.dispatcher) {
2217
- if (c) {
2218
- this.dispatcher.channel = c;
2219
- } else {
2220
- this.delete();
1837
+ async createStream(src, ops) {
1838
+ if (!ops?.disableFilters)
1839
+ this.queue.debug("Initiating DSP filters pipeline...");
1840
+ const stream = !ops?.disableFilters ? this.dsp.create(src, {
1841
+ dsp: {
1842
+ filters: ops?.defaultFilters,
1843
+ disabled: ops?.disableFilters
1844
+ },
1845
+ biquad: ops?.biquadFilter ? {
1846
+ filter: ops.biquadFilter,
1847
+ disabled: ops?.disableBiquad
1848
+ } : void 0,
1849
+ resampler: {
1850
+ targetSampleRate: ops?.sampleRate,
1851
+ disabled: ops?.disableResampler
1852
+ },
1853
+ equalizer: {
1854
+ bandMultiplier: ops?.eq,
1855
+ disabled: ops?.disableEqualizer
1856
+ },
1857
+ volume: {
1858
+ volume: ops?.volume,
1859
+ disabled: ops?.disableVolume
2221
1860
  }
2222
- }
1861
+ }) : src;
1862
+ this.queue.debug("Executing onAfterCreateStream hook...");
1863
+ const postStream = await this.queue.onAfterCreateStream?.(stream, this.queue).catch(
1864
+ () => ({
1865
+ stream,
1866
+ type: ops?.type ?? import_voice3.StreamType.Arbitrary
1867
+ })
1868
+ );
1869
+ this.queue.debug("Preparing AudioResource...");
1870
+ this.audioResource = (0, import_voice3.createAudioResource)(postStream?.stream ?? stream, {
1871
+ inputType: postStream?.type ?? ops?.type ?? import_voice3.StreamType.Arbitrary,
1872
+ metadata: ops?.data,
1873
+ inlineVolume: false
1874
+ });
1875
+ return this.audioResource;
2223
1876
  }
2224
- get connection() {
2225
- return this.dispatcher?.voiceConnection || null;
1877
+ get resampler() {
1878
+ return this.dsp?.resampler;
2226
1879
  }
2227
- get guild() {
2228
- return this.options.guild;
1880
+ get filters() {
1881
+ return this.dsp?.filters;
2229
1882
  }
2230
- get id() {
2231
- return this.guild.id;
1883
+ get biquad() {
1884
+ return this.dsp?.biquad || null;
2232
1885
  }
2233
- setTransitioning(state) {
2234
- __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
2235
- __privateSet(this, _transitioning, state);
1886
+ get equalizer() {
1887
+ return this.dsp?.equalizer || null;
2236
1888
  }
2237
- isTransitioning() {
2238
- return __privateGet(this, _transitioning);
1889
+ get status() {
1890
+ return this.audioPlayer.state.status;
2239
1891
  }
2240
- setRepeatMode(mode) {
2241
- __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
2242
- this.repeatMode = mode;
1892
+ disconnect() {
1893
+ try {
1894
+ if (this.audioPlayer)
1895
+ this.audioPlayer.stop(true);
1896
+ this.voiceConnection.destroy();
1897
+ } catch {
1898
+ }
2243
1899
  }
2244
- isEmpty() {
2245
- __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
2246
- return this.tracks.size < 1;
1900
+ end() {
1901
+ this.audioPlayer.stop();
2247
1902
  }
2248
- isPlaying() {
2249
- __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
2250
- return this.dispatcher?.audioResource != null;
1903
+ pause(interpolateSilence) {
1904
+ const success = this.audioPlayer.pause(interpolateSilence);
1905
+ return success;
2251
1906
  }
2252
- addTrack(track) {
2253
- __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
2254
- const toAdd = track instanceof Playlist ? track.tracks : track;
2255
- this.tracks.add(toAdd);
2256
- const isMulti = Array.isArray(toAdd);
2257
- if (isMulti) {
2258
- this.player.events.emit("audioTracksAdd", this, toAdd);
2259
- } else {
2260
- this.player.events.emit("audioTrackAdd", this, toAdd);
2261
- }
1907
+ resume() {
1908
+ const success = this.audioPlayer.unpause();
1909
+ return success;
2262
1910
  }
2263
- async connect(channelResolvable, options) {
2264
- __privateMethod(this, _warnIfDeleted, warnIfDeleted_fn).call(this);
2265
- const channel = this.player.client.channels.resolve(channelResolvable);
2266
- if (!channel || !channel.isVoiceBased()) {
2267
- throw new Error(`Expected a voice based channel (type ${import_discord3.ChannelType.GuildVoice}/${import_discord3.ChannelType.GuildStageVoice}), received ${channel?.type}`);
1911
+ async playStream(resource = this.audioResource) {
1912
+ if (!resource)
1913
+ throw new PlayerError("Audio resource is not available!", "NoAudioResource" /* NO_AUDIO_RESOURCE */);
1914
+ if (resource.ended) {
1915
+ return void this.emit("finish", resource);
2268
1916
  }
2269
- this.debug(`Connecting to ${channel.type === import_discord3.ChannelType.GuildStageVoice ? "stage" : "voice"} channel ${channel.name} (ID: ${channel.id})`);
2270
- if (this.dispatcher) {
2271
- this.debug("Destroying old connection");
2272
- __privateMethod(this, _removeListeners, removeListeners_fn).call(this, this.dispatcher);
2273
- this.dispatcher.disconnect();
1917
+ if (!this.audioResource)
1918
+ this.audioResource = resource;
1919
+ if (this.voiceConnection.state.status !== import_voice3.VoiceConnectionStatus.Ready) {
1920
+ try {
1921
+ await (0, import_voice3.entersState)(this.voiceConnection, import_voice3.VoiceConnectionStatus.Ready, this.connectionTimeout);
1922
+ } catch (err) {
1923
+ return void this.emit("error", err);
1924
+ }
2274
1925
  }
2275
- this.dispatcher = await this.player.voiceUtils.connect(channel, {
2276
- deaf: Boolean(options?.deaf),
2277
- maxTime: options?.timeout ?? this.player.options.connectionTimeout ?? 12e4
2278
- });
2279
- this.player.events.emit("connection", this);
2280
- if (this.channel.type === import_discord3.ChannelType.GuildStageVoice) {
2281
- await this.channel.guild.members.me.voice.setSuppressed(false).catch(async () => {
2282
- return await this.channel.guild.members.me.voice.setRequestToSpeak(true).catch(Util.noop);
2283
- });
1926
+ try {
1927
+ this.audioPlayer.play(resource);
1928
+ } catch (e) {
1929
+ this.emit("error", e);
2284
1930
  }
2285
- __privateMethod(this, _attachListeners, attachListeners_fn).call(this, this.dispatcher);
2286
1931
  return this;
2287
1932
  }
2288
- get ping() {
2289
- return this.connection?.ping.udp ?? -1;
2290
- }
2291
- delete() {
2292
- if (this.player.nodes.delete(this.id)) {
2293
- __privateSet(this, _deleted, true);
2294
- }
1933
+ setVolume(value) {
1934
+ if (!this.dsp.volume)
1935
+ return false;
1936
+ return this.dsp.volume.setVolume(value);
2295
1937
  }
2296
- awaitInitialization() {
2297
- return new Promise((r) => {
2298
- if (!__privateGet(this, _initializing))
2299
- return r(true);
2300
- __privateGet(this, _initializingPromises).push(r);
2301
- });
1938
+ get volume() {
1939
+ if (!this.dsp.volume)
1940
+ return 100;
1941
+ return this.dsp.volume.volume;
2302
1942
  }
2303
- };
2304
- __name(GuildQueue, "GuildQueue");
2305
- _transitioning = new WeakMap();
2306
- _initializing = new WeakMap();
2307
- _deleted = new WeakMap();
2308
- _initializingPromises = new WeakMap();
2309
- _attachListeners = new WeakSet();
2310
- attachListeners_fn = /* @__PURE__ */ __name(function(dispatcher) {
2311
- dispatcher.on("error", (e) => this.player.events.emit("error", this, e));
2312
- dispatcher.on("debug", (m) => this.player.events.emit("debug", this, m));
2313
- dispatcher.on("finish", (r) => __privateMethod(this, _performFinish, performFinish_fn).call(this, r));
2314
- dispatcher.on("start", (r) => __privateMethod(this, _performStart, performStart_fn).call(this, r));
2315
- dispatcher.on("dsp", (f) => {
2316
- this.filters._lastFiltersCache.filters = f;
2317
- });
2318
- dispatcher.on("biquad", (f) => {
2319
- this.filters._lastFiltersCache.biquad = f;
2320
- });
2321
- dispatcher.on("eqBands", (f) => {
2322
- this.filters._lastFiltersCache.equalizer = f;
2323
- });
2324
- dispatcher.on("volume", (f) => {
2325
- this.filters._lastFiltersCache.volume = f;
2326
- });
2327
- }, "#attachListeners");
2328
- _removeListeners = new WeakSet();
2329
- removeListeners_fn = /* @__PURE__ */ __name(function(dispatcher) {
2330
- dispatcher.removeAllListeners();
2331
- }, "#removeListeners");
2332
- _performStart = new WeakSet();
2333
- performStart_fn = /* @__PURE__ */ __name(function(resource) {
2334
- const track = resource?.metadata || this.currentTrack;
2335
- if (track && !this.isTransitioning())
2336
- this.player.events.emit("playerStart", this, track);
2337
- this.setTransitioning(false);
2338
- this.initializing = false;
2339
- }, "#performStart");
2340
- _performFinish = new WeakSet();
2341
- performFinish_fn = /* @__PURE__ */ __name(function(resource) {
2342
- const track = resource?.metadata || this.currentTrack;
2343
- if (track && !this.isTransitioning()) {
2344
- this.history.push(track);
2345
- this.node.resetProgress();
2346
- this.player.events.emit("playerFinish", this, track);
2347
- if (this.tracks.size < 1 && this.repeatMode === 0 /* OFF */) {
2348
- __privateMethod(this, _emitEnd, emitEnd_fn).call(this);
2349
- } else {
2350
- if (this.repeatMode === 3 /* AUTOPLAY */) {
2351
- __privateMethod(this, _handleAutoplay, handleAutoplay_fn).call(this, track);
2352
- return;
2353
- }
2354
- if (this.repeatMode === 1 /* TRACK */) {
2355
- this.__current = this.history.tracks.dispatch() || track;
2356
- return this.node.play(this.__current);
2357
- }
2358
- if (this.repeatMode === 2 /* QUEUE */)
2359
- this.tracks.add(this.history.tracks.dispatch() || track);
2360
- this.__current = this.tracks.dispatch();
2361
- this.node.play(this.__current, {
2362
- queue: false
2363
- });
2364
- }
1943
+ get streamTime() {
1944
+ if (!this.audioResource)
1945
+ return 0;
1946
+ return this.audioResource.playbackDuration;
2365
1947
  }
2366
- }, "#performFinish");
2367
- _emitEnd = new WeakSet();
2368
- emitEnd_fn = /* @__PURE__ */ __name(function() {
2369
- this.__current = null;
2370
- this.player.events.emit("emptyQueue", this);
2371
- if (this.options.leaveOnEnd) {
2372
- const tm = (0, import_timers.setTimeout)(() => {
2373
- if (this.tracks.size)
2374
- return clearTimeout(tm);
2375
- this.dispatcher?.disconnect();
2376
- }, this.options.leaveOnEndCooldown).unref();
1948
+ };
1949
+ __name(StreamDispatcher, "StreamDispatcher");
1950
+
1951
+ // src/VoiceInterface/VoiceUtils.ts
1952
+ var import_utils6 = require("@discord-player/utils");
1953
+ var VoiceUtils = class {
1954
+ constructor() {
1955
+ this.cache = new import_utils6.Collection();
2377
1956
  }
2378
- }, "#emitEnd");
2379
- _handleAutoplay = new WeakSet();
2380
- handleAutoplay_fn = /* @__PURE__ */ __name(async function(track) {
2381
- let info = await import_youtube_sr3.YouTube.getVideo(track.url).then((x) => x.videos[0]).catch(Util.noop);
2382
- if (!info)
2383
- info = await import_youtube_sr3.YouTube.search(track.author).then((x) => x[0]).catch(Util.noop);
2384
- if (!info) {
2385
- return __privateMethod(this, _emitEnd, emitEnd_fn).call(this);
1957
+ async connect(channel, options) {
1958
+ if (!options?.queue)
1959
+ throw new Error("GuildQueue is required");
1960
+ const conn = await this.join(channel, options);
1961
+ const sub = new StreamDispatcher(conn, channel, options.queue, options.maxTime);
1962
+ this.cache.set(channel.guild.id, sub);
1963
+ return sub;
2386
1964
  }
2387
- const nextTrack = new Track(this.player, {
2388
- title: info.title,
2389
- url: `https://www.youtube.com/watch?v=${info.id}`,
2390
- duration: info.durationFormatted || Util.buildTimeCode(Util.parseMS(info.duration * 1e3)),
2391
- description: info.title,
2392
- thumbnail: typeof info.thumbnail === "string" ? info.thumbnail : info.thumbnail.url,
2393
- views: info.views,
2394
- author: info.channel.name,
2395
- requestedBy: track.requestedBy,
2396
- source: "youtube",
2397
- queryType: "youtubeVideo"
2398
- });
2399
- this.node.play(nextTrack, {
2400
- queue: false,
2401
- seek: 0,
2402
- transitionMode: false
2403
- });
2404
- }, "#handleAutoplay");
2405
- _resolveInitializerAwaiters = new WeakSet();
2406
- resolveInitializerAwaiters_fn = /* @__PURE__ */ __name(function() {
2407
- __privateGet(this, _initializingPromises).forEach((p) => {
2408
- p(!__privateGet(this, _initializing));
2409
- });
2410
- __privateSet(this, _initializingPromises, []);
2411
- }, "#resolveInitializerAwaiters");
2412
- _warnIfDeleted = new WeakSet();
2413
- warnIfDeleted_fn = /* @__PURE__ */ __name(function() {
2414
- if (!this.deleted)
2415
- return;
2416
- Util.warn("Deleted queue usage detected! Please remove references to deleted queues in order to prevent memory leaks.", "DiscordPlayerWarning");
2417
- }, "#warnIfDeleted");
1965
+ async join(channel, options) {
1966
+ const conn = (0, import_voice4.joinVoiceChannel)({
1967
+ guildId: channel.guild.id,
1968
+ channelId: channel.id,
1969
+ adapterCreator: channel.guild.voiceAdapterCreator,
1970
+ selfDeaf: Boolean(options?.deaf)
1971
+ });
1972
+ return conn;
1973
+ }
1974
+ disconnect(connection) {
1975
+ if (connection instanceof StreamDispatcher)
1976
+ return connection.voiceConnection.destroy();
1977
+ return connection.destroy();
1978
+ }
1979
+ getConnection(guild) {
1980
+ return this.cache.get(guild) || (0, import_voice4.getVoiceConnection)(guild);
1981
+ }
1982
+ };
1983
+ __name(VoiceUtils, "VoiceUtils");
2418
1984
 
2419
- // src/Structures/GuildQueue/GuildNodeManager.ts
2420
- var GuildNodeManager = class {
2421
- constructor(player) {
1985
+ // src/utils/QueryCache.ts
1986
+ var import_fuse = __toESM(require("fuse.js"));
1987
+ var DEFAULT_EXPIRY_TIMEOUT = 18e6;
1988
+ var _defaultCache;
1989
+ var QueryCache = class {
1990
+ constructor(player, options = {
1991
+ checkInterval: DEFAULT_EXPIRY_TIMEOUT
1992
+ }) {
2422
1993
  this.player = player;
2423
- this.cache = new import_utils7.Collection();
1994
+ this.options = options;
1995
+ __privateAdd(this, _defaultCache, /* @__PURE__ */ new Map());
1996
+ this.fuse = new import_fuse.default([], {
1997
+ keys: [
1998
+ "url"
1999
+ ]
2000
+ });
2001
+ this.timer = setInterval(this.cleanup.bind(this), this.checkInterval).unref();
2424
2002
  }
2425
- create(guild, options = {}) {
2426
- const server = this.player.client.guilds.resolve(guild);
2427
- if (!server) {
2428
- throw new Error("Invalid or unknown guild");
2429
- }
2430
- if (this.cache.has(server.id)) {
2431
- return this.cache.get(server.id);
2003
+ get checkInterval() {
2004
+ return this.options.checkInterval ?? DEFAULT_EXPIRY_TIMEOUT;
2005
+ }
2006
+ async cleanup() {
2007
+ for (const [id, value] of __privateGet(this, _defaultCache)) {
2008
+ if (value.hasExpired()) {
2009
+ __privateGet(this, _defaultCache).delete(id);
2010
+ }
2432
2011
  }
2433
- options.strategy ?? (options.strategy = "FIFO");
2434
- options.volume ?? (options.volume = 100);
2435
- options.equalizer ?? (options.equalizer = []);
2436
- options.a_filter ?? (options.a_filter = []);
2437
- options.disableHistory ?? (options.disableHistory = false);
2438
- options.skipOnNoStream ?? (options.skipOnNoStream = false);
2439
- options.leaveOnEmpty ?? (options.leaveOnEmpty = true);
2440
- options.leaveOnEmptyCooldown ?? (options.leaveOnEmptyCooldown = 0);
2441
- options.leaveOnEnd ?? (options.leaveOnEnd = true);
2442
- options.leaveOnEndCooldown ?? (options.leaveOnEndCooldown = 0);
2443
- options.leaveOnStop ?? (options.leaveOnStop = true);
2444
- options.leaveOnStopCooldown ?? (options.leaveOnStopCooldown = 0);
2445
- options.resampler ?? (options.resampler = 48e3);
2446
- const queue = new GuildQueue(this.player, {
2447
- guild: server,
2448
- queueStrategy: options.strategy,
2449
- volume: options.volume,
2450
- equalizer: options.equalizer,
2451
- filterer: options.a_filter,
2452
- biquad: options.biquad,
2453
- resampler: options.resampler,
2454
- disableHistory: options.disableHistory,
2455
- skipOnNoStream: options.skipOnNoStream,
2456
- onBeforeCreateStream: options.onBeforeCreateStream,
2457
- repeatMode: options.repeatMode,
2458
- leaveOnEmpty: options.leaveOnEmpty,
2459
- leaveOnEmptyCooldown: options.leaveOnEmptyCooldown,
2460
- leaveOnEnd: options.leaveOnEnd,
2461
- leaveOnEndCooldown: options.leaveOnEndCooldown,
2462
- leaveOnStop: options.leaveOnStop,
2463
- leaveOnStopCooldown: options.leaveOnStopCooldown,
2464
- metadata: options.metadata
2465
- });
2466
- this.cache.set(server.id, queue);
2467
- return queue;
2468
2012
  }
2469
- get(node) {
2470
- const queue = this.resolve(node);
2471
- if (!queue)
2472
- return null;
2473
- return this.cache.get(queue.id) || null;
2013
+ async clear() {
2014
+ __privateGet(this, _defaultCache).clear();
2474
2015
  }
2475
- has(node) {
2476
- const id = node instanceof GuildQueue ? node.id : this.player.client.guilds.resolveId(node);
2477
- return this.cache.has(id);
2016
+ async getData() {
2017
+ return [...__privateGet(this, _defaultCache).values()];
2478
2018
  }
2479
- delete(node) {
2480
- const queue = this.resolve(node);
2481
- if (!queue)
2482
- throw new Error("Cannot delete non-existing queue");
2483
- queue.node.stop(true);
2484
- return this.cache.delete(queue.id);
2019
+ async addData(data) {
2020
+ data.tracks.forEach((d) => {
2021
+ if (__privateGet(this, _defaultCache).has(d.url))
2022
+ return;
2023
+ __privateGet(this, _defaultCache).set(d.url, new DiscordPlayerQueryResultCache(d));
2024
+ });
2485
2025
  }
2486
- resolve(node) {
2487
- if (node instanceof GuildQueue) {
2488
- return node;
2489
- }
2490
- return this.cache.get(this.player.client.guilds.resolveId(node));
2026
+ async resolve(context) {
2027
+ const cacheData = await this.getData();
2028
+ this.fuse.setCollection(cacheData.map((m) => m.data));
2029
+ const result = this.fuse.search(context.query);
2030
+ if (!result.length)
2031
+ return new SearchResult(this.player, {
2032
+ query: context.query,
2033
+ requestedBy: context.requestedBy,
2034
+ queryType: context.queryType
2035
+ });
2036
+ return new SearchResult(this.player, {
2037
+ query: context.query,
2038
+ tracks: result.map((m) => m.item),
2039
+ playlist: null,
2040
+ queryType: context.queryType,
2041
+ requestedBy: context.requestedBy
2042
+ });
2491
2043
  }
2492
- resolveId(node) {
2493
- const q = this.resolve(node);
2494
- return q?.id || null;
2044
+ };
2045
+ __name(QueryCache, "QueryCache");
2046
+ _defaultCache = new WeakMap();
2047
+ var DiscordPlayerQueryResultCache = class {
2048
+ constructor(data, expireAfter = DEFAULT_EXPIRY_TIMEOUT) {
2049
+ this.data = data;
2050
+ this.expireAfter = DEFAULT_EXPIRY_TIMEOUT;
2051
+ if (typeof expireAfter === "number") {
2052
+ this.expireAfter = Date.now() + expireAfter;
2053
+ }
2054
+ }
2055
+ hasExpired() {
2056
+ if (typeof this.expireAfter !== "number" || isNaN(this.expireAfter) || this.expireAfter < 1)
2057
+ return false;
2058
+ return Date.now() <= this.expireAfter;
2495
2059
  }
2496
2060
  };
2497
- __name(GuildNodeManager, "GuildNodeManager");
2061
+ __name(DiscordPlayerQueryResultCache, "DiscordPlayerQueryResultCache");
2062
+
2063
+ // src/Player.ts
2064
+ var import_discord3 = require("discord.js");
2065
+ var import_utils7 = require("@discord-player/utils");
2066
+ var import_voice5 = require("@discordjs/voice");
2067
+
2068
+ // src/utils/__internal__/_container.ts
2069
+ var instances = /* @__PURE__ */ new Map();
2070
+
2071
+ // src/utils/__internal__/addPlayer.ts
2072
+ function addPlayer(player) {
2073
+ if (instances.has(player.id))
2074
+ return true;
2075
+ instances.set(player.id, player);
2076
+ return instances.has(player.id);
2077
+ }
2078
+ __name(addPlayer, "addPlayer");
2079
+
2080
+ // src/utils/__internal__/clearPlayer.ts
2081
+ function clearPlayer(player) {
2082
+ return instances.delete(player.id);
2083
+ }
2084
+ __name(clearPlayer, "clearPlayer");
2085
+
2086
+ // src/utils/__internal__/getPlayers.ts
2087
+ function getPlayers() {
2088
+ return [...instances.values()];
2089
+ }
2090
+ __name(getPlayers, "getPlayers");
2498
2091
 
2499
2092
  // src/Player.ts
2500
- var _lastLatency;
2501
- var Player = class extends import_utils8.EventEmitter {
2093
+ var kSingleton = Symbol("InstanceDiscordPlayerSingleton");
2094
+ var _lastLatency, _voiceStateUpdateListener, _lagMonitorTimeout, _lagMonitorInterval;
2095
+ var _Player = class extends import_utils7.EventEmitter {
2502
2096
  constructor(client, options = {}) {
2503
2097
  super();
2504
- this.options = {
2505
- autoRegisterExtractor: true,
2506
- lockVoiceStateHandler: false,
2507
- blockExtractors: [],
2508
- ytdlOptions: {
2509
- highWaterMark: 1 << 25
2510
- },
2511
- connectionTimeout: 2e4,
2512
- smoothVolume: true,
2513
- lagMonitor: 3e4
2514
- };
2515
- this.queues = new import_utils9.Collection();
2098
+ this.id = import_discord3.SnowflakeUtil.generate().toString();
2516
2099
  this.nodes = new GuildNodeManager(this);
2517
2100
  this.voiceUtils = new VoiceUtils();
2518
2101
  this.requiredEvents = ["error", "connectionError"];
2519
2102
  this.extractors = new ExtractorExecutionContext(this);
2520
- this.events = new import_utils8.EventEmitter();
2103
+ this.events = new import_utils7.EventEmitter();
2521
2104
  __privateAdd(this, _lastLatency, -1);
2105
+ __privateAdd(this, _voiceStateUpdateListener, this.handleVoiceState.bind(this));
2106
+ __privateAdd(this, _lagMonitorTimeout, void 0);
2107
+ __privateAdd(this, _lagMonitorInterval, void 0);
2522
2108
  this.client = client;
2523
- if (this.client?.options?.intents && !new import_discord4.IntentsBitField(this.client?.options?.intents).has(import_discord4.IntentsBitField.Flags.GuildVoiceStates)) {
2524
- throw new PlayerError('client is missing "GuildVoiceStates" intent');
2109
+ if (this.client?.options?.intents && !new import_discord3.IntentsBitField(this.client?.options?.intents).has(import_discord3.IntentsBitField.Flags.GuildVoiceStates)) {
2110
+ Util.warn('client is missing "GuildVoiceStates" intent', "InvalidIntentsBitField");
2525
2111
  }
2526
- this.options = Object.assign(this.options, options);
2527
- this.client.on("voiceStateUpdate", this.handleVoiceState.bind(this));
2112
+ this.options = {
2113
+ autoRegisterExtractor: true,
2114
+ lockVoiceStateHandler: false,
2115
+ blockExtractors: [],
2116
+ blockStreamFrom: [],
2117
+ connectionTimeout: 2e4,
2118
+ smoothVolume: true,
2119
+ lagMonitor: 3e4,
2120
+ queryCache: options.queryCache === null ? null : new QueryCache(this),
2121
+ ...options,
2122
+ ytdlOptions: {
2123
+ highWaterMark: 1 << 25,
2124
+ ...options.ytdlOptions
2125
+ }
2126
+ };
2127
+ this.client.on("voiceStateUpdate", __privateGet(this, _voiceStateUpdateListener));
2528
2128
  if (this.options?.autoRegisterExtractor) {
2529
2129
  let nv;
2530
2130
  if (nv = Util.require("@discord-player/extractor")) {
@@ -2532,113 +2132,60 @@ var Player = class extends import_utils8.EventEmitter {
2532
2132
  }
2533
2133
  }
2534
2134
  if (typeof this.options.lagMonitor === "number" && this.options.lagMonitor > 0) {
2535
- setInterval(() => {
2135
+ __privateSet(this, _lagMonitorInterval, setInterval(() => {
2536
2136
  const start = performance.now();
2537
- setTimeout(() => {
2137
+ __privateSet(this, _lagMonitorTimeout, setTimeout(() => {
2538
2138
  __privateSet(this, _lastLatency, performance.now() - start);
2539
- }, 0).unref();
2540
- }, this.options.lagMonitor).unref();
2139
+ }, 0).unref());
2140
+ }, this.options.lagMonitor).unref());
2141
+ }
2142
+ addPlayer(this);
2143
+ }
2144
+ static singleton(client, options = {}) {
2145
+ if (!(kSingleton in _Player)) {
2146
+ Object.defineProperty(_Player, kSingleton, {
2147
+ value: new _Player(client, options),
2148
+ writable: true,
2149
+ configurable: true,
2150
+ enumerable: false
2151
+ });
2541
2152
  }
2153
+ return _Player[kSingleton];
2154
+ }
2155
+ static getAllPlayers() {
2156
+ return getPlayers();
2157
+ }
2158
+ static clearAllPlayers() {
2159
+ return instances.clear();
2160
+ }
2161
+ get queryCache() {
2162
+ return this.options.queryCache ?? null;
2163
+ }
2164
+ get queues() {
2165
+ return this.nodes;
2542
2166
  }
2543
2167
  get eventLoopLag() {
2544
2168
  return __privateGet(this, _lastLatency);
2545
2169
  }
2546
2170
  generateStatistics() {
2547
- return this.queues.map((m) => m.generateStatistics());
2171
+ return {
2172
+ instances: instances.size,
2173
+ queuesCount: this.queues.cache.size,
2174
+ queryCacheEnabled: this.queryCache != null,
2175
+ queues: this.queues.cache.map((m) => m.stats.generate())
2176
+ };
2548
2177
  }
2549
- _handleVoiceStateLegacy(oldState, newState) {
2550
- const queue = this.getQueue(oldState.guild.id);
2551
- if (!queue || !queue.connection)
2552
- return;
2553
- const wasHandled = this.emit("voiceStateUpdate", queue, oldState, newState);
2554
- if (wasHandled && !this.options.lockVoiceStateHandler)
2555
- return;
2556
- if (oldState.channelId && !newState.channelId && newState.member.id === newState.guild.members.me.id) {
2557
- try {
2558
- queue.destroy();
2559
- } catch {
2560
- }
2561
- return void this.emit("botDisconnect", queue);
2562
- }
2563
- if (!oldState.channelId && newState.channelId && newState.member.id === newState.guild.members.me.id) {
2564
- if (newState.serverMute != null && oldState.serverMute !== newState.serverMute) {
2565
- queue.setPaused(newState.serverMute);
2566
- } else if (newState.channel?.type === import_discord4.ChannelType.GuildStageVoice && newState.suppress != null && oldState.suppress !== newState.suppress) {
2567
- queue.setPaused(newState.suppress);
2568
- if (newState.suppress) {
2569
- newState.guild.members.me.voice.setRequestToSpeak(true).catch(Util.noop);
2570
- }
2571
- }
2572
- }
2573
- if (!newState.channelId && oldState.channelId === queue.connection.channel.id) {
2574
- if (!Util.isVoiceEmpty(queue.connection.channel))
2575
- return;
2576
- const timeout = setTimeout(() => {
2577
- if (!Util.isVoiceEmpty(queue.connection.channel))
2578
- return;
2579
- if (!this.queues.has(queue.guild.id))
2580
- return;
2581
- if (queue.options.leaveOnEmpty)
2582
- queue.destroy(true);
2583
- this.emit("channelEmpty", queue);
2584
- }, queue.options.leaveOnEmptyCooldown || 0).unref();
2585
- queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
2586
- }
2587
- if (newState.channelId && newState.channelId === queue.connection.channel.id) {
2588
- const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
2589
- const channelEmpty = Util.isVoiceEmpty(queue.connection.channel);
2590
- if (!channelEmpty && emptyTimeout) {
2591
- clearTimeout(emptyTimeout);
2592
- queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
2593
- }
2594
- }
2595
- if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId) {
2596
- if (newState.member.id === newState.guild.members.me.id) {
2597
- if (queue.connection && newState.member.id === newState.guild.members.me.id)
2598
- queue.connection.channel = newState.channel;
2599
- const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
2600
- const channelEmpty = Util.isVoiceEmpty(queue.connection.channel);
2601
- if (!channelEmpty && emptyTimeout) {
2602
- clearTimeout(emptyTimeout);
2603
- queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
2604
- } else {
2605
- const timeout = setTimeout(() => {
2606
- if (queue.connection && !Util.isVoiceEmpty(queue.connection.channel))
2607
- return;
2608
- if (!this.queues.has(queue.guild.id))
2609
- return;
2610
- if (queue.options.leaveOnEmpty)
2611
- queue.destroy(true);
2612
- this.emit("channelEmpty", queue);
2613
- }, queue.options.leaveOnEmptyCooldown || 0).unref();
2614
- queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
2615
- }
2616
- } else {
2617
- if (newState.channelId !== queue.connection.channel.id) {
2618
- if (!Util.isVoiceEmpty(queue.connection.channel))
2619
- return;
2620
- if (queue._cooldownsTimeout.has(`empty_${oldState.guild.id}`))
2621
- return;
2622
- const timeout = setTimeout(() => {
2623
- if (!Util.isVoiceEmpty(queue.connection.channel))
2624
- return;
2625
- if (!this.queues.has(queue.guild.id))
2626
- return;
2627
- if (queue.options.leaveOnEmpty)
2628
- queue.destroy(true);
2629
- this.emit("channelEmpty", queue);
2630
- }, queue.options.leaveOnEmptyCooldown || 0).unref();
2631
- queue._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout);
2632
- } else {
2633
- const emptyTimeout = queue._cooldownsTimeout.get(`empty_${oldState.guild.id}`);
2634
- const channelEmpty = Util.isVoiceEmpty(queue.connection.channel);
2635
- if (!channelEmpty && emptyTimeout) {
2636
- clearTimeout(emptyTimeout);
2637
- queue._cooldownsTimeout.delete(`empty_${oldState.guild.id}`);
2638
- }
2639
- }
2640
- }
2641
- }
2178
+ async destroy() {
2179
+ this.nodes.cache.forEach((node) => node.delete());
2180
+ this.client.off("voiceStateUpdate", __privateGet(this, _voiceStateUpdateListener));
2181
+ this.removeAllListeners();
2182
+ this.events.removeAllListeners();
2183
+ await this.extractors.unregisterAll();
2184
+ if (__privateGet(this, _lagMonitorInterval))
2185
+ clearInterval(__privateGet(this, _lagMonitorInterval));
2186
+ if (__privateGet(this, _lagMonitorTimeout))
2187
+ clearInterval(__privateGet(this, _lagMonitorTimeout));
2188
+ clearPlayer(this);
2642
2189
  }
2643
2190
  _handleVoiceState(oldState, newState) {
2644
2191
  const queue = this.nodes.get(oldState.guild.id);
@@ -2657,7 +2204,7 @@ var Player = class extends import_utils8.EventEmitter {
2657
2204
  if (!oldState.channelId && newState.channelId && newState.member.id === newState.guild.members.me.id) {
2658
2205
  if (newState.serverMute != null && oldState.serverMute !== newState.serverMute) {
2659
2206
  queue.node.setPaused(newState.serverMute);
2660
- } else if (newState.channel?.type === import_discord4.ChannelType.GuildStageVoice && newState.suppress != null && oldState.suppress !== newState.suppress) {
2207
+ } else if (newState.channel?.type === import_discord3.ChannelType.GuildStageVoice && newState.suppress != null && oldState.suppress !== newState.suppress) {
2661
2208
  queue.node.setPaused(newState.suppress);
2662
2209
  if (newState.suppress) {
2663
2210
  newState.guild.members.me.voice.setRequestToSpeak(true).catch(Util.noop);
@@ -2736,7 +2283,6 @@ var Player = class extends import_utils8.EventEmitter {
2736
2283
  }
2737
2284
  handleVoiceState(oldState, newState) {
2738
2285
  this._handleVoiceState(oldState, newState);
2739
- this._handleVoiceStateLegacy(oldState, newState);
2740
2286
  }
2741
2287
  lockVoiceStateHandler() {
2742
2288
  this.options.lockVoiceStateHandler = true;
@@ -2747,42 +2293,6 @@ var Player = class extends import_utils8.EventEmitter {
2747
2293
  isVoiceStateHandlerLocked() {
2748
2294
  return !!this.options.lockVoiceStateHandler;
2749
2295
  }
2750
- createQueue(guild, queueInitOptions = {}) {
2751
- Util.warn("<Player.createQueue> is deprecated and will be removed in the future. Use new <Player.nodes.create> instead!");
2752
- guild = this.client.guilds.resolve(guild);
2753
- if (!guild)
2754
- throw new PlayerError("Unknown Guild", "UnknownGuild" /* UNKNOWN_GUILD */);
2755
- if (this.queues.has(guild.id))
2756
- return this.queues.get(guild.id);
2757
- const _meta = queueInitOptions.metadata;
2758
- delete queueInitOptions["metadata"];
2759
- queueInitOptions.volumeSmoothness ?? (queueInitOptions.volumeSmoothness = this.options.smoothVolume ? 0.08 : 0);
2760
- queueInitOptions.ytdlOptions ?? (queueInitOptions.ytdlOptions = this.options.ytdlOptions);
2761
- const queue = new Queue(this, guild, queueInitOptions);
2762
- queue.metadata = _meta;
2763
- this.queues.set(guild.id, queue);
2764
- return queue;
2765
- }
2766
- getQueue(guild) {
2767
- Util.warn("<Player.getQueue> is deprecated and will be removed in the future. Use new <Player.nodes.get> instead!");
2768
- guild = this.client.guilds.resolve(guild);
2769
- if (!guild)
2770
- throw new PlayerError("Unknown Guild", "UnknownGuild" /* UNKNOWN_GUILD */);
2771
- return this.queues.get(guild.id);
2772
- }
2773
- deleteQueue(guild) {
2774
- Util.warn("<Player.deleteQueue> is deprecated and will be removed in the future. Use new <Player.nodes.delete> instead!");
2775
- guild = this.client.guilds.resolve(guild);
2776
- if (!guild)
2777
- throw new PlayerError("Unknown Guild", "UnknownGuild" /* UNKNOWN_GUILD */);
2778
- const prev = this.getQueue(guild);
2779
- try {
2780
- prev.destroy();
2781
- } catch {
2782
- }
2783
- this.queues.delete(guild.id);
2784
- return prev;
2785
- }
2786
2296
  async play(channel, query, options = {}) {
2787
2297
  const vc = this.client.channels.resolve(channel);
2788
2298
  if (!vc?.isVoiceBased())
@@ -2829,6 +2339,15 @@ var Player = class extends import_utils8.EventEmitter {
2829
2339
  return new SearchResult(this, { query, queryType });
2830
2340
  }
2831
2341
  if (!extractor) {
2342
+ if (!options.ignoreCache) {
2343
+ const res2 = await this.queryCache?.resolve({
2344
+ query,
2345
+ queryType,
2346
+ requestedBy: options.requestedBy
2347
+ });
2348
+ if (res2?.hasTracks())
2349
+ return res2;
2350
+ }
2832
2351
  extractor = (await this.extractors.run(async (ext) => {
2833
2352
  if (options.blockExtractors?.includes(ext.identifier))
2834
2353
  return false;
@@ -2843,29 +2362,37 @@ var Player = class extends import_utils8.EventEmitter {
2843
2362
  requestedBy: options.requestedBy
2844
2363
  }).catch(() => null);
2845
2364
  if (res) {
2846
- return new SearchResult(this, {
2365
+ const result2 = new SearchResult(this, {
2847
2366
  query,
2848
2367
  queryType,
2849
2368
  playlist: res.playlist,
2850
2369
  tracks: res.tracks,
2851
2370
  extractor
2852
2371
  });
2372
+ if (!options.ignoreCache) {
2373
+ await this.queryCache?.addData(result2);
2374
+ }
2375
+ return result2;
2853
2376
  }
2854
2377
  const result = await this.extractors.run(
2855
- async (ext) => await ext.validate(query) && ext.handle(query, {
2378
+ async (ext) => !options.blockExtractors?.includes(ext.identifier) && await ext.validate(query) && ext.handle(query, {
2856
2379
  type: queryType,
2857
2380
  requestedBy: options.requestedBy
2858
2381
  })
2859
2382
  );
2860
2383
  if (!result?.result)
2861
2384
  return new SearchResult(this, { query, queryType });
2862
- return new SearchResult(this, {
2385
+ const data = new SearchResult(this, {
2863
2386
  query,
2864
2387
  queryType,
2865
2388
  playlist: result.result.playlist,
2866
2389
  tracks: result.result.tracks,
2867
2390
  extractor: result.extractor
2868
2391
  });
2392
+ if (!options.ignoreCache) {
2393
+ await this.queryCache?.addData(data);
2394
+ }
2395
+ return data;
2869
2396
  }
2870
2397
  scanDeps() {
2871
2398
  const line = "-".repeat(50);
@@ -2887,25 +2414,26 @@ ${line}`;
2887
2414
  return super.emit(eventName, ...args);
2888
2415
  }
2889
2416
  }
2890
- resolveQueue(queueLike) {
2891
- Util.warn("<Player.resolveQueue> is deprecated and will be removed in the future. Use new <Player.nodes.resolve> instead!");
2892
- return this.getQueue(queueLike instanceof Queue ? queueLike.guild : queueLike);
2893
- }
2894
2417
  *[Symbol.iterator]() {
2895
- yield* this.nodes.cache.size ? this.nodes.cache.values() : this.queues.values();
2418
+ yield* this.nodes.cache.values();
2896
2419
  }
2897
2420
  createPlaylist(data) {
2898
2421
  return new Playlist(this, data);
2899
2422
  }
2900
2423
  };
2424
+ var Player = _Player;
2901
2425
  __name(Player, "Player");
2902
2426
  _lastLatency = new WeakMap();
2427
+ _voiceStateUpdateListener = new WeakMap();
2428
+ _lagMonitorTimeout = new WeakMap();
2429
+ _lagMonitorInterval = new WeakMap();
2430
+ Player._singletonKey = kSingleton;
2903
2431
 
2904
2432
  // src/index.ts
2905
2433
  var import_equalizer3 = require("@discord-player/equalizer");
2906
- var version = "5.4.0";
2907
- if (!import_discord5.version.startsWith("14")) {
2908
- process.emitWarning(`Discord.js v${import_discord5.version} is incompatible with Discord Player v${version}! Please use >=v14.x of Discord.js`);
2434
+ var version = "6.0.0-dev.3";
2435
+ if (!import_discord4.version.startsWith("14")) {
2436
+ process.emitWarning(`Discord.js v${import_discord4.version} is incompatible with Discord Player v${version}! Please use >=v14.x of Discord.js`);
2909
2437
  }
2910
2438
  // Annotate the CommonJS export names for ESM import in node:
2911
2439
  0 && (module.exports = {
@@ -2917,11 +2445,13 @@ if (!import_discord5.version.startsWith("14")) {
2917
2445
  BaseExtractor,
2918
2446
  BiquadFilterType,
2919
2447
  BiquadFilters,
2448
+ DiscordPlayerQueryResultCache,
2920
2449
  EqualizerConfigurationPreset,
2921
2450
  ErrorStatusCode,
2922
2451
  ExtractorExecutionContext,
2923
2452
  FFMPEG_ARGS_PIPED,
2924
2453
  FFMPEG_ARGS_STRING,
2454
+ FFMPEG_SRATE_REGEX,
2925
2455
  FFmpegFilterer,
2926
2456
  FiltersChain,
2927
2457
  GuildNodeManager,
@@ -2935,10 +2465,10 @@ if (!import_discord5.version.startsWith("14")) {
2935
2465
  PlayerError,
2936
2466
  Playlist,
2937
2467
  Q_BUTTERWORTH,
2938
- QueryResolver,
2468
+ QueryCache,
2939
2469
  QueryType,
2940
- Queue,
2941
2470
  QueueRepeatMode,
2471
+ SearchResult,
2942
2472
  StreamDispatcher,
2943
2473
  Track,
2944
2474
  Util,