distube 5.0.1 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -159,8 +159,7 @@ interface SongInfo {
159
159
  plugin: DisTubePlugin | null;
160
160
  source: string;
161
161
  playFromSource: boolean;
162
- streamURL?: string;
163
- id?: string;
162
+ id: string;
164
163
  name?: string;
165
164
  isLive?: boolean;
166
165
  duration?: number;
@@ -469,7 +468,7 @@ declare class Song<T = unknown> {
469
468
  /**
470
469
  * Song ID.
471
470
  */
472
- id?: string;
471
+ id: string;
473
472
  /**
474
473
  * Song name.
475
474
  */
@@ -813,7 +812,7 @@ declare abstract class GuildIdManager<V> extends BaseManager<V> {
813
812
  declare class DisTubeVoiceManager extends GuildIdManager<DisTubeVoice> {
814
813
  /**
815
814
  * Create a {@link DisTubeVoice} instance
816
- * @param channel - A voice channel to join
815
+ * @param channel - A voice chann el to join
817
816
  */
818
817
  create(channel: VoiceBasedChannel): DisTubeVoice;
819
818
  /**
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ var require_package = __commonJS({
36
36
  "package.json"(exports2, module2) {
37
37
  module2.exports = {
38
38
  name: "distube",
39
- version: "5.0.1",
39
+ version: "5.0.2",
40
40
  description: "A powerful Discord.js module for simplifying music commands and effortless playback of various sources with integrated audio filters.",
41
41
  main: "./dist/index.js",
42
42
  types: "./dist/index.d.ts",
@@ -49,18 +49,17 @@ var require_package = __commonJS({
49
49
  "dist"
50
50
  ],
51
51
  scripts: {
52
- test: "jest",
52
+ test: "VITE_CJS_IGNORE_WARNING=true vitest run",
53
53
  docs: "typedoc",
54
54
  lint: "prettier --check . && eslint .",
55
55
  "lint:fix": "eslint . --fix",
56
56
  prettier: 'prettier --write "**/*.{ts,json,yml,yaml,md}"',
57
57
  build: "tsup",
58
- "build:check": "tsc --noEmit",
58
+ type: "tsc --noEmit",
59
59
  update: 'pnpm up -L "!eslint"',
60
60
  prepare: "husky",
61
61
  prepublishOnly: "pnpm run lint && pnpm run test",
62
- prepack: "pnpm run build",
63
- "dev:add-docs-to-worktree": "git worktree add --track -b docs docs origin/docs"
62
+ prepack: "pnpm run build"
64
63
  },
65
64
  repository: {
66
65
  type: "git",
@@ -91,34 +90,29 @@ var require_package = __commonJS({
91
90
  undici: "^6.18.2"
92
91
  },
93
92
  devDependencies: {
94
- "@babel/core": "^7.24.6",
95
- "@babel/plugin-transform-class-properties": "^7.24.6",
96
- "@babel/plugin-transform-object-rest-spread": "^7.24.6",
97
- "@babel/plugin-transform-private-methods": "^7.24.6",
98
- "@babel/preset-env": "^7.24.6",
99
- "@babel/preset-typescript": "^7.24.6",
100
93
  "@commitlint/cli": "^19.3.0",
101
94
  "@commitlint/config-conventional": "^19.2.2",
102
95
  "@discordjs/voice": "^0.17.0",
103
- "@types/jest": "^29.5.12",
104
- "@types/node": "^20.14.1",
96
+ "@types/node": "^20.14.2",
105
97
  "@types/tough-cookie": "^4.0.5",
106
- "@typescript-eslint/eslint-plugin": "^7.12.0",
107
- "@typescript-eslint/parser": "^7.12.0",
108
- "babel-jest": "^29.7.0",
98
+ "@typescript-eslint/eslint-plugin": "^7.13.0",
99
+ "@typescript-eslint/parser": "^7.13.0",
100
+ "@vitest/coverage-v8": "^1.6.0",
109
101
  "discord.js": "^14.15.3",
110
102
  eslint: "^8.57.0",
111
103
  "eslint-config-distube": "^1.7.0",
112
104
  husky: "^9.0.11",
113
- jest: "^29.7.0",
114
105
  "nano-staged": "^0.8.0",
115
- prettier: "^3.3.0",
106
+ prettier: "^3.3.2",
116
107
  "sodium-native": "^4.1.1",
117
108
  "ts-node": "^10.9.2",
118
109
  tsup: "^8.1.0",
119
110
  typedoc: "^0.25.13",
120
111
  "typedoc-material-theme": "^1.0.2",
121
- typescript: "^5.4.5"
112
+ "typedoc-plugin-extras": "^3.0.0",
113
+ typescript: "^5.4.5",
114
+ "vite-tsconfig-paths": "^4.3.2",
115
+ vitest: "^1.6.0"
122
116
  },
123
117
  peerDependencies: {
124
118
  "@discordjs/voice": "*",
@@ -1313,7 +1307,7 @@ var import_voice3 = require("@discordjs/voice");
1313
1307
  var _DisTubeVoiceManager = class _DisTubeVoiceManager extends GuildIdManager {
1314
1308
  /**
1315
1309
  * Create a {@link DisTubeVoice} instance
1316
- * @param channel - A voice channel to join
1310
+ * @param channel - A voice chann el to join
1317
1311
  */
1318
1312
  create(channel) {
1319
1313
  const existing = this.get(channel.guildId);
@@ -1558,7 +1552,9 @@ voiceEventHandler_fn = /* @__PURE__ */ __name(function(queue) {
1558
1552
  * @param queue - Queue
1559
1553
  */
1560
1554
  emitPlaySong_fn = /* @__PURE__ */ __name(function(queue) {
1561
- return !this.options.emitNewSongOnly || queue.repeatMode === 1 /* SONG */ && queue._next || queue.repeatMode !== 1 /* SONG */ && queue.songs[0]?.id !== queue.songs[1]?.id;
1555
+ if (!this.options.emitNewSongOnly) return true;
1556
+ if (queue.repeatMode === 1 /* SONG */) return queue._next || queue._prev;
1557
+ return queue.songs[0].id !== queue.songs[1].id;
1562
1558
  }, "#emitPlaySong");
1563
1559
  handleSongFinish_fn = /* @__PURE__ */ __name(async function(queue) {
1564
1560
  this.debug(`[QueueManager] Handling song finish: ${queue.id}`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/index.ts","../src/type.ts","../src/constant.ts","../src/struct/DisTubeError.ts","../src/struct/TaskQueue.ts","../src/struct/Playlist.ts","../src/struct/Song.ts","../src/core/DisTubeBase.ts","../src/core/DisTubeVoice.ts","../src/core/DisTubeStream.ts","../src/core/DisTubeHandler.ts","../src/core/DisTubeOptions.ts","../src/core/manager/BaseManager.ts","../src/core/manager/GuildIdManager.ts","../src/core/manager/DisTubeVoiceManager.ts","../src/core/manager/FilterManager.ts","../src/core/manager/QueueManager.ts","../src/struct/Queue.ts","../src/struct/Plugin.ts","../src/struct/ExtractorPlugin.ts","../src/struct/InfoExtratorPlugin.ts","../src/struct/PlayableExtratorPlugin.ts","../src/util.ts","../src/DisTube.ts"],"sourcesContent":["{\n \"name\": \"distube\",\n \"version\": \"5.0.1\",\n \"description\": \"A powerful Discord.js module for simplifying music commands and effortless playback of various sources with integrated audio filters.\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": \"./dist/index.js\",\n \"directories\": {\n \"lib\": \"src\",\n \"test\": \"tests\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"test\": \"jest\",\n \"docs\": \"typedoc\",\n \"lint\": \"prettier --check . && eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n \"prettier\": \"prettier --write \\\"**/*.{ts,json,yml,yaml,md}\\\"\",\n \"build\": \"tsup\",\n \"build:check\": \"tsc --noEmit\",\n \"update\": \"pnpm up -L \\\"!eslint\\\"\",\n \"prepare\": \"husky\",\n \"prepublishOnly\": \"pnpm run lint && pnpm run test\",\n \"prepack\": \"pnpm run build\",\n \"dev:add-docs-to-worktree\": \"git worktree add --track -b docs docs origin/docs\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/skick1234/DisTube.git\"\n },\n \"keywords\": [\n \"youtube\",\n \"music\",\n \"discord\",\n \"discordjs\",\n \"bot\",\n \"distube\",\n \"queue\",\n \"musicbot\",\n \"discord-music-bot\",\n \"music-bot\",\n \"discord-js\"\n ],\n \"author\": \"Skick (https://github.com/skick1234)\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/skick1234/DisTube/issues\"\n },\n \"funding\": \"https://github.com/skick1234/DisTube?sponsor\",\n \"homepage\": \"https://distube.js.org/\",\n \"dependencies\": {\n \"tiny-typed-emitter\": \"^2.1.0\",\n \"undici\": \"^6.18.2\"\n },\n \"devDependencies\": {\n \"@babel/core\": \"^7.24.6\",\n \"@babel/plugin-transform-class-properties\": \"^7.24.6\",\n \"@babel/plugin-transform-object-rest-spread\": \"^7.24.6\",\n \"@babel/plugin-transform-private-methods\": \"^7.24.6\",\n \"@babel/preset-env\": \"^7.24.6\",\n \"@babel/preset-typescript\": \"^7.24.6\",\n \"@commitlint/cli\": \"^19.3.0\",\n \"@commitlint/config-conventional\": \"^19.2.2\",\n \"@discordjs/voice\": \"^0.17.0\",\n \"@types/jest\": \"^29.5.12\",\n \"@types/node\": \"^20.14.1\",\n \"@types/tough-cookie\": \"^4.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^7.12.0\",\n \"@typescript-eslint/parser\": \"^7.12.0\",\n \"babel-jest\": \"^29.7.0\",\n \"discord.js\": \"^14.15.3\",\n \"eslint\": \"^8.57.0\",\n \"eslint-config-distube\": \"^1.7.0\",\n \"husky\": \"^9.0.11\",\n \"jest\": \"^29.7.0\",\n \"nano-staged\": \"^0.8.0\",\n \"prettier\": \"^3.3.0\",\n \"sodium-native\": \"^4.1.1\",\n \"ts-node\": \"^10.9.2\",\n \"tsup\": \"^8.1.0\",\n \"typedoc\": \"^0.25.13\",\n \"typedoc-material-theme\": \"^1.0.2\",\n \"typescript\": \"^5.4.5\"\n },\n \"peerDependencies\": {\n \"@discordjs/voice\": \"*\",\n \"discord.js\": \"14\"\n },\n \"nano-staged\": {\n \"*.ts\": [\n \"prettier --write\",\n \"eslint\"\n ],\n \"*.{json,yml,yaml,md}\": [\n \"prettier --write\"\n ]\n },\n \"engines\": {\n \"node\": \">=18.17\"\n }\n}\n","export * from \"./type\";\nexport * from \"./constant\";\nexport * from \"./struct\";\nexport * from \"./util\";\nexport * from \"./core\";\nexport { DisTube, DisTube as default, version } from \"./DisTube\";\n","import type {\n DisTubeError,\n DisTubeVoice,\n ExtractorPlugin,\n InfoExtractorPlugin,\n PlayableExtractorPlugin,\n Playlist,\n Queue,\n Song,\n} from \".\";\nimport type {\n Guild,\n GuildMember,\n GuildTextBasedChannel,\n Interaction,\n Message,\n Snowflake,\n VoiceBasedChannel,\n VoiceState,\n} from \"discord.js\";\n\nexport type Awaitable<T = any> = T | PromiseLike<T>;\n\nexport enum Events {\n ERROR = \"error\",\n ADD_LIST = \"addList\",\n ADD_SONG = \"addSong\",\n PLAY_SONG = \"playSong\",\n FINISH_SONG = \"finishSong\",\n EMPTY = \"empty\",\n FINISH = \"finish\",\n INIT_QUEUE = \"initQueue\",\n NO_RELATED = \"noRelated\",\n DISCONNECT = \"disconnect\",\n DELETE_QUEUE = \"deleteQueue\",\n FFMPEG_DEBUG = \"ffmpegDebug\",\n DEBUG = \"debug\",\n}\n\nexport type DisTubeEvents = {\n [Events.ADD_LIST]: [queue: Queue, playlist: Playlist];\n [Events.ADD_SONG]: [queue: Queue, song: Song];\n [Events.DELETE_QUEUE]: [queue: Queue];\n [Events.DISCONNECT]: [queue: Queue];\n [Events.ERROR]: [error: Error, queue: Queue, song: Song | undefined];\n [Events.FFMPEG_DEBUG]: [debug: string];\n [Events.DEBUG]: [debug: string];\n [Events.FINISH]: [queue: Queue];\n [Events.FINISH_SONG]: [queue: Queue, song: Song];\n [Events.INIT_QUEUE]: [queue: Queue];\n [Events.NO_RELATED]: [queue: Queue, error: DisTubeError];\n [Events.PLAY_SONG]: [queue: Queue, song: Song];\n};\n\nexport type TypedDisTubeEvents = {\n [K in keyof DisTubeEvents]: (...args: DisTubeEvents[K]) => Awaitable;\n};\n\nexport type DisTubeVoiceEvents = {\n disconnect: (error?: Error) => Awaitable;\n error: (error: Error) => Awaitable;\n finish: () => Awaitable;\n};\n\n/**\n * An FFmpeg audio filter object\n * ```ts\n * {\n * name: \"bassboost\",\n * value: \"bass=g=10\"\n * }\n * ```ts\n */\nexport interface Filter {\n /**\n * Name of the filter\n */\n name: string;\n /**\n * FFmpeg audio filter argument\n */\n value: string;\n}\n\n/**\n * Data that resolves to give an FFmpeg audio filter. This can be:\n * - A name of a default filters or custom filters (`string`)\n * - A {@link Filter} object\n * @see {@link defaultFilters}\n * @see {@link DisTubeOptions|DisTubeOptions.customFilters}\n */\nexport type FilterResolvable = string | Filter;\n\n/**\n * FFmpeg Filters\n * ```ts\n * {\n * \"Filter Name\": \"Filter Value\",\n * \"bassboost\": \"bass=g=10\"\n * }\n * ```\n * @see {@link defaultFilters}\n */\nexport type Filters = Record<string, string>;\n\n/**\n * DisTube options\n */\nexport type DisTubeOptions = {\n /**\n * DisTube plugins.\n * The order of this effects the priority of the plugins when verifying the input.\n */\n plugins?: DisTubePlugin[];\n /**\n * Whether or not emitting {@link Events.PLAY_SONG} event when looping a song\n * or next song is the same as the previous one\n */\n emitNewSongOnly?: boolean;\n /**\n * Whether or not saving the previous songs of the queue and enable {@link\n * DisTube#previous} method. Disable it may help to reduce the memory usage\n */\n savePreviousSongs?: boolean;\n /**\n * Override {@link defaultFilters} or add more ffmpeg filters\n */\n customFilters?: Filters;\n /**\n * Whether or not playing age-restricted content and disabling safe search in\n * non-NSFW channel\n */\n nsfw?: boolean;\n /**\n * Whether or not emitting `addSong` event when creating a new Queue\n */\n emitAddSongWhenCreatingQueue?: boolean;\n /**\n * Whether or not emitting `addList` event when creating a new Queue\n */\n emitAddListWhenCreatingQueue?: boolean;\n /**\n * Whether or not joining the new voice channel when using {@link DisTube#play}\n * method\n */\n joinNewVoiceChannel?: boolean;\n /**\n * FFmpeg options\n */\n ffmpeg?: {\n /**\n * FFmpeg path\n */\n path?: string;\n /**\n * FFmpeg default arguments\n */\n args?: Partial<FFmpegArgs>;\n };\n};\n\n/**\n * Data that can be resolved to give a guild id string. This can be:\n * - A guild id string | a guild {@link https://discord.js.org/#/docs/main/stable/class/Snowflake|Snowflake}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/Guild | Guild}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/Message | Message}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/BaseGuildVoiceChannel\n * | BaseGuildVoiceChannel}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/BaseGuildTextChannel\n * | BaseGuildTextChannel}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/VoiceState |\n * VoiceState}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/GuildMember |\n * GuildMember}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/Interaction |\n * Interaction}\n * - A {@link DisTubeVoice}\n * - A {@link Queue}\n */\nexport type GuildIdResolvable =\n | Queue\n | DisTubeVoice\n | Snowflake\n | Message\n | GuildTextBasedChannel\n | VoiceBasedChannel\n | VoiceState\n | Guild\n | GuildMember\n | Interaction\n | string;\n\nexport interface SongInfo {\n plugin: DisTubePlugin | null;\n source: string;\n playFromSource: boolean;\n streamURL?: string;\n id?: string;\n name?: string;\n isLive?: boolean;\n duration?: number;\n url?: string;\n thumbnail?: string;\n views?: number;\n likes?: number;\n dislikes?: number;\n reposts?: number;\n uploader?: {\n name?: string;\n url?: string;\n };\n ageRestricted?: boolean;\n}\n\nexport interface PlaylistInfo {\n source: string;\n songs: Song[];\n id?: string;\n name?: string;\n url?: string;\n thumbnail?: string;\n}\n\nexport type RelatedSong = Omit<Song, \"related\">;\n\nexport type PlayHandlerOptions = {\n /**\n * [Default: false] Skip the playing song (if exists) and play the added playlist\n * instantly\n */\n skip?: boolean;\n /**\n * [Default: 0] Position of the song/playlist to add to the queue, \\<= 0 to add to\n * the end of the queue\n */\n position?: number;\n /**\n * The default text channel of the queue\n */\n textChannel?: GuildTextBasedChannel;\n};\n\nexport interface PlayOptions<T = unknown> extends PlayHandlerOptions, ResolveOptions<T> {\n /**\n * Called message (For built-in search events. If this is a {@link\n * https://developer.mozilla.org/en-US/docs/Glossary/Falsy | falsy value}, it will\n * play the first result instead)\n */\n message?: Message;\n}\n\nexport interface ResolveOptions<T = unknown> {\n /**\n * Requested user\n */\n member?: GuildMember;\n /**\n * Metadata\n */\n metadata?: T;\n}\n\nexport interface ResolvePlaylistOptions<T = unknown> extends ResolveOptions<T> {\n /**\n * Source of the playlist\n */\n source?: string;\n}\n\nexport interface CustomPlaylistOptions {\n /**\n * A guild member creating the playlist\n */\n member?: GuildMember;\n /**\n * Whether or not fetch the songs in parallel\n */\n parallel?: boolean;\n /**\n * Metadata\n */\n metadata?: any;\n /**\n * Playlist name\n */\n name?: string;\n /**\n * Playlist source\n */\n source?: string;\n /**\n * Playlist url\n */\n url?: string;\n /**\n * Playlist thumbnail\n */\n thumbnail?: string;\n}\n\n/**\n * The repeat mode of a {@link Queue}\n * - `DISABLED` = 0\n * - `SONG` = 1\n * - `QUEUE` = 2\n */\nexport enum RepeatMode {\n DISABLED,\n SONG,\n QUEUE,\n}\n\n/**\n * All available plugin types:\n * - `EXTRACTOR` = `\"extractor\"`: {@link ExtractorPlugin}\n * - `INFO_EXTRACTOR` = `\"info-extractor\"`: {@link InfoExtractorPlugin}\n * - `PLAYABLE_EXTRACTOR` = `\"playable-extractor\"`: {@link PlayableExtractorPlugin}\n */\nexport enum PluginType {\n EXTRACTOR = \"extractor\",\n INFO_EXTRACTOR = \"info-extractor\",\n PLAYABLE_EXTRACTOR = \"playable-extractor\",\n}\n\nexport type DisTubePlugin = ExtractorPlugin | InfoExtractorPlugin | PlayableExtractorPlugin;\n\nexport type FFmpegArg = Record<string, string | number | boolean | Array<string | null | undefined> | null | undefined>;\n\n/**\n * FFmpeg arguments for different use cases\n */\nexport type FFmpegArgs = {\n global: FFmpegArg;\n input: FFmpegArg;\n output: FFmpegArg;\n};\n\n/**\n * FFmpeg options\n */\nexport type FFmpegOptions = {\n /**\n * Path to the ffmpeg executable\n */\n path: string;\n /**\n * Arguments\n */\n args: FFmpegArgs;\n};\n","import type { DisTubeOptions, Filters } from \".\";\n\n/**\n * Default DisTube audio filters.\n */\nexport const defaultFilters: Filters = {\n \"3d\": \"apulsator=hz=0.125\",\n bassboost: \"bass=g=10\",\n echo: \"aecho=0.8:0.9:1000:0.3\",\n flanger: \"flanger\",\n gate: \"agate\",\n haas: \"haas\",\n karaoke: \"stereotools=mlev=0.1\",\n nightcore: \"asetrate=48000*1.25,aresample=48000,bass=g=5\",\n reverse: \"areverse\",\n vaporwave: \"asetrate=48000*0.8,aresample=48000,atempo=1.1\",\n mcompand: \"mcompand\",\n phaser: \"aphaser\",\n tremolo: \"tremolo\",\n surround: \"surround\",\n earwax: \"earwax\",\n};\n\nexport const defaultOptions = {\n plugins: [],\n emitNewSongOnly: false,\n savePreviousSongs: true,\n nsfw: false,\n emitAddSongWhenCreatingQueue: true,\n emitAddListWhenCreatingQueue: true,\n joinNewVoiceChannel: true,\n} satisfies DisTubeOptions;\n","import { inspect } from \"node:util\";\n\nconst ERROR_MESSAGES = {\n INVALID_TYPE: (expected: (number | string) | readonly (number | string)[], got: any, name?: string) =>\n `Expected ${\n Array.isArray(expected) ? expected.map(e => (typeof e === \"number\" ? e : `'${e}'`)).join(\" or \") : `'${expected}'`\n }${name ? ` for '${name}'` : \"\"}, but got ${inspect(got)} (${typeof got})`,\n NUMBER_COMPARE: (name: string, expected: string, value: number) => `'${name}' must be ${expected} ${value}`,\n EMPTY_ARRAY: (name: string) => `'${name}' is an empty array`,\n EMPTY_FILTERED_ARRAY: (name: string, type: string) => `There is no valid '${type}' in the '${name}' array`,\n EMPTY_STRING: (name: string) => `'${name}' string must not be empty`,\n INVALID_KEY: (obj: string, key: string) => `'${key}' does not need to be provided in ${obj}`,\n MISSING_KEY: (obj: string, key: string) => `'${key}' needs to be provided in ${obj}`,\n MISSING_KEYS: (obj: string, key: string[], all: boolean) =>\n `${key.map(k => `'${k}'`).join(all ? \" and \" : \" or \")} need to be provided in ${obj}`,\n\n MISSING_INTENTS: (i: string) => `${i} intent must be provided for the Client`,\n DISABLED_OPTION: (o: string) => `DisTubeOptions.${o} is disabled`,\n ENABLED_OPTION: (o: string) => `DisTubeOptions.${o} is enabled`,\n\n NOT_IN_VOICE: \"User is not in any voice channel\",\n VOICE_FULL: \"The voice channel is full\",\n VOICE_ALREADY_CREATED: \"This guild already has a voice connection which is not managed by DisTube\",\n VOICE_CONNECT_FAILED: (s: number) => `Cannot connect to the voice channel after ${s} seconds`,\n VOICE_MISSING_PERMS: \"I do not have permission to join this voice channel\",\n VOICE_RECONNECT_FAILED: \"Cannot reconnect to the voice channel\",\n VOICE_DIFFERENT_GUILD: \"Cannot join a voice channel in a different guild\",\n VOICE_DIFFERENT_CLIENT: \"Cannot join a voice channel created by a different client\",\n\n FFMPEG_EXITED: (code: number) => `ffmpeg exited with code ${code}`,\n FFMPEG_NOT_INSTALLED: (path: string) => `ffmpeg is not installed at '${path}' path`,\n\n NO_QUEUE: \"There is no playing queue in this guild\",\n QUEUE_EXIST: \"This guild has a Queue already\",\n QUEUE_STOPPED: \"The queue has been stopped already\",\n PAUSED: \"The queue has been paused already\",\n RESUMED: \"The queue has been playing already\",\n NO_PREVIOUS: \"There is no previous song in this queue\",\n NO_UP_NEXT: \"There is no up next song\",\n NO_SONG_POSITION: \"Does not have any song at this position\",\n NO_PLAYING_SONG: \"There is no playing song in the queue\",\n\n NO_RELATED: \"Cannot find any related songs\",\n CANNOT_PLAY_RELATED: \"Cannot play the related song\",\n UNAVAILABLE_VIDEO: \"This video is unavailable\",\n UNPLAYABLE_FORMATS: \"No playable format found\",\n NON_NSFW: \"Cannot play age-restricted content in non-NSFW channel\",\n NOT_SUPPORTED_URL: \"This url is not supported\",\n NOT_SUPPORTED_SONG: (song: string) => `There is no plugin supporting this song (${song})`,\n NO_VALID_SONG: \"'songs' array does not have any valid Song or url\",\n CANNOT_RESOLVE_SONG: (t: any) => `Cannot resolve ${inspect(t)} to a Song`,\n CANNOT_GET_STREAM_URL: (song: string) => `Cannot get stream url from this song (${song})`,\n CANNOT_GET_SEARCH_QUERY: (song: string) => `Cannot get search query from this song (${song})`,\n NO_RESULT: (query: string) => `Cannot get song stream from this query (${query})`,\n NO_STREAM_URL: (song: string) => `No stream url attached (${song})`,\n\n EMPTY_FILTERED_PLAYLIST:\n \"There is no valid video in the playlist\\n\" +\n \"Maybe age-restricted contents is filtered because you are in non-NSFW channel\",\n EMPTY_PLAYLIST: \"There is no valid video in the playlist\",\n};\n\ntype ErrorMessage = typeof ERROR_MESSAGES;\ntype ErrorCode = keyof ErrorMessage;\ntype StaticErrorCode = { [K in ErrorCode]-?: ErrorMessage[K] extends string ? K : never }[ErrorCode];\ntype TemplateErrorCode = Exclude<keyof typeof ERROR_MESSAGES, StaticErrorCode>;\n\nconst haveCode = (code: string): code is ErrorCode => Object.keys(ERROR_MESSAGES).includes(code);\nconst parseMessage = (m: string | ((...x: any) => string), ...args: any) => (typeof m === \"string\" ? m : m(...args));\nconst getErrorMessage = (code: string, ...args: any): string =>\n haveCode(code) ? parseMessage(ERROR_MESSAGES[code], ...args) : args[0];\nexport class DisTubeError<T extends string = any> extends Error {\n errorCode: string;\n constructor(code: T extends StaticErrorCode ? T : never);\n constructor(code: T extends TemplateErrorCode ? T : never, ...args: Parameters<ErrorMessage[typeof code]>);\n constructor(code: TemplateErrorCode, _: never);\n constructor(code: T extends ErrorCode ? never : T, message: string);\n constructor(code: string, ...args: any) {\n super(getErrorMessage(code, ...args));\n\n this.errorCode = code;\n if (Error.captureStackTrace) Error.captureStackTrace(this, DisTubeError);\n }\n\n override get name() {\n return `DisTubeError [${this.errorCode}]`;\n }\n\n get code() {\n return this.errorCode;\n }\n}\n","class Task {\n resolve!: () => void;\n promise: Promise<void>;\n constructor() {\n this.promise = new Promise<void>(res => {\n this.resolve = res;\n });\n }\n}\n\n/**\n * Task queuing system\n */\nexport class TaskQueue {\n /**\n * The task array\n */\n #tasks: Task[] = [];\n\n /**\n * Waits for last task finished and queues a new task\n */\n queuing(): Promise<void> {\n const next = this.remaining ? this.#tasks[this.#tasks.length - 1].promise : Promise.resolve();\n this.#tasks.push(new Task());\n return next;\n }\n\n /**\n * Removes the finished task and processes the next task\n */\n resolve(): void {\n this.#tasks.shift()?.resolve();\n }\n\n /**\n * The remaining number of tasks\n */\n get remaining(): number {\n return this.#tasks.length;\n }\n}\n","import { DisTubeError, formatDuration, isMemberInstance } from \"..\";\nimport type { GuildMember } from \"discord.js\";\nimport type { PlaylistInfo, ResolveOptions, Song } from \"..\";\n\n/**\n * Class representing a playlist.\n */\nexport class Playlist<T = unknown> implements PlaylistInfo {\n /**\n * Playlist source.\n */\n source: string;\n /**\n * Songs in the playlist.\n */\n songs: Song[];\n /**\n * Playlist ID.\n */\n id?: string;\n /**\n * Playlist name.\n */\n name?: string;\n /**\n * Playlist URL.\n */\n url?: string;\n /**\n * Playlist thumbnail.\n */\n thumbnail?: string;\n #metadata!: T;\n #member?: GuildMember;\n /**\n * Create a Playlist\n * @param playlist - Raw playlist info\n * @param options - Optional data\n */\n constructor(playlist: PlaylistInfo, { member, metadata }: ResolveOptions<T> = {}) {\n if (!Array.isArray(playlist.songs) || !playlist.songs.length) throw new DisTubeError(\"EMPTY_PLAYLIST\");\n\n this.source = playlist.source.toLowerCase();\n this.songs = playlist.songs;\n this.name = playlist.name;\n this.id = playlist.id;\n this.url = playlist.url;\n this.thumbnail = playlist.thumbnail;\n this.member = member;\n this.songs.forEach(s => (s.playlist = this));\n this.metadata = metadata as T;\n }\n\n /**\n * Playlist duration in second.\n */\n get duration() {\n return this.songs.reduce((prev, next) => prev + next.duration, 0);\n }\n\n /**\n * Formatted duration string `hh:mm:ss`.\n */\n get formattedDuration() {\n return formatDuration(this.duration);\n }\n\n /**\n * User requested.\n */\n get member() {\n return this.#member;\n }\n\n set member(member: GuildMember | undefined) {\n if (!isMemberInstance(member)) return;\n this.#member = member;\n this.songs.forEach(s => (s.member = this.member));\n }\n\n /**\n * User requested.\n */\n get user() {\n return this.member?.user;\n }\n\n /**\n * Optional metadata that can be used to identify the playlist.\n */\n get metadata() {\n return this.#metadata;\n }\n\n set metadata(metadata: T) {\n this.#metadata = metadata;\n this.songs.forEach(s => (s.metadata = metadata));\n }\n\n toString() {\n return `${this.name} (${this.songs.length} songs)`;\n }\n}\n","import { Playlist } from \".\";\nimport { DisTubeError, formatDuration, isMemberInstance } from \"..\";\nimport type { GuildMember } from \"discord.js\";\nimport type { DisTubePlugin, ResolveOptions, SongInfo } from \"..\";\n\n/**\n * Class representing a song.\n */\nexport class Song<T = unknown> {\n /**\n * The source of this song info\n */\n source: string;\n /**\n * Song ID.\n */\n id?: string;\n /**\n * Song name.\n */\n name?: string;\n /**\n * Indicates if the song is an active live.\n */\n isLive?: boolean;\n /**\n * Song duration.\n */\n duration: number;\n /**\n * Formatted duration string (`hh:mm:ss`, `mm:ss` or `Live`).\n */\n formattedDuration: string;\n /**\n * Song URL.\n */\n url?: string;\n /**\n * Song thumbnail.\n */\n thumbnail?: string;\n /**\n * Song view count\n */\n views?: number;\n /**\n * Song like count\n */\n likes?: number;\n /**\n * Song dislike count\n */\n dislikes?: number;\n /**\n * Song repost (share) count\n */\n reposts?: number;\n /**\n * Song uploader\n */\n uploader: {\n name?: string;\n url?: string;\n };\n /**\n * Whether or not an age-restricted content\n */\n ageRestricted?: boolean;\n /**\n * Stream info\n */\n stream:\n | {\n /**\n * The stream of this song will be played from source\n */\n playFromSource: true;\n /**\n * Stream URL of this song\n */\n url?: string;\n }\n | {\n /**\n * The stream of this song will be played from another song\n */\n playFromSource: false;\n /**\n * The song that this song will be played from\n */\n song?: Song<T>;\n };\n /**\n * The plugin that created this song\n */\n plugin: DisTubePlugin | null;\n #metadata!: T;\n #member?: GuildMember;\n #playlist?: Playlist;\n /**\n * Create a Song\n *\n * @param info - Raw song info\n * @param options - Optional data\n */\n constructor(info: SongInfo, { member, metadata }: ResolveOptions<T> = {}) {\n this.source = info.source.toLowerCase();\n this.metadata = <T>metadata;\n this.member = member;\n this.id = info.id;\n this.name = info.name;\n this.isLive = info.isLive;\n this.duration = this.isLive || !info.duration ? 0 : info.duration;\n this.formattedDuration = this.isLive ? \"Live\" : formatDuration(this.duration);\n this.url = info.url;\n this.thumbnail = info.thumbnail;\n this.views = info.views;\n this.likes = info.likes;\n this.dislikes = info.dislikes;\n this.reposts = info.reposts;\n this.uploader = {\n name: info.uploader?.name,\n url: info.uploader?.url,\n };\n this.ageRestricted = info.ageRestricted;\n this.stream = { playFromSource: info.playFromSource };\n this.plugin = info.plugin;\n }\n\n /**\n * The playlist this song belongs to\n */\n get playlist() {\n return this.#playlist;\n }\n\n set playlist(playlist: Playlist | undefined) {\n if (!(playlist instanceof Playlist)) throw new DisTubeError(\"INVALID_TYPE\", \"Playlist\", playlist, \"Song#playlist\");\n this.#playlist = playlist;\n this.member = playlist.member;\n }\n\n /**\n * User requested to play this song.\n */\n get member() {\n return this.#member;\n }\n\n set member(member: GuildMember | undefined) {\n if (isMemberInstance(member)) this.#member = member;\n }\n\n /**\n * User requested to play this song.\n */\n get user() {\n return this.member?.user;\n }\n\n /**\n * Optional metadata that can be used to identify the song. This is attached by the\n * {@link DisTube#play} method.\n */\n get metadata() {\n return this.#metadata;\n }\n\n set metadata(metadata: T) {\n this.#metadata = metadata;\n }\n\n toString() {\n return this.name || this.url || this.id || \"Unknown\";\n }\n}\n","import type { Client } from \"discord.js\";\nimport type {\n DisTube,\n DisTubeEvents,\n DisTubeHandler,\n DisTubePlugin,\n DisTubeVoiceManager,\n Options,\n Queue,\n QueueManager,\n Song,\n} from \"..\";\n\nexport abstract class DisTubeBase {\n distube: DisTube;\n constructor(distube: DisTube) {\n /**\n * DisTube\n */\n this.distube = distube;\n }\n /**\n * Emit the {@link DisTube} of this base\n * @param eventName - Event name\n * @param args - arguments\n */\n emit(eventName: keyof DisTubeEvents, ...args: any): boolean {\n return this.distube.emit(eventName, ...args);\n }\n /**\n * Emit error event\n * @param error - error\n * @param queue - The queue encountered the error\n * @param song - The playing song when encountered the error\n */\n emitError(error: Error, queue: Queue, song?: Song) {\n this.distube.emitError(error, queue, song);\n }\n /**\n * Emit debug event\n * @param message - debug message\n */\n debug(message: string) {\n this.distube.debug(message);\n }\n /**\n * The queue manager\n */\n get queues(): QueueManager {\n return this.distube.queues;\n }\n /**\n * The voice manager\n */\n get voices(): DisTubeVoiceManager {\n return this.distube.voices;\n }\n /**\n * Discord.js client\n */\n get client(): Client {\n return this.distube.client;\n }\n /**\n * DisTube options\n */\n get options(): Options {\n return this.distube.options;\n }\n /**\n * DisTube handler\n */\n get handler(): DisTubeHandler {\n return this.distube.handler;\n }\n /**\n * DisTube plugins\n */\n get plugins(): DisTubePlugin[] {\n return this.distube.plugins;\n }\n}\n","import { Constants } from \"discord.js\";\nimport { TypedEmitter } from \"tiny-typed-emitter\";\nimport { DisTubeError, isSupportedVoiceChannel } from \"..\";\nimport {\n AudioPlayerStatus,\n VoiceConnectionDisconnectReason,\n VoiceConnectionStatus,\n createAudioPlayer,\n entersState,\n joinVoiceChannel,\n} from \"@discordjs/voice\";\nimport type { AudioPlayer, VoiceConnection } from \"@discordjs/voice\";\nimport type { Snowflake, VoiceBasedChannel, VoiceState } from \"discord.js\";\nimport type { DisTubeStream, DisTubeVoiceEvents, DisTubeVoiceManager } from \"..\";\n\n/**\n * Create a voice connection to the voice channel\n */\nexport class DisTubeVoice extends TypedEmitter<DisTubeVoiceEvents> {\n readonly id: Snowflake;\n readonly voices: DisTubeVoiceManager;\n readonly audioPlayer: AudioPlayer;\n connection!: VoiceConnection;\n emittedError!: boolean;\n isDisconnected = false;\n stream?: DisTubeStream;\n #channel!: VoiceBasedChannel;\n #volume = 100;\n constructor(voiceManager: DisTubeVoiceManager, channel: VoiceBasedChannel) {\n super();\n /**\n * The voice manager that instantiated this connection\n */\n this.voices = voiceManager;\n this.id = channel.guildId;\n this.channel = channel;\n this.voices.add(this.id, this);\n this.audioPlayer = createAudioPlayer()\n .on(AudioPlayerStatus.Idle, oldState => {\n if (oldState.status !== AudioPlayerStatus.Idle) this.emit(\"finish\");\n })\n .on(\"error\", (error: NodeJS.ErrnoException) => {\n if (this.emittedError) return;\n this.emittedError = true;\n this.emit(\"error\", error);\n });\n this.connection\n .on(VoiceConnectionStatus.Disconnected, (_, newState) => {\n if (newState.reason === VoiceConnectionDisconnectReason.Manual) {\n // User disconnect\n this.leave();\n } else if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {\n // Move to other channel\n entersState(this.connection, VoiceConnectionStatus.Connecting, 5e3).catch(() => {\n if (\n ![VoiceConnectionStatus.Ready, VoiceConnectionStatus.Connecting].includes(this.connection.state.status)\n ) {\n this.leave();\n }\n });\n } else if (this.connection.rejoinAttempts < 5) {\n // Try to rejoin\n setTimeout(\n () => {\n this.connection.rejoin();\n },\n (this.connection.rejoinAttempts + 1) * 5e3,\n ).unref();\n } else if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) {\n // Leave after 5 attempts\n this.leave(new DisTubeError(\"VOICE_RECONNECT_FAILED\"));\n }\n })\n .on(VoiceConnectionStatus.Destroyed, () => {\n this.leave();\n })\n .on(\"error\", () => undefined);\n this.connection.subscribe(this.audioPlayer);\n }\n /**\n * The voice channel id the bot is in\n */\n get channelId() {\n return this.connection?.joinConfig?.channelId ?? undefined;\n }\n get channel() {\n if (!this.channelId) return this.#channel;\n if (this.#channel?.id === this.channelId) return this.#channel;\n const channel = this.voices.client.channels.cache.get(this.channelId);\n if (!channel) return this.#channel;\n for (const type of Constants.VoiceBasedChannelTypes) {\n if (channel.type === type) {\n this.#channel = channel;\n return channel;\n }\n }\n return this.#channel;\n }\n set channel(channel: VoiceBasedChannel) {\n if (!isSupportedVoiceChannel(channel)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"BaseGuildVoiceChannel\", channel, \"DisTubeVoice#channel\");\n }\n if (channel.guildId !== this.id) throw new DisTubeError(\"VOICE_DIFFERENT_GUILD\");\n if (channel.client.user?.id !== this.voices.client.user?.id) throw new DisTubeError(\"VOICE_DIFFERENT_CLIENT\");\n if (channel.id === this.channelId) return;\n if (!channel.joinable) {\n if (channel.full) throw new DisTubeError(\"VOICE_FULL\");\n else throw new DisTubeError(\"VOICE_MISSING_PERMS\");\n }\n this.connection = this.#join(channel);\n this.#channel = channel;\n }\n #join(channel: VoiceBasedChannel) {\n return joinVoiceChannel({\n channelId: channel.id,\n guildId: this.id,\n adapterCreator: channel.guild.voiceAdapterCreator,\n group: channel.client.user?.id,\n });\n }\n /**\n * Join a voice channel with this connection\n * @param channel - A voice channel\n */\n async join(channel?: VoiceBasedChannel): Promise<DisTubeVoice> {\n const TIMEOUT = 30e3;\n if (channel) this.channel = channel;\n try {\n await entersState(this.connection, VoiceConnectionStatus.Ready, TIMEOUT);\n } catch {\n if (this.connection.state.status === VoiceConnectionStatus.Ready) return this;\n if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) this.connection.destroy();\n this.voices.remove(this.id);\n throw new DisTubeError(\"VOICE_CONNECT_FAILED\", TIMEOUT / 1e3);\n }\n return this;\n }\n /**\n * Leave the voice channel of this connection\n * @param error - Optional, an error to emit with 'error' event.\n */\n leave(error?: Error) {\n this.stop(true);\n if (!this.isDisconnected) {\n this.emit(\"disconnect\", error);\n this.isDisconnected = true;\n }\n if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) this.connection.destroy();\n this.voices.remove(this.id);\n }\n /**\n * Stop the playing stream\n * @param force - If true, will force the {@link DisTubeVoice#audioPlayer} to enter the Idle state even\n * if the {@link DisTubeStream#audioResource} has silence padding frames.\n */\n stop(force = false) {\n this.audioPlayer.stop(force);\n }\n /**\n * Play a {@link DisTubeStream}\n * @param dtStream - DisTubeStream\n */\n play(dtStream: DisTubeStream) {\n this.emittedError = false;\n dtStream.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (this.emittedError || error.code === \"ERR_STREAM_PREMATURE_CLOSE\") return;\n this.emittedError = true;\n this.emit(\"error\", error);\n });\n if (this.audioPlayer.state.status !== AudioPlayerStatus.Paused) this.audioPlayer.play(dtStream.audioResource);\n this.stream?.kill();\n this.stream = dtStream;\n this.volume = this.#volume;\n dtStream.spawn();\n }\n set volume(volume: number) {\n if (typeof volume !== \"number\" || isNaN(volume)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"number\", volume, \"volume\");\n }\n if (volume < 0) {\n throw new DisTubeError(\"NUMBER_COMPARE\", \"Volume\", \"bigger or equal to\", 0);\n }\n this.#volume = volume;\n this.stream?.setVolume(Math.pow(this.#volume / 100, 0.5 / Math.log10(2)));\n }\n /**\n * Get or set the volume percentage\n */\n get volume() {\n return this.#volume;\n }\n /**\n * Playback duration of the audio resource in seconds\n */\n get playbackDuration() {\n return (this.stream?.audioResource?.playbackDuration ?? 0) / 1000;\n }\n pause() {\n this.audioPlayer.pause();\n }\n unpause() {\n const state = this.audioPlayer.state;\n if (state.status !== AudioPlayerStatus.Paused) return;\n if (this.stream?.audioResource && state.resource !== this.stream.audioResource) {\n this.audioPlayer.play(this.stream.audioResource);\n } else {\n this.audioPlayer.unpause();\n }\n }\n /**\n * Whether the bot is self-deafened\n */\n get selfDeaf(): boolean {\n return this.connection.joinConfig.selfDeaf;\n }\n /**\n * Whether the bot is self-muted\n */\n get selfMute(): boolean {\n return this.connection.joinConfig.selfMute;\n }\n /**\n * Self-deafens/undeafens the bot.\n * @param selfDeaf - Whether or not the bot should be self-deafened\n * @returns true if the voice state was successfully updated, otherwise false\n */\n setSelfDeaf(selfDeaf: boolean): boolean {\n if (typeof selfDeaf !== \"boolean\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"boolean\", selfDeaf, \"selfDeaf\");\n }\n return this.connection.rejoin({\n ...this.connection.joinConfig,\n selfDeaf,\n });\n }\n /**\n * Self-mutes/unmutes the bot.\n * @param selfMute - Whether or not the bot should be self-muted\n * @returns true if the voice state was successfully updated, otherwise false\n */\n setSelfMute(selfMute: boolean): boolean {\n if (typeof selfMute !== \"boolean\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"boolean\", selfMute, \"selfMute\");\n }\n return this.connection.rejoin({\n ...this.connection.joinConfig,\n selfMute,\n });\n }\n /**\n * The voice state of this connection\n */\n get voiceState(): VoiceState | undefined {\n return this.channel?.guild?.members?.me?.voice;\n }\n}\n","import { Transform } from \"stream\";\nimport { DisTubeError, Events } from \"..\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { TypedEmitter } from \"tiny-typed-emitter\";\nimport { StreamType, createAudioResource } from \"@discordjs/voice\";\nimport type { TransformCallback } from \"stream\";\nimport type { ChildProcess } from \"child_process\";\nimport type { AudioResource } from \"@discordjs/voice\";\nimport type { Awaitable, DisTube, FFmpegArg, FFmpegOptions } from \"..\";\n\n/**\n * Options for {@link DisTubeStream}\n */\nexport interface StreamOptions {\n /**\n * FFmpeg options\n */\n ffmpeg: FFmpegOptions;\n /**\n * Seek time (in seconds).\n * @default 0\n */\n seek?: number;\n}\n\nlet checked = process.env.NODE_ENV === \"test\";\nexport const checkFFmpeg = (distube: DisTube) => {\n if (checked) return;\n const path = distube.options.ffmpeg.path;\n const debug = (str: string) => distube.emit(Events.FFMPEG_DEBUG, str);\n try {\n debug(`[test] spawn ffmpeg at '${path}' path`);\n const process = spawnSync(path, [\"-h\"], { windowsHide: true, shell: true, encoding: \"utf-8\" });\n if (process.error) throw process.error;\n if (process.stderr && !process.stdout) throw new Error(process.stderr);\n\n const result = process.output.join(\"\\n\");\n const version = /ffmpeg version (\\S+)/iu.exec(result)?.[1];\n if (!version) throw new Error(\"Invalid FFmpeg version\");\n debug(`[test] ffmpeg version: ${version}`);\n } catch (e: any) {\n debug(`[test] failed to spawn ffmpeg at '${path}': ${e?.stack ?? e}`);\n throw new DisTubeError(\"FFMPEG_NOT_INSTALLED\", path);\n }\n checked = true;\n};\n\n/**\n * Create a stream to play with {@link DisTubeVoice}\n */\nexport class DisTubeStream extends TypedEmitter<{\n debug: (debug: string) => Awaitable;\n error: (error: Error) => Awaitable;\n}> {\n #ffmpegPath: string;\n #opts: string[];\n process?: ChildProcess;\n stream: VolumeTransformer;\n audioResource: AudioResource;\n /**\n * Create a DisTubeStream to play with {@link DisTubeVoice}\n * @param url - Stream URL\n * @param options - Stream options\n */\n constructor(url: string, options: StreamOptions) {\n super();\n const { ffmpeg, seek } = options;\n const opts: FFmpegArg = {\n reconnect: 1,\n reconnect_streamed: 1,\n reconnect_delay_max: 5,\n analyzeduration: 0,\n hide_banner: true,\n ...ffmpeg.args.global,\n ...ffmpeg.args.input,\n i: url,\n ar: 48000,\n ac: 2,\n ...ffmpeg.args.output,\n f: \"s16le\",\n };\n\n if (typeof seek === \"number\" && seek > 0) opts.ss = seek.toString();\n\n const fileUrl = new URL(url);\n if (fileUrl.protocol === \"file:\") {\n opts.reconnect = null;\n opts.reconnect_streamed = null;\n opts.reconnect_delay_max = null;\n opts.i = fileUrl.hostname + fileUrl.pathname;\n }\n\n this.#ffmpegPath = ffmpeg.path;\n this.#opts = [\n ...Object.entries(opts)\n .flatMap(([key, value]) =>\n Array.isArray(value)\n ? value.filter(Boolean).map(v => [`-${key}`, String(v)])\n : value == null || value === false\n ? []\n : [value === true ? `-${key}` : [`-${key}`, String(value)]],\n )\n .flat(),\n \"pipe:1\",\n ];\n\n this.stream = new VolumeTransformer();\n this.stream\n .on(\"close\", () => this.kill())\n .on(\"error\", err => {\n this.debug(`[stream] error: ${err.message}`);\n this.emit(\"error\", err);\n })\n .on(\"finish\", () => this.debug(\"[stream] log: stream finished\"));\n\n this.audioResource = createAudioResource(this.stream, { inputType: StreamType.Raw, inlineVolume: false });\n }\n\n spawn() {\n this.debug(`[process] spawn: ${this.#ffmpegPath} ${this.#opts.join(\" \")}`);\n this.process = spawn(this.#ffmpegPath, this.#opts, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: false,\n windowsHide: true,\n })\n .on(\"error\", err => {\n this.debug(`[process] error: ${err.message}`);\n this.emit(\"error\", err);\n })\n .on(\"exit\", (code, signal) => {\n this.debug(`[process] exit: code=${code ?? \"unknown\"} signal=${signal ?? \"unknown\"}`);\n if (!code || [0, 255].includes(code)) return;\n this.debug(`[process] error: ffmpeg exited with code ${code}`);\n this.emit(\"error\", new DisTubeError(\"FFMPEG_EXITED\", code));\n });\n\n if (!this.process.stdout || !this.process.stderr) {\n this.kill();\n throw new Error(\"Failed to create ffmpeg process\");\n }\n\n this.process.stdout.pipe(this.stream);\n this.process.stderr.setEncoding(\"utf8\")?.on(\"data\", (data: string) => {\n const lines = data.split(/\\r\\n|\\r|\\n/u);\n for (const line of lines) {\n if (/^\\s*$/.test(line)) continue;\n this.debug(`[ffmpeg] log: ${line}`);\n }\n });\n }\n\n private debug(debug: string) {\n this.emit(\"debug\", debug);\n }\n\n setVolume(volume: number) {\n this.stream.vol = volume;\n }\n\n kill() {\n if (!this.stream.destroyed) this.stream.destroy();\n if (this.process && !this.process.killed) this.process.kill(\"SIGKILL\");\n }\n}\n\n// Based on prism-media\nclass VolumeTransformer extends Transform {\n private buffer = Buffer.allocUnsafe(0);\n private readonly extrema = [-Math.pow(2, 16 - 1), Math.pow(2, 16 - 1) - 1];\n vol = 1;\n\n override _transform(newChunk: Buffer, _encoding: BufferEncoding, done: TransformCallback): void {\n const { vol } = this;\n if (vol === 1) {\n this.push(newChunk);\n done();\n return;\n }\n\n const bytes = 2;\n const chunk = Buffer.concat([this.buffer, newChunk]);\n const readableLength = Math.floor(chunk.length / bytes) * bytes;\n\n for (let i = 0; i < readableLength; i += bytes) {\n const value = chunk.readInt16LE(i);\n const clampedValue = Math.min(this.extrema[1], Math.max(this.extrema[0], value * vol));\n chunk.writeInt16LE(clampedValue, i);\n }\n\n this.buffer = chunk.subarray(readableLength);\n this.push(chunk.subarray(0, readableLength));\n done();\n }\n}\n","import { DisTubeBase } from \".\";\nimport { request } from \"undici\";\nimport { DisTubeError, Playlist, PluginType, Song, isURL } from \"..\";\nimport type { DisTubePlugin, ResolveOptions } from \"..\";\n\nconst REDIRECT_CODES = new Set([301, 302, 303, 307, 308]);\n\n/**\n * DisTube's Handler\n */\nexport class DisTubeHandler extends DisTubeBase {\n resolve<T = unknown>(song: Song<T>, options?: Omit<ResolveOptions, \"metadata\">): Promise<Song<T>>;\n resolve<T = unknown>(song: Playlist<T>, options?: Omit<ResolveOptions, \"metadata\">): Promise<Playlist<T>>;\n resolve<T = unknown>(song: string, options?: ResolveOptions<T>): Promise<Song<T> | Playlist<T>>;\n resolve<T = unknown>(song: Song, options: ResolveOptions<T>): Promise<Song<T>>;\n resolve<T = unknown>(song: Playlist, options: ResolveOptions<T>): Promise<Playlist<T>>;\n resolve(song: string | Song | Playlist, options?: ResolveOptions): Promise<Song | Playlist>;\n /**\n * Resolve a url or a supported object to a {@link Song} or {@link Playlist}\n * @throws {@link DisTubeError}\n * @param input - Resolvable input\n * @param options - Optional options\n * @returns Resolved\n */\n async resolve(input: string | Song | Playlist, options: ResolveOptions = {}): Promise<Song | Playlist> {\n if (input instanceof Song || input instanceof Playlist) {\n if (\"metadata\" in options) input.metadata = options.metadata;\n if (\"member\" in options) input.member = options.member;\n return input;\n }\n if (typeof input === \"string\") {\n if (isURL(input)) {\n const plugin =\n (await this._getPluginFromURL(input)) || (await this._getPluginFromURL(await this.followRedirectLink(input)));\n if (!plugin) throw new DisTubeError(\"NOT_SUPPORTED_URL\");\n this.debug(`[${plugin.constructor.name}] Resolving from url: ${input}`);\n return plugin.resolve(input, options);\n }\n try {\n const song = await this.#searchSong(input, options);\n if (song) return song;\n } catch {\n // ignore\n }\n }\n throw new DisTubeError(\"CANNOT_RESOLVE_SONG\", input);\n }\n\n async _getPluginFromURL(url: string): Promise<DisTubePlugin | null> {\n for (const plugin of this.plugins) if (await plugin.validate(url)) return plugin;\n return null;\n }\n\n _getPluginFromSong(song: Song): Promise<DisTubePlugin | null>;\n _getPluginFromSong<T extends PluginType>(\n song: Song,\n types: T[],\n validate?: boolean,\n ): Promise<(DisTubePlugin & { type: T }) | null>;\n async _getPluginFromSong<T extends PluginType>(\n song: Song,\n types?: T[],\n validate = true,\n ): Promise<(DisTubePlugin & { type: T }) | null> {\n if (!types || types.includes(<T>song.plugin?.type)) return song.plugin as DisTubePlugin & { type: T };\n if (!song.url) return null;\n for (const plugin of this.plugins) {\n if ((!types || types.includes(<T>plugin?.type)) && (!validate || (await plugin.validate(song.url)))) {\n return plugin as DisTubePlugin & { type: T };\n }\n }\n return null;\n }\n\n async #searchSong(query: string, options: ResolveOptions = {}, getStreamURL = false): Promise<Song | null> {\n for (const plugin of this.plugins) {\n if (plugin.type === PluginType.EXTRACTOR) {\n this.debug(`[${plugin.constructor.name}] Searching for song: ${query}`);\n const result = await plugin.searchSong(query, options);\n if (result) {\n if (getStreamURL && result.stream.playFromSource) result.stream.url = await plugin.getStreamURL(result);\n return result;\n }\n }\n }\n return null;\n }\n\n /**\n * Get {@link Song}'s stream info and attach it to the song.\n * @param song - A Song\n */\n async attachStreamInfo(song: Song) {\n if (song.stream.playFromSource) {\n if (song.stream.url) return;\n this.debug(`[DisTubeHandler] Getting stream info: ${song}`);\n const plugin = await this._getPluginFromSong(song, [PluginType.EXTRACTOR, PluginType.PLAYABLE_EXTRACTOR]);\n if (!plugin) throw new DisTubeError(\"NOT_SUPPORTED_SONG\", song.toString());\n this.debug(`[${plugin.constructor.name}] Getting stream URL: ${song}`);\n song.stream.url = await plugin.getStreamURL(song);\n if (!song.stream.url) throw new DisTubeError(\"CANNOT_GET_STREAM_URL\", song.toString());\n } else {\n if (song.stream.song?.stream?.playFromSource && song.stream.song.stream.url) return;\n this.debug(`[DisTubeHandler] Getting stream info: ${song}`);\n const plugin = await this._getPluginFromSong(song, [PluginType.INFO_EXTRACTOR]);\n if (!plugin) throw new DisTubeError(\"NOT_SUPPORTED_SONG\", song.toString());\n this.debug(`[${plugin.constructor.name}] Creating search query for: ${song}`);\n const query = await plugin.createSearchQuery(song);\n if (!query) throw new DisTubeError(\"CANNOT_GET_SEARCH_QUERY\", song.toString());\n const altSong = await this.#searchSong(query, { metadata: song.metadata, member: song.member }, true);\n if (!altSong || !altSong.stream.playFromSource) throw new DisTubeError(\"NO_RESULT\", query || song.toString());\n song.stream.song = altSong;\n }\n }\n\n async followRedirectLink(url: string, maxRedirect = 5): Promise<string> {\n if (maxRedirect === 0) return url;\n\n const res = await request(url, {\n method: \"HEAD\",\n headers: {\n \"user-agent\":\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \" +\n \"Chrome/125.0.0.0 Safari/537.36\",\n },\n });\n\n if (REDIRECT_CODES.has(res.statusCode ?? 200)) {\n let location = res.headers.location;\n if (typeof location !== \"string\") location = location?.[0] ?? url;\n return this.followRedirectLink(location, --maxRedirect);\n }\n\n return url;\n }\n}\n","import { DisTubeError, checkInvalidKey, defaultOptions } from \"..\";\nimport type { DisTubeOptions, DisTubePlugin, FFmpegArgs, FFmpegOptions, Filters } from \"..\";\n\nexport class Options {\n plugins: DisTubePlugin[];\n emitNewSongOnly: boolean;\n savePreviousSongs: boolean;\n customFilters?: Filters;\n nsfw: boolean;\n emitAddSongWhenCreatingQueue: boolean;\n emitAddListWhenCreatingQueue: boolean;\n joinNewVoiceChannel: boolean;\n ffmpeg: FFmpegOptions;\n constructor(options: DisTubeOptions) {\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"object\", options, \"DisTubeOptions\");\n }\n const opts = { ...defaultOptions, ...options };\n this.plugins = opts.plugins;\n this.emitNewSongOnly = opts.emitNewSongOnly;\n this.savePreviousSongs = opts.savePreviousSongs;\n this.customFilters = opts.customFilters;\n this.nsfw = opts.nsfw;\n this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;\n this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;\n this.joinNewVoiceChannel = opts.joinNewVoiceChannel;\n this.ffmpeg = this.#ffmpegOption(options);\n checkInvalidKey(opts, this, \"DisTubeOptions\");\n this.#validateOptions();\n }\n\n #validateOptions(options = this) {\n const booleanOptions = new Set([\n \"emitNewSongOnly\",\n \"savePreviousSongs\",\n \"joinNewVoiceChannel\",\n \"nsfw\",\n \"emitAddSongWhenCreatingQueue\",\n \"emitAddListWhenCreatingQueue\",\n ]);\n const numberOptions = new Set();\n const stringOptions = new Set();\n const objectOptions = new Set([\"customFilters\", \"ffmpeg\"]);\n const optionalOptions = new Set([\"customFilters\"]);\n\n for (const [key, value] of Object.entries(options)) {\n if (value === undefined && optionalOptions.has(key)) continue;\n if (key === \"plugins\" && !Array.isArray(value)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"Array<Plugin>\", value, `DisTubeOptions.${key}`);\n } else if (booleanOptions.has(key)) {\n if (typeof value !== \"boolean\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"boolean\", value, `DisTubeOptions.${key}`);\n }\n } else if (numberOptions.has(key)) {\n if (typeof value !== \"number\" || isNaN(value)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"number\", value, `DisTubeOptions.${key}`);\n }\n } else if (stringOptions.has(key)) {\n if (typeof value !== \"string\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"string\", value, `DisTubeOptions.${key}`);\n }\n } else if (objectOptions.has(key)) {\n if (typeof value !== \"object\" || Array.isArray(value)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"object\", value, `DisTubeOptions.${key}`);\n }\n }\n }\n }\n\n #ffmpegOption(opts: DisTubeOptions) {\n const args: FFmpegArgs = { global: {}, input: {}, output: {} };\n if (opts.ffmpeg?.args) {\n if (opts.ffmpeg.args.global) args.global = opts.ffmpeg.args.global;\n if (opts.ffmpeg.args.input) args.input = opts.ffmpeg.args.input;\n if (opts.ffmpeg.args.output) args.output = opts.ffmpeg.args.output;\n }\n const path = opts.ffmpeg?.path ?? \"ffmpeg\";\n if (typeof path !== \"string\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"string\", path, \"DisTubeOptions.ffmpeg.path\");\n }\n for (const [key, value] of Object.entries(args)) {\n if (typeof value !== \"object\" || Array.isArray(value)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"object\", value, `DisTubeOptions.ffmpeg.${key}`);\n }\n for (const [k, v] of Object.entries(value)) {\n if (\n typeof v !== \"string\" &&\n typeof v !== \"number\" &&\n typeof v !== \"boolean\" &&\n !Array.isArray(v) &&\n v !== null &&\n v !== undefined\n ) {\n throw new DisTubeError(\n \"INVALID_TYPE\",\n [\"string\", \"number\", \"boolean\", \"Array<string | null | undefined>\", \"null\", \"undefined\"],\n v,\n `DisTubeOptions.ffmpeg.${key}.${k}`,\n );\n }\n }\n }\n return { path, args };\n }\n}\n","import { DisTubeBase } from \"..\";\nimport { Collection } from \"discord.js\";\n\n/**\n * Manages the collection of a data model.\n */\nexport abstract class BaseManager<V> extends DisTubeBase {\n /**\n * The collection of items for this manager.\n */\n collection = new Collection<string, V>();\n /**\n * The size of the collection.\n */\n get size() {\n return this.collection.size;\n }\n}\n","import { BaseManager } from \".\";\nimport { resolveGuildId } from \"../..\";\nimport type { GuildIdResolvable } from \"../..\";\n\n/**\n * Manages the collection of a data model paired with a guild id.\n */\nexport abstract class GuildIdManager<V> extends BaseManager<V> {\n add(idOrInstance: GuildIdResolvable, data: V) {\n const id = resolveGuildId(idOrInstance);\n const existing = this.get(id);\n if (existing) return this;\n this.collection.set(id, data);\n return this;\n }\n get(idOrInstance: GuildIdResolvable): V | undefined {\n return this.collection.get(resolveGuildId(idOrInstance));\n }\n remove(idOrInstance: GuildIdResolvable): boolean {\n return this.collection.delete(resolveGuildId(idOrInstance));\n }\n has(idOrInstance: GuildIdResolvable): boolean {\n return this.collection.has(resolveGuildId(idOrInstance));\n }\n}\n","import { GuildIdManager } from \".\";\nimport { DisTubeVoice } from \"../DisTubeVoice\";\nimport { DisTubeError, resolveGuildId } from \"../..\";\nimport { VoiceConnectionStatus, getVoiceConnection } from \"@discordjs/voice\";\nimport type { GuildIdResolvable } from \"../..\";\nimport type { VoiceBasedChannel } from \"discord.js\";\n\n/**\n * Manages voice connections\n */\nexport class DisTubeVoiceManager extends GuildIdManager<DisTubeVoice> {\n /**\n * Create a {@link DisTubeVoice} instance\n * @param channel - A voice channel to join\n */\n create(channel: VoiceBasedChannel): DisTubeVoice {\n const existing = this.get(channel.guildId);\n if (existing) {\n existing.channel = channel;\n return existing;\n }\n if (\n getVoiceConnection(resolveGuildId(channel), this.client.user?.id) ||\n getVoiceConnection(resolveGuildId(channel))\n ) {\n throw new DisTubeError(\"VOICE_ALREADY_CREATED\");\n }\n return new DisTubeVoice(this, channel);\n }\n /**\n * Join a voice channel and wait until the connection is ready\n * @param channel - A voice channel to join\n */\n join(channel: VoiceBasedChannel): Promise<DisTubeVoice> {\n const existing = this.get(channel.guildId);\n if (existing) return existing.join(channel);\n return this.create(channel).join();\n }\n /**\n * Leave the connected voice channel in a guild\n * @param guild - Queue Resolvable\n */\n leave(guild: GuildIdResolvable) {\n const voice = this.get(guild);\n if (voice) {\n voice.leave();\n } else {\n const connection =\n getVoiceConnection(resolveGuildId(guild), this.client.user?.id) ?? getVoiceConnection(resolveGuildId(guild));\n if (connection && connection.state.status !== VoiceConnectionStatus.Destroyed) {\n connection.destroy();\n }\n }\n }\n}\n","import { BaseManager } from \".\";\nimport { DisTubeError } from \"../..\";\nimport type { FFmpegArg as FFmpegArgsValue, Filter, FilterResolvable, Queue } from \"../..\";\n\n/**\n * Manage filters of a playing {@link Queue}\n */\nexport class FilterManager extends BaseManager<Filter> {\n /**\n * The queue to manage\n */\n queue: Queue;\n constructor(queue: Queue) {\n super(queue.distube);\n this.queue = queue;\n }\n\n #resolve(filter: FilterResolvable): Filter {\n if (typeof filter === \"object\" && typeof filter.name === \"string\" && typeof filter.value === \"string\") {\n return filter;\n }\n if (typeof filter === \"string\" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter)) {\n return {\n name: filter,\n value: this.distube.filters[filter],\n };\n }\n throw new DisTubeError(\"INVALID_TYPE\", \"FilterResolvable\", filter, \"filter\");\n }\n\n #apply() {\n this.queue._beginTime = this.queue.currentTime;\n this.queue.play(false);\n }\n\n /**\n * Enable a filter or multiple filters to the manager\n * @param filterOrFilters - The filter or filters to enable\n * @param override - Wether or not override the applied filter with new filter value\n */\n add(filterOrFilters: FilterResolvable | FilterResolvable[], override = false) {\n if (Array.isArray(filterOrFilters)) {\n for (const filter of filterOrFilters) {\n const ft = this.#resolve(filter);\n if (override || !this.has(ft)) this.collection.set(ft.name, ft);\n }\n } else {\n const ft = this.#resolve(filterOrFilters);\n if (override || !this.has(ft)) this.collection.set(ft.name, ft);\n }\n this.#apply();\n return this;\n }\n\n /**\n * Clear enabled filters of the manager\n */\n clear() {\n return this.set([]);\n }\n\n /**\n * Set the filters applied to the manager\n * @param filters - The filters to apply\n */\n set(filters: FilterResolvable[]) {\n if (!Array.isArray(filters)) throw new DisTubeError(\"INVALID_TYPE\", \"Array<FilterResolvable>\", filters, \"filters\");\n this.collection.clear();\n for (const f of filters) {\n const filter = this.#resolve(f);\n this.collection.set(filter.name, filter);\n }\n this.#apply();\n return this;\n }\n\n #removeFn(f: FilterResolvable) {\n return this.collection.delete(this.#resolve(f).name);\n }\n\n /**\n * Disable a filter or multiple filters\n * @param filterOrFilters - The filter or filters to disable\n */\n remove(filterOrFilters: FilterResolvable | FilterResolvable[]) {\n if (Array.isArray(filterOrFilters)) filterOrFilters.forEach(f => this.#removeFn(f));\n else this.#removeFn(filterOrFilters);\n this.#apply();\n return this;\n }\n\n /**\n * Check whether a filter enabled or not\n * @param filter - The filter to check\n */\n has(filter: FilterResolvable) {\n return this.collection.has(typeof filter === \"string\" ? filter : this.#resolve(filter).name);\n }\n\n /**\n * Array of enabled filter names\n */\n get names(): string[] {\n return [...this.collection.keys()];\n }\n\n /**\n * Array of enabled filters\n */\n get values(): Filter[] {\n return [...this.collection.values()];\n }\n\n get ffmpegArgs(): FFmpegArgsValue {\n return this.size ? { af: this.values.map(f => f.value).join(\",\") } : {};\n }\n\n override toString() {\n return this.names.toString();\n }\n}\n","import { GuildIdManager } from \".\";\nimport { DisTubeError, DisTubeStream, Events, Queue, RepeatMode, checkFFmpeg, objectKeys } from \"../..\";\nimport type { Song } from \"../..\";\nimport type { GuildTextBasedChannel, VoiceBasedChannel } from \"discord.js\";\n\n/**\n * Queue manager\n */\nexport class QueueManager extends GuildIdManager<Queue> {\n /**\n * Create a {@link Queue}\n * @param channel - A voice channel\n * @param textChannel - Default text channel\n * @returns Returns `true` if encounter an error\n */\n async create(channel: VoiceBasedChannel, textChannel?: GuildTextBasedChannel): Promise<Queue> {\n if (this.has(channel.guildId)) throw new DisTubeError(\"QUEUE_EXIST\");\n this.debug(`[QueueManager] Creating queue for guild: ${channel.guildId}`);\n const voice = this.voices.create(channel);\n const queue = new Queue(this.distube, voice, textChannel);\n await queue._taskQueue.queuing();\n try {\n checkFFmpeg(this.distube);\n this.debug(`[QueueManager] Joining voice channel: ${channel.id}`);\n await voice.join();\n this.#voiceEventHandler(queue);\n this.add(queue.id, queue);\n this.emit(Events.INIT_QUEUE, queue);\n return queue;\n } finally {\n queue._taskQueue.resolve();\n }\n }\n\n /**\n * Listen to DisTubeVoice events and handle the Queue\n * @param queue - Queue\n */\n #voiceEventHandler(queue: Queue) {\n queue._listeners = {\n disconnect: error => {\n queue.remove();\n this.emit(Events.DISCONNECT, queue);\n if (error) this.emitError(error, queue, queue.songs?.[0]);\n },\n error: error => this.#handlePlayingError(queue, error),\n finish: () => this.#handleSongFinish(queue),\n };\n for (const event of objectKeys(queue._listeners)) {\n queue.voice.on(event, queue._listeners[event]);\n }\n }\n\n /**\n * Whether or not emit playSong event\n * @param queue - Queue\n */\n #emitPlaySong(queue: Queue): boolean {\n return (\n !this.options.emitNewSongOnly ||\n (queue.repeatMode === RepeatMode.SONG && queue._next) ||\n (queue.repeatMode !== RepeatMode.SONG && queue.songs[0]?.id !== queue.songs[1]?.id)\n );\n }\n\n /**\n * Handle the queue when a Song finish\n * @param queue - queue\n */\n async #handleSongFinish(queue: Queue): Promise<void> {\n this.debug(`[QueueManager] Handling song finish: ${queue.id}`);\n const song = queue.songs[0];\n this.emit(Events.FINISH_SONG, queue, queue.songs[0]);\n await queue._taskQueue.queuing();\n try {\n if (queue.stopped) return;\n if (queue.repeatMode === RepeatMode.QUEUE && !queue._prev) queue.songs.push(song);\n if (queue._prev) {\n if (queue.repeatMode === RepeatMode.QUEUE) queue.songs.unshift(queue.songs.pop() as Song);\n else queue.songs.unshift(queue.previousSongs.pop() as Song);\n }\n if (queue.songs.length <= 1 && (queue._next || queue.repeatMode === RepeatMode.DISABLED)) {\n if (queue.autoplay) {\n try {\n this.debug(`[QueueManager] Adding related song: ${queue.id}`);\n await queue.addRelatedSong();\n } catch (e: any) {\n this.debug(`[${queue.id}] Add related song error: ${e.message}`);\n this.emit(Events.NO_RELATED, queue, e);\n }\n }\n if (queue.songs.length <= 1) {\n this.debug(`[${queue.id}] Queue is empty, stopping...`);\n if (!queue.autoplay) this.emit(Events.FINISH, queue);\n queue.remove();\n return;\n }\n }\n const emitPlaySong = this.#emitPlaySong(queue);\n if (!queue._prev && (queue.repeatMode !== RepeatMode.SONG || queue._next)) {\n const prev = queue.songs.shift() as Song;\n if (this.options.savePreviousSongs) queue.previousSongs.push(prev);\n else queue.previousSongs.push({ id: prev.id } as Song);\n }\n queue._next = queue._prev = false;\n queue._beginTime = 0;\n if (song !== queue.songs[0]) {\n const playedSong = song.stream.playFromSource ? song : song.stream.song;\n if (playedSong?.stream.playFromSource) delete playedSong.stream.url;\n }\n await this.playSong(queue, emitPlaySong);\n } finally {\n queue._taskQueue.resolve();\n }\n }\n\n /**\n * Handle error while playing\n * @param queue - queue\n * @param error - error\n */\n #handlePlayingError(queue: Queue, error: Error) {\n const song = queue.songs.shift()!;\n try {\n error.name = \"PlayingError\";\n } catch {\n // Emit original error\n }\n this.debug(`[${queue.id}] Error while playing: ${error.stack || error.message}`);\n this.emitError(error, queue, song);\n if (queue.songs.length > 0) {\n this.debug(`[${queue.id}] Playing next song: ${queue.songs[0]}`);\n queue._next = queue._prev = false;\n queue._beginTime = 0;\n this.playSong(queue);\n } else {\n this.debug(`[${queue.id}] Queue is empty, stopping...`);\n queue.stop();\n }\n }\n\n /**\n * Play a song on voice connection with queue properties\n * @param queue - The guild queue to play\n * @param emitPlaySong - Whether or not emit {@link Events.PLAY_SONG} event\n */\n async playSong(queue: Queue, emitPlaySong = true) {\n if (!queue) return;\n if (queue.stopped || !queue.songs.length) {\n queue.stop();\n return;\n }\n try {\n const song = queue.songs[0];\n this.debug(`[${queue.id}] Getting stream from: ${song}`);\n await this.handler.attachStreamInfo(song);\n const willPlaySong = song.stream.playFromSource ? song : song.stream.song;\n const stream = willPlaySong?.stream;\n if (!willPlaySong || !stream?.playFromSource || !stream.url) throw new DisTubeError(\"NO_STREAM_URL\", `${song}`);\n this.debug(`[${queue.id}] Creating DisTubeStream for: ${willPlaySong}`);\n const streamOptions = {\n ffmpeg: {\n path: this.options.ffmpeg.path,\n args: {\n global: { ...queue.ffmpegArgs.global },\n input: { ...queue.ffmpegArgs.input },\n output: { ...queue.ffmpegArgs.output, ...queue.filters.ffmpegArgs },\n },\n },\n seek: willPlaySong.duration ? queue._beginTime : undefined,\n };\n const dtStream = new DisTubeStream(stream.url, streamOptions);\n dtStream.on(\"debug\", data => this.emit(Events.FFMPEG_DEBUG, `[${queue.id}] ${data}`));\n this.debug(`[${queue.id}] Started playing: ${willPlaySong}`);\n queue.voice.play(dtStream);\n if (emitPlaySong) this.emit(Events.PLAY_SONG, queue, song);\n } catch (e: any) {\n this.#handlePlayingError(queue, e);\n }\n }\n}\n","import { DisTubeBase, FilterManager } from \"../core\";\nimport { DisTubeError, Events, RepeatMode, TaskQueue, formatDuration, objectKeys } from \"..\";\nimport type { GuildTextBasedChannel, Snowflake } from \"discord.js\";\nimport type { DisTube, DisTubeVoice, DisTubeVoiceEvents, FFmpegArgs, Song } from \"..\";\n\n/**\n * Represents a queue.\n */\nexport class Queue extends DisTubeBase {\n /**\n * Queue id (Guild id)\n */\n readonly id: Snowflake;\n /**\n * Voice connection of this queue.\n */\n voice: DisTubeVoice;\n /**\n * List of songs in the queue (The first one is the playing song)\n */\n songs: Song[];\n /**\n * List of the previous songs.\n */\n previousSongs: Song[];\n /**\n * Whether stream is currently stopped.\n */\n stopped: boolean;\n /**\n * Whether or not the stream is currently playing.\n */\n playing: boolean;\n /**\n * Whether or not the stream is currently paused.\n */\n paused: boolean;\n /**\n * Type of repeat mode (`0` is disabled, `1` is repeating a song, `2` is repeating\n * all the queue). Default value: `0` (disabled)\n */\n repeatMode: RepeatMode;\n /**\n * Whether or not the autoplay mode is enabled. Default value: `false`\n */\n autoplay: boolean;\n /**\n * FFmpeg arguments for the current queue. Default value is defined with {@link DisTubeOptions}.ffmpeg.args.\n * `af` output argument will be replaced with {@link Queue#filters} manager\n */\n ffmpegArgs: FFmpegArgs;\n /**\n * The text channel of the Queue. (Default: where the first command is called).\n */\n textChannel?: GuildTextBasedChannel;\n #filters: FilterManager;\n /**\n * What time in the song to begin (in seconds).\n */\n _beginTime: number;\n /**\n * Whether or not the last song was skipped to next song.\n */\n _next: boolean;\n /**\n * Whether or not the last song was skipped to previous song.\n */\n _prev: boolean;\n /**\n * Task queuing system\n */\n _taskQueue: TaskQueue;\n /**\n * {@link DisTubeVoice} listener\n */\n _listeners?: DisTubeVoiceEvents;\n /**\n * Create a queue for the guild\n * @param distube - DisTube\n * @param voice - Voice connection\n * @param textChannel - Default text channel\n */\n constructor(distube: DisTube, voice: DisTubeVoice, textChannel?: GuildTextBasedChannel) {\n super(distube);\n this.voice = voice;\n this.id = voice.id;\n this.volume = 50;\n this.songs = [];\n this.previousSongs = [];\n this.stopped = false;\n this._next = false;\n this._prev = false;\n this.playing = false;\n this.paused = false;\n this.repeatMode = RepeatMode.DISABLED;\n this.autoplay = false;\n this.#filters = new FilterManager(this);\n this._beginTime = 0;\n this.textChannel = textChannel;\n this._taskQueue = new TaskQueue();\n this._listeners = undefined;\n this.ffmpegArgs = {\n global: { ...this.options.ffmpeg.args.global },\n input: { ...this.options.ffmpeg.args.input },\n output: { ...this.options.ffmpeg.args.output },\n };\n }\n /**\n * The client user as a `GuildMember` of this queue's guild\n */\n get clientMember() {\n return this.voice.channel.guild.members.me ?? undefined;\n }\n /**\n * The filter manager of the queue\n */\n get filters() {\n return this.#filters;\n }\n /**\n * Formatted duration string.\n */\n get formattedDuration() {\n return formatDuration(this.duration);\n }\n /**\n * Queue's duration.\n */\n get duration() {\n return this.songs.length ? this.songs.reduce((prev, next) => prev + next.duration, 0) : 0;\n }\n /**\n * What time in the song is playing (in seconds).\n */\n get currentTime() {\n return this.voice.playbackDuration + this._beginTime;\n }\n /**\n * Formatted {@link Queue#currentTime} string.\n */\n get formattedCurrentTime() {\n return formatDuration(this.currentTime);\n }\n /**\n * The voice channel playing in.\n */\n get voiceChannel() {\n return this.clientMember?.voice?.channel ?? null;\n }\n /**\n * Get or set the stream volume. Default value: `50`.\n */\n get volume() {\n return this.voice.volume;\n }\n set volume(value: number) {\n this.voice.volume = value;\n }\n /**\n * @throws {DisTubeError}\n * @param song - Song to add\n * @param position - Position to add, \\<= 0 to add to the end of the queue\n * @returns The guild queue\n */\n addToQueue(song: Song | Song[], position = 0): Queue {\n if (this.stopped) throw new DisTubeError(\"QUEUE_STOPPED\");\n if (!song || (Array.isArray(song) && !song.length)) {\n throw new DisTubeError(\"INVALID_TYPE\", [\"Song\", \"Array<Song>\"], song, \"song\");\n }\n if (typeof position !== \"number\" || !Number.isInteger(position)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"integer\", position, \"position\");\n }\n if (position <= 0) {\n if (Array.isArray(song)) this.songs.push(...song);\n else this.songs.push(song);\n } else if (Array.isArray(song)) {\n this.songs.splice(position, 0, ...song);\n } else {\n this.songs.splice(position, 0, song);\n }\n return this;\n }\n /**\n * Pause the guild stream\n * @returns The guild queue\n */\n pause(): Queue {\n if (this.paused) throw new DisTubeError(\"PAUSED\");\n this.paused = true;\n this.voice.pause();\n return this;\n }\n /**\n * Resume the guild stream\n * @returns The guild queue\n */\n resume(): Queue {\n if (!this.paused) throw new DisTubeError(\"RESUMED\");\n this.paused = false;\n this.voice.unpause();\n return this;\n }\n /**\n * Set the guild stream's volume\n * @param percent - The percentage of volume you want to set\n * @returns The guild queue\n */\n setVolume(percent: number): Queue {\n this.volume = percent;\n return this;\n }\n\n /**\n * Skip the playing song if there is a next song in the queue. <info>If {@link\n * Queue#autoplay} is `true` and there is no up next song, DisTube will add and\n * play a related song.</info>\n * @returns The song will skip to\n */\n async skip(): Promise<Song> {\n await this._taskQueue.queuing();\n try {\n if (this.songs.length <= 1) {\n if (this.autoplay) await this.addRelatedSong();\n else throw new DisTubeError(\"NO_UP_NEXT\");\n }\n const song = this.songs[1];\n this._next = true;\n this.voice.stop();\n return song;\n } finally {\n this._taskQueue.resolve();\n }\n }\n\n /**\n * Play the previous song if exists\n * @returns The guild queue\n */\n async previous(): Promise<Song> {\n await this._taskQueue.queuing();\n try {\n if (!this.options.savePreviousSongs) throw new DisTubeError(\"DISABLED_OPTION\", \"savePreviousSongs\");\n if (this.previousSongs?.length === 0 && this.repeatMode !== RepeatMode.QUEUE) {\n throw new DisTubeError(\"NO_PREVIOUS\");\n }\n const song =\n this.repeatMode === 2 ? this.songs[this.songs.length - 1] : this.previousSongs[this.previousSongs.length - 1];\n this._prev = true;\n this.voice.stop();\n return song;\n } finally {\n this._taskQueue.resolve();\n }\n }\n /**\n * Shuffle the queue's songs\n * @returns The guild queue\n */\n async shuffle(): Promise<Queue> {\n await this._taskQueue.queuing();\n try {\n const playing = this.songs.shift();\n if (playing === undefined) return this;\n for (let i = this.songs.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [this.songs[i], this.songs[j]] = [this.songs[j], this.songs[i]];\n }\n this.songs.unshift(playing);\n return this;\n } finally {\n this._taskQueue.resolve();\n }\n }\n /**\n * Jump to the song position in the queue. The next one is 1, 2,... The previous\n * one is -1, -2,...\n * if `num` is invalid number\n * @param position - The song position to play\n * @returns The new Song will be played\n */\n async jump(position: number): Promise<Song> {\n await this._taskQueue.queuing();\n try {\n if (typeof position !== \"number\") throw new DisTubeError(\"INVALID_TYPE\", \"number\", position, \"position\");\n if (!position || position > this.songs.length || -position > this.previousSongs.length) {\n throw new DisTubeError(\"NO_SONG_POSITION\");\n }\n let nextSong: Song;\n if (position > 0) {\n const nextSongs = this.songs.splice(position - 1);\n if (this.options.savePreviousSongs) {\n this.previousSongs.push(...this.songs);\n } else {\n this.previousSongs.push(...this.songs.map(s => ({ id: s.id }) as Song));\n }\n this.songs = nextSongs;\n this._next = true;\n nextSong = nextSongs[1];\n } else if (!this.options.savePreviousSongs) {\n throw new DisTubeError(\"DISABLED_OPTION\", \"savePreviousSongs\");\n } else {\n this._prev = true;\n if (position !== -1) this.songs.unshift(...this.previousSongs.splice(position + 1));\n nextSong = this.previousSongs[this.previousSongs.length - 1];\n }\n this.voice.stop();\n return nextSong;\n } finally {\n this._taskQueue.resolve();\n }\n }\n /**\n * Set the repeat mode of the guild queue.\n * Toggle mode `(Disabled -> Song -> Queue -> Disabled ->...)` if `mode` is `undefined`\n * @param mode - The repeat modes (toggle if `undefined`)\n * @returns The new repeat mode\n */\n setRepeatMode(mode?: RepeatMode): RepeatMode {\n if (mode !== undefined && !Object.values(RepeatMode).includes(mode)) {\n throw new DisTubeError(\"INVALID_TYPE\", [\"RepeatMode\", \"undefined\"], mode, \"mode\");\n }\n if (mode === undefined) this.repeatMode = (this.repeatMode + 1) % 3;\n else if (this.repeatMode === mode) this.repeatMode = RepeatMode.DISABLED;\n else this.repeatMode = mode;\n return this.repeatMode;\n }\n /**\n * Set the playing time to another position\n * @param time - Time in seconds\n * @returns The guild queue\n */\n seek(time: number): Queue {\n if (typeof time !== \"number\") throw new DisTubeError(\"INVALID_TYPE\", \"number\", time, \"time\");\n if (isNaN(time) || time < 0) throw new DisTubeError(\"NUMBER_COMPARE\", \"time\", \"bigger or equal to\", 0);\n this._beginTime = time;\n this.play(false);\n return this;\n }\n async #getRelatedSong(current: Song): Promise<Song[]> {\n const plugin = await this.handler._getPluginFromSong(current);\n if (plugin) return plugin.getRelatedSongs(current);\n return [];\n }\n /**\n * Add a related song of the playing song to the queue\n * @returns The added song\n */\n async addRelatedSong(): Promise<Song> {\n const current = this.songs?.[0];\n if (!current) throw new DisTubeError(\"NO_PLAYING_SONG\");\n const prevIds = this.previousSongs.map(p => p.id);\n const relatedSongs = (await this.#getRelatedSong(current)).filter(s => !prevIds.includes(s.id));\n this.debug(`[${this.id}] Getting related songs from: ${current}`);\n if (!relatedSongs.length && !current.stream.playFromSource) {\n const altSong = current.stream.song;\n if (altSong) relatedSongs.push(...(await this.#getRelatedSong(altSong)).filter(s => !prevIds.includes(s.id)));\n this.debug(`[${this.id}] Getting related songs from streamed song: ${altSong}`);\n }\n const song = relatedSongs[0];\n if (!song) throw new DisTubeError(\"NO_RELATED\");\n song.metadata = current.metadata;\n song.member = this.clientMember;\n this.addToQueue(song);\n return song;\n }\n /**\n * Stop the guild stream and delete the queue\n */\n async stop() {\n await this._taskQueue.queuing();\n try {\n this.playing = false;\n this.paused = false;\n this.stopped = true;\n this.voice.stop();\n this.remove();\n } finally {\n this._taskQueue.resolve();\n }\n }\n /**\n * Remove the queue from the manager\n */\n remove() {\n this.stopped = true;\n this.songs = [];\n this.previousSongs = [];\n if (this._listeners) {\n for (const event of objectKeys(this._listeners)) {\n this.voice.off(event, this._listeners[event]);\n }\n }\n this.queues.remove(this.id);\n this.emit(Events.DELETE_QUEUE, this);\n }\n /**\n * Toggle autoplay mode\n * @returns Autoplay mode state\n */\n toggleAutoplay(): boolean {\n this.autoplay = !this.autoplay;\n return this.autoplay;\n }\n /**\n * Play the queue\n * @param emitPlaySong - Whether or not emit {@link Events.PLAY_SONG} event\n */\n play(emitPlaySong = true) {\n if (this.stopped) throw new DisTubeError(\"QUEUE_STOPPED\");\n this.playing = true;\n return this.queues.playSong(this, emitPlaySong);\n }\n}\n","import type { Awaitable, DisTube, PluginType, Song } from \"..\";\n\n/**\n * DisTube Plugin\n */\nexport abstract class Plugin {\n /**\n * Type of the plugin\n */\n abstract readonly type: PluginType;\n /**\n * DisTube\n */\n distube!: DisTube;\n init(distube: DisTube) {\n this.distube = distube;\n }\n /**\n * Get related songs from a supported url.\n * @param song - Input song\n */\n abstract getRelatedSongs(song: Song): Awaitable<Song[]>;\n}\n","import { Plugin } from \".\";\nimport { PluginType } from \"..\";\nimport type { Awaitable, Playlist, ResolveOptions, Song } from \"..\";\n\n/**\n * This plugin can extract the info, search, and play a song directly from its source\n */\nexport abstract class ExtractorPlugin extends Plugin {\n readonly type = PluginType.EXTRACTOR;\n /**\n * Check if the url is working with this plugin\n * @param url - Input url\n */\n abstract validate(url: string): Awaitable<boolean>;\n /**\n * Resolve the validated url to a {@link Song} or a {@link Playlist}.\n * @param url - URL\n * @param options - Optional options\n */\n abstract resolve<T>(url: string, options: ResolveOptions<T>): Awaitable<Song<T> | Playlist<T>>;\n /**\n * Search for a Song which playable from this plugin's source\n * @param query - Search query\n * @param options - Optional options\n */\n abstract searchSong<T>(query: string, options: ResolveOptions<T>): Awaitable<Song<T> | null>;\n /**\n * Get the stream url from {@link Song#url}. Returns {@link Song#url} by default.\n * Not needed if the plugin plays song from YouTube.\n * @param song - Input song\n */\n abstract getStreamURL<T>(song: Song<T>): Awaitable<string>;\n}\n","import { Plugin } from \".\";\nimport { PluginType } from \"..\";\nimport type { Awaitable, Playlist, ResolveOptions, Song } from \"..\";\n\n/**\n * This plugin only can extract the info from supported links, but not play song directly from its source\n */\nexport abstract class InfoExtractorPlugin extends Plugin {\n readonly type = PluginType.INFO_EXTRACTOR;\n /**\n * Check if the url is working with this plugin\n * @param url - Input url\n */\n abstract validate(url: string): Awaitable<boolean>;\n /**\n * Resolve the validated url to a {@link Song} or a {@link Playlist}.\n * @param url - URL\n * @param options - Optional options\n */\n abstract resolve<T>(url: string, options: ResolveOptions<T>): Awaitable<Song<T> | Playlist<T>>;\n\n /**\n * Create a search query to be used in {@link ExtractorPlugin#searchSong}\n * @param song - Input song\n */\n abstract createSearchQuery<T>(song: Song<T>): Awaitable<string>;\n}\n","import { Plugin } from \".\";\nimport { PluginType } from \"..\";\nimport type { Awaitable, Playlist, ResolveOptions, Song } from \"..\";\n\n/**\n * This plugin can extract and play song from supported links, but cannot search for songs from its source\n */\nexport abstract class PlayableExtractorPlugin extends Plugin {\n readonly type = PluginType.PLAYABLE_EXTRACTOR;\n /**\n * Check if the url is working with this plugin\n * @param url - Input url\n */\n abstract validate(url: string): Awaitable<boolean>;\n /**\n * Resolve the validated url to a {@link Song} or a {@link Playlist}.\n * @param url - URL\n * @param options - Optional options\n */\n abstract resolve<T>(url: string, options: ResolveOptions<T>): Awaitable<Song<T> | Playlist<T>>;\n /**\n * Get the stream url from {@link Song#url}. Returns {@link Song#url} by default.\n * Not needed if the plugin plays song from YouTube.\n * @param song - Input song\n */\n abstract getStreamURL<T>(song: Song<T>): Awaitable<string>;\n}\n","import { URL } from \"url\";\nimport { DisTubeError, DisTubeVoice, Queue } from \".\";\nimport { Constants, GatewayIntentBits, IntentsBitField, SnowflakeUtil } from \"discord.js\";\nimport type { GuildIdResolvable } from \".\";\nimport type {\n Client,\n ClientOptions,\n Guild,\n GuildMember,\n GuildTextBasedChannel,\n Message,\n Snowflake,\n VoiceBasedChannel,\n VoiceState,\n} from \"discord.js\";\n\nconst formatInt = (int: number) => (int < 10 ? `0${int}` : int);\n\n/**\n * Format duration to string\n * @param sec - Duration in seconds\n */\nexport function formatDuration(sec: number): string {\n if (!sec || !Number(sec)) return \"00:00\";\n const seconds = Math.floor(sec % 60);\n const minutes = Math.floor((sec % 3600) / 60);\n const hours = Math.floor(sec / 3600);\n if (hours > 0) return `${formatInt(hours)}:${formatInt(minutes)}:${formatInt(seconds)}`;\n if (minutes > 0) return `${formatInt(minutes)}:${formatInt(seconds)}`;\n return `00:${formatInt(seconds)}`;\n}\nconst SUPPORTED_PROTOCOL = [\"https:\", \"http:\", \"file:\"] as const;\n/**\n * Check if the string is an URL\n * @param input - input\n */\nexport function isURL(input: any): input is `${(typeof SUPPORTED_PROTOCOL)[number]}//${string}` {\n if (typeof input !== \"string\" || input.includes(\" \")) return false;\n try {\n const url = new URL(input);\n if (!SUPPORTED_PROTOCOL.some(p => p === url.protocol)) return false;\n } catch {\n return false;\n }\n return true;\n}\n/**\n * Check if the Client has enough intents to using DisTube\n * @param options - options\n */\nexport function checkIntents(options: ClientOptions): void {\n const intents = options.intents instanceof IntentsBitField ? options.intents : new IntentsBitField(options.intents);\n if (!intents.has(GatewayIntentBits.GuildVoiceStates)) throw new DisTubeError(\"MISSING_INTENTS\", \"GuildVoiceStates\");\n}\n\n/**\n * Check if the voice channel is empty\n * @param voiceState - voiceState\n */\nexport function isVoiceChannelEmpty(voiceState: VoiceState): boolean {\n const guild = voiceState.guild;\n const clientId = voiceState.client.user?.id;\n if (!guild || !clientId) return false;\n const voiceChannel = guild.members.me?.voice?.channel;\n if (!voiceChannel) return false;\n const members = voiceChannel.members.filter(m => !m.user.bot);\n return !members.size;\n}\n\nexport function isSnowflake(id: any): id is Snowflake {\n try {\n return SnowflakeUtil.deconstruct(id).timestamp > SnowflakeUtil.epoch;\n } catch {\n return false;\n }\n}\n\nexport function isMemberInstance(member: any): member is GuildMember {\n return (\n Boolean(member) &&\n isSnowflake(member.id) &&\n isSnowflake(member.guild?.id) &&\n isSnowflake(member.user?.id) &&\n member.id === member.user.id\n );\n}\n\nexport function isTextChannelInstance(channel: any): channel is GuildTextBasedChannel {\n return (\n Boolean(channel) &&\n isSnowflake(channel.id) &&\n isSnowflake(channel.guildId || channel.guild?.id) &&\n Constants.TextBasedChannelTypes.includes(channel.type) &&\n typeof channel.send === \"function\" &&\n (typeof channel.nsfw === \"boolean\" || typeof channel.parent?.nsfw === \"boolean\")\n );\n}\n\nexport function isMessageInstance(message: any): message is Message<true> {\n // Simple check for using distube normally\n return (\n Boolean(message) &&\n isSnowflake(message.id) &&\n isSnowflake(message.guildId || message.guild?.id) &&\n isMemberInstance(message.member) &&\n isTextChannelInstance(message.channel) &&\n Constants.NonSystemMessageTypes.includes(message.type) &&\n message.member.id === message.author?.id\n );\n}\n\nexport function isSupportedVoiceChannel(channel: any): channel is VoiceBasedChannel {\n return (\n Boolean(channel) &&\n isSnowflake(channel.id) &&\n isSnowflake(channel.guildId || channel.guild?.id) &&\n Constants.VoiceBasedChannelTypes.includes(channel.type)\n );\n}\n\nexport function isGuildInstance(guild: any): guild is Guild {\n return Boolean(guild) && isSnowflake(guild.id) && isSnowflake(guild.ownerId) && typeof guild.name === \"string\";\n}\n\nexport function resolveGuildId(resolvable: GuildIdResolvable): Snowflake {\n let guildId: string | undefined;\n if (typeof resolvable === \"string\") {\n guildId = resolvable;\n } else if (isObject(resolvable)) {\n if (\"guildId\" in resolvable && resolvable.guildId) {\n guildId = resolvable.guildId;\n } else if (resolvable instanceof Queue || resolvable instanceof DisTubeVoice || isGuildInstance(resolvable)) {\n guildId = resolvable.id;\n } else if (\"guild\" in resolvable && isGuildInstance(resolvable.guild)) {\n guildId = resolvable.guild.id;\n }\n }\n if (!isSnowflake(guildId)) throw new DisTubeError(\"INVALID_TYPE\", \"GuildIdResolvable\", resolvable);\n return guildId;\n}\n\nexport function isClientInstance(client: any): client is Client {\n return Boolean(client) && typeof client.login === \"function\";\n}\n\nexport function checkInvalidKey(\n target: Record<string, any>,\n source: Record<string, any> | string[],\n sourceName: string,\n) {\n if (!isObject(target)) throw new DisTubeError(\"INVALID_TYPE\", \"object\", target, sourceName);\n const sourceKeys = Array.isArray(source) ? source : objectKeys(source);\n const invalidKey = objectKeys(target).find(key => !sourceKeys.includes(key));\n if (invalidKey) throw new DisTubeError(\"INVALID_KEY\", sourceName, invalidKey);\n}\n\nexport function isObject(obj: any): obj is object {\n return typeof obj === \"object\" && obj !== null && !Array.isArray(obj);\n}\n\nexport type KeyOf<T> = T extends object ? (keyof T)[] : [];\nexport function objectKeys<T>(obj: T): KeyOf<T> {\n if (!isObject(obj)) return [] as KeyOf<T>;\n return Object.keys(obj) as KeyOf<T>;\n}\n\nexport function isNsfwChannel(channel?: GuildTextBasedChannel): boolean {\n if (!isTextChannelInstance(channel)) return false;\n if (channel.isThread()) return channel.parent?.nsfw ?? false;\n return channel.nsfw;\n}\n\nexport type Falsy = undefined | null | false | 0 | \"\";\nexport const isTruthy = <T>(x: T | Falsy): x is T => Boolean(x);\n","import { TypedEmitter } from \"tiny-typed-emitter\";\nimport {\n DisTubeError,\n DisTubeHandler,\n DisTubeVoiceManager,\n Events,\n Options,\n Playlist,\n QueueManager,\n Song,\n checkIntents,\n defaultFilters,\n isClientInstance,\n isMemberInstance,\n isMessageInstance,\n isNsfwChannel,\n isObject,\n isSupportedVoiceChannel,\n isTextChannelInstance,\n isURL,\n} from \".\";\nimport type { Client, VoiceBasedChannel } from \"discord.js\";\nimport type {\n Awaitable,\n CustomPlaylistOptions,\n DisTubeOptions,\n DisTubePlugin,\n Filters,\n GuildIdResolvable,\n PlayOptions,\n Queue,\n RepeatMode,\n TypedDisTubeEvents,\n} from \".\";\n\n// Cannot be `import` as it's not under TS root dir\n// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports\nexport const { version }: { version: string } = require(\"../package.json\");\n\n/**\n * DisTube class\n */\nexport class DisTube extends TypedEmitter<TypedDisTubeEvents> {\n /**\n * @event\n * Emitted after DisTube add a new playlist to the playing {@link Queue}.\n * @param queue - The guild queue\n * @param playlist - Playlist info\n */\n static readonly [Events.ADD_LIST]: (queue: Queue, playlist: Playlist) => Awaitable;\n /**\n * @event\n * Emitted after DisTube add a new song to the playing {@link Queue}.\n * @param queue - The guild queue\n * @param song - Added song\n */\n static readonly [Events.ADD_SONG]: (queue: Queue, song: Song) => Awaitable;\n /**\n * @event\n * Emitted when a {@link Queue} is deleted with any reasons.\n * @param queue - The guild queue\n */\n static readonly [Events.DELETE_QUEUE]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when the bot is disconnected to a voice channel.\n * @param queue - The guild queue\n */\n static readonly [Events.DISCONNECT]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when DisTube encounters an error while playing songs.\n * @param error - error\n * @param queue - The queue encountered the error\n * @param song - The playing song when encountered the error\n */\n static readonly [Events.ERROR]: (error: Error, queue: Queue, song?: Song) => Awaitable;\n /**\n * @event\n * Emitted for logging FFmpeg debug information.\n * @param debug - Debug message string.\n */\n static readonly [Events.FFMPEG_DEBUG]: (debug: string) => Awaitable;\n /**\n * @event\n * Emitted to provide debug information from DisTube's operation.\n * Useful for troubleshooting or logging purposes.\n *\n * @param debug - Debug message string.\n */\n static readonly [Events.DEBUG]: (debug: string) => Awaitable;\n /**\n * @event\n * Emitted when there is no more song in the queue and {@link Queue#autoplay} is `false`.\n * @param queue - The guild queue\n */\n static readonly [Events.FINISH]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when DisTube finished a song.\n * @param queue - The guild queue\n * @param song - Finished song\n */\n static readonly [Events.FINISH_SONG]: (queue: Queue, song: Song) => Awaitable;\n /**\n * @event\n * Emitted when DisTube initialize a queue to change queue default properties.\n * @param queue - The guild queue\n */\n static readonly [Events.INIT_QUEUE]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when {@link Queue#autoplay} is `true`, {@link Queue#songs} is empty, and\n * DisTube cannot find related songs to play.\n * @param queue - The guild queue\n */\n static readonly [Events.NO_RELATED]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when DisTube play a song.\n * If {@link DisTubeOptions}.emitNewSongOnly is `true`, this event is not emitted\n * when looping a song or next song is the previous one.\n * @param queue - The guild queue\n * @param song - Playing song\n */\n static readonly [Events.PLAY_SONG]: (queue: Queue, song: Song) => Awaitable;\n /**\n * DisTube internal handler\n */\n readonly handler: DisTubeHandler;\n /**\n * DisTube options\n */\n readonly options: Options;\n /**\n * Discord.js v14 client\n */\n readonly client: Client;\n /**\n * Queues manager\n */\n readonly queues: QueueManager;\n /**\n * DisTube voice connections manager\n */\n readonly voices: DisTubeVoiceManager;\n /**\n * DisTube plugins\n */\n readonly plugins: DisTubePlugin[];\n /**\n * DisTube ffmpeg audio filters\n */\n readonly filters: Filters;\n /**\n * Create a new DisTube class.\n * @throws {@link DisTubeError}\n * @param client - Discord.JS client\n * @param opts - Custom DisTube options\n */\n constructor(client: Client, opts: DisTubeOptions = {}) {\n super();\n this.setMaxListeners(1);\n if (!isClientInstance(client)) throw new DisTubeError(\"INVALID_TYPE\", \"Discord.Client\", client, \"client\");\n this.client = client;\n checkIntents(client.options);\n this.options = new Options(opts);\n this.voices = new DisTubeVoiceManager(this);\n this.handler = new DisTubeHandler(this);\n this.queues = new QueueManager(this);\n this.filters = { ...defaultFilters, ...this.options.customFilters };\n this.plugins = [...this.options.plugins];\n this.plugins.forEach(p => p.init(this));\n }\n\n static get version() {\n return version;\n }\n\n /**\n * DisTube version\n */\n get version() {\n return version;\n }\n\n /**\n * Play / add a song or playlist from url.\n * Search and play a song (with {@link ExtractorPlugin}) if it is not a valid url.\n * @throws {@link DisTubeError}\n * @param voiceChannel - The channel will be joined if the bot isn't in any channels, the bot will be\n * moved to this channel if {@link DisTubeOptions}.joinNewVoiceChannel is `true`\n * @param song - URL | Search string | {@link Song} | {@link Playlist}\n * @param options - Optional options\n */\n async play<T = unknown>(\n voiceChannel: VoiceBasedChannel,\n song: string | Song | Playlist,\n options: PlayOptions<T> = {},\n ): Promise<void> {\n if (!isSupportedVoiceChannel(voiceChannel)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"BaseGuildVoiceChannel\", voiceChannel, \"voiceChannel\");\n }\n if (!isObject(options)) throw new DisTubeError(\"INVALID_TYPE\", \"object\", options, \"options\");\n\n const { textChannel, member, skip, message, metadata } = {\n member: voiceChannel.guild.members.me ?? undefined,\n textChannel: options?.message?.channel,\n skip: false,\n ...options,\n };\n const position = Number(options.position) || (skip ? 1 : 0);\n\n if (message && !isMessageInstance(message)) {\n throw new DisTubeError(\"INVALID_TYPE\", [\"Discord.Message\", \"a falsy value\"], message, \"options.message\");\n }\n if (textChannel && !isTextChannelInstance(textChannel)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"Discord.GuildTextBasedChannel\", textChannel, \"options.textChannel\");\n }\n if (member && !isMemberInstance(member)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"Discord.GuildMember\", member, \"options.member\");\n }\n\n const queue = this.getQueue(voiceChannel) || (await this.queues.create(voiceChannel, textChannel));\n await queue._taskQueue.queuing();\n try {\n this.debug(`[${queue.id}] Playing input: ${song}`);\n const resolved = await this.handler.resolve(song, { member, metadata });\n const isNsfw = isNsfwChannel(queue?.textChannel || textChannel);\n if (resolved instanceof Playlist) {\n if (!this.options.nsfw && !isNsfw) {\n resolved.songs = resolved.songs.filter(s => !s.ageRestricted);\n if (!resolved.songs.length) throw new DisTubeError(\"EMPTY_FILTERED_PLAYLIST\");\n }\n if (!resolved.songs.length) throw new DisTubeError(\"EMPTY_PLAYLIST\");\n this.debug(`[${queue.id}] Adding playlist to queue: ${resolved.songs.length} songs`);\n queue.addToQueue(resolved.songs, position);\n if (queue.playing || this.options.emitAddListWhenCreatingQueue) this.emit(Events.ADD_LIST, queue, resolved);\n } else {\n if (!this.options.nsfw && resolved.ageRestricted && !isNsfwChannel(queue?.textChannel || textChannel)) {\n throw new DisTubeError(\"NON_NSFW\");\n }\n this.debug(`[${queue.id}] Adding song to queue: ${resolved.name || resolved.url || resolved.id || resolved}`);\n queue.addToQueue(resolved, position);\n if (queue.playing || this.options.emitAddSongWhenCreatingQueue) this.emit(Events.ADD_SONG, queue, resolved);\n }\n\n if (!queue.playing) await queue.play();\n } catch (e: any) {\n if (!(e instanceof DisTubeError)) {\n this.debug(`[${queue.id}] Unexpected error while playing song: ${e.stack || e.message}`);\n try {\n e.name = \"PlayError\";\n e.message = `${typeof song === \"string\" ? song : song.url}\\n${e.message}`;\n } catch {\n // Throw original error\n }\n }\n throw e;\n } finally {\n queue._taskQueue.resolve();\n }\n }\n\n /**\n * Create a custom playlist\n * @param songs - Array of url or Song\n * @param options - Optional options\n */\n async createCustomPlaylist(\n songs: (string | Song)[],\n { member, parallel, metadata, name, source, url, thumbnail }: CustomPlaylistOptions = {},\n ): Promise<Playlist> {\n if (!Array.isArray(songs)) throw new DisTubeError(\"INVALID_TYPE\", \"Array\", songs, \"songs\");\n if (!songs.length) throw new DisTubeError(\"EMPTY_ARRAY\", \"songs\");\n const filteredSongs = songs.filter(song => song instanceof Song || isURL(song));\n if (!filteredSongs.length) throw new DisTubeError(\"NO_VALID_SONG\");\n if (member && !isMemberInstance(member)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"Discord.Member\", member, \"options.member\");\n }\n let resolvedSongs: Song[];\n if (parallel !== false) {\n const promises = filteredSongs.map((song: string | Song) =>\n this.handler.resolve(song, { member, metadata }).catch(() => undefined),\n );\n resolvedSongs = (await Promise.all(promises)).filter((s): s is Song => s instanceof Song);\n } else {\n resolvedSongs = [];\n for (const song of filteredSongs) {\n const resolved = await this.handler.resolve(song, { member, metadata }).catch(() => undefined);\n if (resolved instanceof Song) resolvedSongs.push(resolved);\n }\n }\n return new Playlist(\n {\n source: source || \"custom\",\n name,\n url,\n thumbnail: thumbnail || resolvedSongs.find(s => s.thumbnail)?.thumbnail,\n songs: resolvedSongs,\n },\n { member, metadata },\n );\n }\n\n /**\n * Get the guild queue\n * @param guild - The type can be resolved to give a {@link Queue}\n */\n getQueue(guild: GuildIdResolvable): Queue | undefined {\n return this.queues.get(guild);\n }\n\n #getQueue(guild: GuildIdResolvable): Queue {\n const queue = this.getQueue(guild);\n if (!queue) throw new DisTubeError(\"NO_QUEUE\");\n return queue;\n }\n\n /**\n * Pause the guild stream\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The guild queue\n */\n pause(guild: GuildIdResolvable): Queue {\n return this.#getQueue(guild).pause();\n }\n\n /**\n * Resume the guild stream\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The guild queue\n */\n resume(guild: GuildIdResolvable): Queue {\n return this.#getQueue(guild).resume();\n }\n\n /**\n * Stop the guild stream\n * @param guild - The type can be resolved to give a {@link Queue}\n */\n stop(guild: GuildIdResolvable): Promise<void> {\n return this.#getQueue(guild).stop();\n }\n\n /**\n * Set the guild stream's volume\n * @param guild - The type can be resolved to give a {@link Queue}\n * @param percent - The percentage of volume you want to set\n * @returns The guild queue\n */\n setVolume(guild: GuildIdResolvable, percent: number): Queue {\n return this.#getQueue(guild).setVolume(percent);\n }\n\n /**\n * Skip the playing song if there is a next song in the queue. <info>If {@link\n * Queue#autoplay} is `true` and there is no up next song, DisTube will add and\n * play a related song.</info>\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The new Song will be played\n */\n skip(guild: GuildIdResolvable): Promise<Song> {\n return this.#getQueue(guild).skip();\n }\n\n /**\n * Play the previous song\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The new Song will be played\n */\n previous(guild: GuildIdResolvable): Promise<Song> {\n return this.#getQueue(guild).previous();\n }\n\n /**\n * Shuffle the guild queue songs\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The guild queue\n */\n shuffle(guild: GuildIdResolvable): Promise<Queue> {\n return this.#getQueue(guild).shuffle();\n }\n\n /**\n * Jump to the song number in the queue. The next one is 1, 2,... The previous one\n * is -1, -2,...\n * @param guild - The type can be resolved to give a {@link Queue}\n * @param num - The song number to play\n * @returns The new Song will be played\n */\n jump(guild: GuildIdResolvable, num: number): Promise<Song> {\n return this.#getQueue(guild).jump(num);\n }\n\n /**\n * Set the repeat mode of the guild queue.\n * Toggle mode `(Disabled -> Song -> Queue -> Disabled ->...)` if `mode` is `undefined`\n * @param guild - The type can be resolved to give a {@link Queue}\n * @param mode - The repeat modes (toggle if `undefined`)\n * @returns The new repeat mode\n */\n setRepeatMode(guild: GuildIdResolvable, mode?: RepeatMode): RepeatMode {\n return this.#getQueue(guild).setRepeatMode(mode);\n }\n\n /**\n * Toggle autoplay mode\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns Autoplay mode state\n */\n toggleAutoplay(guild: GuildIdResolvable): boolean {\n const queue = this.#getQueue(guild);\n queue.autoplay = !queue.autoplay;\n return queue.autoplay;\n }\n\n /**\n * Add related song to the queue\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The guild queue\n */\n addRelatedSong(guild: GuildIdResolvable): Promise<Song> {\n return this.#getQueue(guild).addRelatedSong();\n }\n\n /**\n * Set the playing time to another position\n * @param guild - The type can be resolved to give a {@link Queue}\n * @param time - Time in seconds\n * @returns Seeked queue\n */\n seek(guild: GuildIdResolvable, time: number): Queue {\n return this.#getQueue(guild).seek(time);\n }\n\n /**\n * Emit error event\n * @param error - error\n * @param queue - The queue encountered the error\n * @param song - The playing song when encountered the error\n */\n emitError(error: Error, queue: Queue, song?: Song): void {\n this.emit(Events.ERROR, error, queue, song);\n }\n\n /**\n * Emit debug event\n * @param message - debug message\n */\n debug(message: string) {\n this.emit(Events.DEBUG, message);\n }\n}\n\nexport default DisTube;\n"],"mappings":"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","names":["exports","module","Events","RepeatMode","PluginType","_metadata","_member","import_tiny_typed_emitter","import_voice","process","version","import_discord","import_voice","import_discord","import_tiny_typed_emitter"]}
1
+ {"version":3,"sources":["../package.json","../src/index.ts","../src/type.ts","../src/constant.ts","../src/struct/DisTubeError.ts","../src/struct/TaskQueue.ts","../src/struct/Playlist.ts","../src/struct/Song.ts","../src/core/DisTubeBase.ts","../src/core/DisTubeVoice.ts","../src/core/DisTubeStream.ts","../src/core/DisTubeHandler.ts","../src/core/DisTubeOptions.ts","../src/core/manager/BaseManager.ts","../src/core/manager/GuildIdManager.ts","../src/core/manager/DisTubeVoiceManager.ts","../src/core/manager/FilterManager.ts","../src/core/manager/QueueManager.ts","../src/struct/Queue.ts","../src/struct/Plugin.ts","../src/struct/ExtractorPlugin.ts","../src/struct/InfoExtratorPlugin.ts","../src/struct/PlayableExtratorPlugin.ts","../src/util.ts","../src/DisTube.ts"],"sourcesContent":["{\n \"name\": \"distube\",\n \"version\": \"5.0.2\",\n \"description\": \"A powerful Discord.js module for simplifying music commands and effortless playback of various sources with integrated audio filters.\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": \"./dist/index.js\",\n \"directories\": {\n \"lib\": \"src\",\n \"test\": \"tests\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"test\": \"VITE_CJS_IGNORE_WARNING=true vitest run\",\n \"docs\": \"typedoc\",\n \"lint\": \"prettier --check . && eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n \"prettier\": \"prettier --write \\\"**/*.{ts,json,yml,yaml,md}\\\"\",\n \"build\": \"tsup\",\n \"type\": \"tsc --noEmit\",\n \"update\": \"pnpm up -L \\\"!eslint\\\"\",\n \"prepare\": \"husky\",\n \"prepublishOnly\": \"pnpm run lint && pnpm run test\",\n \"prepack\": \"pnpm run build\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/skick1234/DisTube.git\"\n },\n \"keywords\": [\n \"youtube\",\n \"music\",\n \"discord\",\n \"discordjs\",\n \"bot\",\n \"distube\",\n \"queue\",\n \"musicbot\",\n \"discord-music-bot\",\n \"music-bot\",\n \"discord-js\"\n ],\n \"author\": \"Skick (https://github.com/skick1234)\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/skick1234/DisTube/issues\"\n },\n \"funding\": \"https://github.com/skick1234/DisTube?sponsor\",\n \"homepage\": \"https://distube.js.org/\",\n \"dependencies\": {\n \"tiny-typed-emitter\": \"^2.1.0\",\n \"undici\": \"^6.18.2\"\n },\n \"devDependencies\": {\n \"@commitlint/cli\": \"^19.3.0\",\n \"@commitlint/config-conventional\": \"^19.2.2\",\n \"@discordjs/voice\": \"^0.17.0\",\n \"@types/node\": \"^20.14.2\",\n \"@types/tough-cookie\": \"^4.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^7.13.0\",\n \"@typescript-eslint/parser\": \"^7.13.0\",\n \"@vitest/coverage-v8\": \"^1.6.0\",\n \"discord.js\": \"^14.15.3\",\n \"eslint\": \"^8.57.0\",\n \"eslint-config-distube\": \"^1.7.0\",\n \"husky\": \"^9.0.11\",\n \"nano-staged\": \"^0.8.0\",\n \"prettier\": \"^3.3.2\",\n \"sodium-native\": \"^4.1.1\",\n \"ts-node\": \"^10.9.2\",\n \"tsup\": \"^8.1.0\",\n \"typedoc\": \"^0.25.13\",\n \"typedoc-material-theme\": \"^1.0.2\",\n \"typedoc-plugin-extras\": \"^3.0.0\",\n \"typescript\": \"^5.4.5\",\n \"vite-tsconfig-paths\": \"^4.3.2\",\n \"vitest\": \"^1.6.0\"\n },\n \"peerDependencies\": {\n \"@discordjs/voice\": \"*\",\n \"discord.js\": \"14\"\n },\n \"nano-staged\": {\n \"*.ts\": [\n \"prettier --write\",\n \"eslint\"\n ],\n \"*.{json,yml,yaml,md}\": [\n \"prettier --write\"\n ]\n },\n \"engines\": {\n \"node\": \">=18.17\"\n }\n}\n","export * from \"./type\";\nexport * from \"./constant\";\nexport * from \"./struct\";\nexport * from \"./util\";\nexport * from \"./core\";\nexport { DisTube, DisTube as default, version } from \"./DisTube\";\n","import type {\n DisTubeError,\n DisTubeVoice,\n ExtractorPlugin,\n InfoExtractorPlugin,\n PlayableExtractorPlugin,\n Playlist,\n Queue,\n Song,\n} from \".\";\nimport type {\n Guild,\n GuildMember,\n GuildTextBasedChannel,\n Interaction,\n Message,\n Snowflake,\n VoiceBasedChannel,\n VoiceState,\n} from \"discord.js\";\n\nexport type Awaitable<T = any> = T | PromiseLike<T>;\n\nexport enum Events {\n ERROR = \"error\",\n ADD_LIST = \"addList\",\n ADD_SONG = \"addSong\",\n PLAY_SONG = \"playSong\",\n FINISH_SONG = \"finishSong\",\n EMPTY = \"empty\",\n FINISH = \"finish\",\n INIT_QUEUE = \"initQueue\",\n NO_RELATED = \"noRelated\",\n DISCONNECT = \"disconnect\",\n DELETE_QUEUE = \"deleteQueue\",\n FFMPEG_DEBUG = \"ffmpegDebug\",\n DEBUG = \"debug\",\n}\n\nexport type DisTubeEvents = {\n [Events.ADD_LIST]: [queue: Queue, playlist: Playlist];\n [Events.ADD_SONG]: [queue: Queue, song: Song];\n [Events.DELETE_QUEUE]: [queue: Queue];\n [Events.DISCONNECT]: [queue: Queue];\n [Events.ERROR]: [error: Error, queue: Queue, song: Song | undefined];\n [Events.FFMPEG_DEBUG]: [debug: string];\n [Events.DEBUG]: [debug: string];\n [Events.FINISH]: [queue: Queue];\n [Events.FINISH_SONG]: [queue: Queue, song: Song];\n [Events.INIT_QUEUE]: [queue: Queue];\n [Events.NO_RELATED]: [queue: Queue, error: DisTubeError];\n [Events.PLAY_SONG]: [queue: Queue, song: Song];\n};\n\nexport type TypedDisTubeEvents = {\n [K in keyof DisTubeEvents]: (...args: DisTubeEvents[K]) => Awaitable;\n};\n\nexport type DisTubeVoiceEvents = {\n disconnect: (error?: Error) => Awaitable;\n error: (error: Error) => Awaitable;\n finish: () => Awaitable;\n};\n\n/**\n * An FFmpeg audio filter object\n * ```ts\n * {\n * name: \"bassboost\",\n * value: \"bass=g=10\"\n * }\n * ```ts\n */\nexport interface Filter {\n /**\n * Name of the filter\n */\n name: string;\n /**\n * FFmpeg audio filter argument\n */\n value: string;\n}\n\n/**\n * Data that resolves to give an FFmpeg audio filter. This can be:\n * - A name of a default filters or custom filters (`string`)\n * - A {@link Filter} object\n * @see {@link defaultFilters}\n * @see {@link DisTubeOptions|DisTubeOptions.customFilters}\n */\nexport type FilterResolvable = string | Filter;\n\n/**\n * FFmpeg Filters\n * ```ts\n * {\n * \"Filter Name\": \"Filter Value\",\n * \"bassboost\": \"bass=g=10\"\n * }\n * ```\n * @see {@link defaultFilters}\n */\nexport type Filters = Record<string, string>;\n\n/**\n * DisTube options\n */\nexport type DisTubeOptions = {\n /**\n * DisTube plugins.\n * The order of this effects the priority of the plugins when verifying the input.\n */\n plugins?: DisTubePlugin[];\n /**\n * Whether or not emitting {@link Events.PLAY_SONG} event when looping a song\n * or next song is the same as the previous one\n */\n emitNewSongOnly?: boolean;\n /**\n * Whether or not saving the previous songs of the queue and enable {@link\n * DisTube#previous} method. Disable it may help to reduce the memory usage\n */\n savePreviousSongs?: boolean;\n /**\n * Override {@link defaultFilters} or add more ffmpeg filters\n */\n customFilters?: Filters;\n /**\n * Whether or not playing age-restricted content and disabling safe search in\n * non-NSFW channel\n */\n nsfw?: boolean;\n /**\n * Whether or not emitting `addSong` event when creating a new Queue\n */\n emitAddSongWhenCreatingQueue?: boolean;\n /**\n * Whether or not emitting `addList` event when creating a new Queue\n */\n emitAddListWhenCreatingQueue?: boolean;\n /**\n * Whether or not joining the new voice channel when using {@link DisTube#play}\n * method\n */\n joinNewVoiceChannel?: boolean;\n /**\n * FFmpeg options\n */\n ffmpeg?: {\n /**\n * FFmpeg path\n */\n path?: string;\n /**\n * FFmpeg default arguments\n */\n args?: Partial<FFmpegArgs>;\n };\n};\n\n/**\n * Data that can be resolved to give a guild id string. This can be:\n * - A guild id string | a guild {@link https://discord.js.org/#/docs/main/stable/class/Snowflake|Snowflake}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/Guild | Guild}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/Message | Message}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/BaseGuildVoiceChannel\n * | BaseGuildVoiceChannel}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/BaseGuildTextChannel\n * | BaseGuildTextChannel}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/VoiceState |\n * VoiceState}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/GuildMember |\n * GuildMember}\n * - A {@link https://discord.js.org/#/docs/main/stable/class/Interaction |\n * Interaction}\n * - A {@link DisTubeVoice}\n * - A {@link Queue}\n */\nexport type GuildIdResolvable =\n | Queue\n | DisTubeVoice\n | Snowflake\n | Message\n | GuildTextBasedChannel\n | VoiceBasedChannel\n | VoiceState\n | Guild\n | GuildMember\n | Interaction\n | string;\n\nexport interface SongInfo {\n plugin: DisTubePlugin | null;\n source: string;\n playFromSource: boolean;\n id: string;\n name?: string;\n isLive?: boolean;\n duration?: number;\n url?: string;\n thumbnail?: string;\n views?: number;\n likes?: number;\n dislikes?: number;\n reposts?: number;\n uploader?: {\n name?: string;\n url?: string;\n };\n ageRestricted?: boolean;\n}\n\nexport interface PlaylistInfo {\n source: string;\n songs: Song[];\n id?: string;\n name?: string;\n url?: string;\n thumbnail?: string;\n}\n\nexport type RelatedSong = Omit<Song, \"related\">;\n\nexport type PlayHandlerOptions = {\n /**\n * [Default: false] Skip the playing song (if exists) and play the added playlist\n * instantly\n */\n skip?: boolean;\n /**\n * [Default: 0] Position of the song/playlist to add to the queue, \\<= 0 to add to\n * the end of the queue\n */\n position?: number;\n /**\n * The default text channel of the queue\n */\n textChannel?: GuildTextBasedChannel;\n};\n\nexport interface PlayOptions<T = unknown> extends PlayHandlerOptions, ResolveOptions<T> {\n /**\n * Called message (For built-in search events. If this is a {@link\n * https://developer.mozilla.org/en-US/docs/Glossary/Falsy | falsy value}, it will\n * play the first result instead)\n */\n message?: Message;\n}\n\nexport interface ResolveOptions<T = unknown> {\n /**\n * Requested user\n */\n member?: GuildMember;\n /**\n * Metadata\n */\n metadata?: T;\n}\n\nexport interface ResolvePlaylistOptions<T = unknown> extends ResolveOptions<T> {\n /**\n * Source of the playlist\n */\n source?: string;\n}\n\nexport interface CustomPlaylistOptions {\n /**\n * A guild member creating the playlist\n */\n member?: GuildMember;\n /**\n * Whether or not fetch the songs in parallel\n */\n parallel?: boolean;\n /**\n * Metadata\n */\n metadata?: any;\n /**\n * Playlist name\n */\n name?: string;\n /**\n * Playlist source\n */\n source?: string;\n /**\n * Playlist url\n */\n url?: string;\n /**\n * Playlist thumbnail\n */\n thumbnail?: string;\n}\n\n/**\n * The repeat mode of a {@link Queue}\n * - `DISABLED` = 0\n * - `SONG` = 1\n * - `QUEUE` = 2\n */\nexport enum RepeatMode {\n DISABLED,\n SONG,\n QUEUE,\n}\n\n/**\n * All available plugin types:\n * - `EXTRACTOR` = `\"extractor\"`: {@link ExtractorPlugin}\n * - `INFO_EXTRACTOR` = `\"info-extractor\"`: {@link InfoExtractorPlugin}\n * - `PLAYABLE_EXTRACTOR` = `\"playable-extractor\"`: {@link PlayableExtractorPlugin}\n */\nexport enum PluginType {\n EXTRACTOR = \"extractor\",\n INFO_EXTRACTOR = \"info-extractor\",\n PLAYABLE_EXTRACTOR = \"playable-extractor\",\n}\n\nexport type DisTubePlugin = ExtractorPlugin | InfoExtractorPlugin | PlayableExtractorPlugin;\n\nexport type FFmpegArg = Record<string, string | number | boolean | Array<string | null | undefined> | null | undefined>;\n\n/**\n * FFmpeg arguments for different use cases\n */\nexport type FFmpegArgs = {\n global: FFmpegArg;\n input: FFmpegArg;\n output: FFmpegArg;\n};\n\n/**\n * FFmpeg options\n */\nexport type FFmpegOptions = {\n /**\n * Path to the ffmpeg executable\n */\n path: string;\n /**\n * Arguments\n */\n args: FFmpegArgs;\n};\n","import type { DisTubeOptions, Filters } from \".\";\n\n/**\n * Default DisTube audio filters.\n */\nexport const defaultFilters: Filters = {\n \"3d\": \"apulsator=hz=0.125\",\n bassboost: \"bass=g=10\",\n echo: \"aecho=0.8:0.9:1000:0.3\",\n flanger: \"flanger\",\n gate: \"agate\",\n haas: \"haas\",\n karaoke: \"stereotools=mlev=0.1\",\n nightcore: \"asetrate=48000*1.25,aresample=48000,bass=g=5\",\n reverse: \"areverse\",\n vaporwave: \"asetrate=48000*0.8,aresample=48000,atempo=1.1\",\n mcompand: \"mcompand\",\n phaser: \"aphaser\",\n tremolo: \"tremolo\",\n surround: \"surround\",\n earwax: \"earwax\",\n};\n\nexport const defaultOptions = {\n plugins: [],\n emitNewSongOnly: false,\n savePreviousSongs: true,\n nsfw: false,\n emitAddSongWhenCreatingQueue: true,\n emitAddListWhenCreatingQueue: true,\n joinNewVoiceChannel: true,\n} satisfies DisTubeOptions;\n","import { inspect } from \"node:util\";\n\nconst ERROR_MESSAGES = {\n INVALID_TYPE: (expected: (number | string) | readonly (number | string)[], got: any, name?: string) =>\n `Expected ${\n Array.isArray(expected) ? expected.map(e => (typeof e === \"number\" ? e : `'${e}'`)).join(\" or \") : `'${expected}'`\n }${name ? ` for '${name}'` : \"\"}, but got ${inspect(got)} (${typeof got})`,\n NUMBER_COMPARE: (name: string, expected: string, value: number) => `'${name}' must be ${expected} ${value}`,\n EMPTY_ARRAY: (name: string) => `'${name}' is an empty array`,\n EMPTY_FILTERED_ARRAY: (name: string, type: string) => `There is no valid '${type}' in the '${name}' array`,\n EMPTY_STRING: (name: string) => `'${name}' string must not be empty`,\n INVALID_KEY: (obj: string, key: string) => `'${key}' does not need to be provided in ${obj}`,\n MISSING_KEY: (obj: string, key: string) => `'${key}' needs to be provided in ${obj}`,\n MISSING_KEYS: (obj: string, key: string[], all: boolean) =>\n `${key.map(k => `'${k}'`).join(all ? \" and \" : \" or \")} need to be provided in ${obj}`,\n\n MISSING_INTENTS: (i: string) => `${i} intent must be provided for the Client`,\n DISABLED_OPTION: (o: string) => `DisTubeOptions.${o} is disabled`,\n ENABLED_OPTION: (o: string) => `DisTubeOptions.${o} is enabled`,\n\n NOT_IN_VOICE: \"User is not in any voice channel\",\n VOICE_FULL: \"The voice channel is full\",\n VOICE_ALREADY_CREATED: \"This guild already has a voice connection which is not managed by DisTube\",\n VOICE_CONNECT_FAILED: (s: number) => `Cannot connect to the voice channel after ${s} seconds`,\n VOICE_MISSING_PERMS: \"I do not have permission to join this voice channel\",\n VOICE_RECONNECT_FAILED: \"Cannot reconnect to the voice channel\",\n VOICE_DIFFERENT_GUILD: \"Cannot join a voice channel in a different guild\",\n VOICE_DIFFERENT_CLIENT: \"Cannot join a voice channel created by a different client\",\n\n FFMPEG_EXITED: (code: number) => `ffmpeg exited with code ${code}`,\n FFMPEG_NOT_INSTALLED: (path: string) => `ffmpeg is not installed at '${path}' path`,\n\n NO_QUEUE: \"There is no playing queue in this guild\",\n QUEUE_EXIST: \"This guild has a Queue already\",\n QUEUE_STOPPED: \"The queue has been stopped already\",\n PAUSED: \"The queue has been paused already\",\n RESUMED: \"The queue has been playing already\",\n NO_PREVIOUS: \"There is no previous song in this queue\",\n NO_UP_NEXT: \"There is no up next song\",\n NO_SONG_POSITION: \"Does not have any song at this position\",\n NO_PLAYING_SONG: \"There is no playing song in the queue\",\n\n NO_RELATED: \"Cannot find any related songs\",\n CANNOT_PLAY_RELATED: \"Cannot play the related song\",\n UNAVAILABLE_VIDEO: \"This video is unavailable\",\n UNPLAYABLE_FORMATS: \"No playable format found\",\n NON_NSFW: \"Cannot play age-restricted content in non-NSFW channel\",\n NOT_SUPPORTED_URL: \"This url is not supported\",\n NOT_SUPPORTED_SONG: (song: string) => `There is no plugin supporting this song (${song})`,\n NO_VALID_SONG: \"'songs' array does not have any valid Song or url\",\n CANNOT_RESOLVE_SONG: (t: any) => `Cannot resolve ${inspect(t)} to a Song`,\n CANNOT_GET_STREAM_URL: (song: string) => `Cannot get stream url from this song (${song})`,\n CANNOT_GET_SEARCH_QUERY: (song: string) => `Cannot get search query from this song (${song})`,\n NO_RESULT: (query: string) => `Cannot get song stream from this query (${query})`,\n NO_STREAM_URL: (song: string) => `No stream url attached (${song})`,\n\n EMPTY_FILTERED_PLAYLIST:\n \"There is no valid video in the playlist\\n\" +\n \"Maybe age-restricted contents is filtered because you are in non-NSFW channel\",\n EMPTY_PLAYLIST: \"There is no valid video in the playlist\",\n};\n\ntype ErrorMessage = typeof ERROR_MESSAGES;\ntype ErrorCode = keyof ErrorMessage;\ntype StaticErrorCode = { [K in ErrorCode]-?: ErrorMessage[K] extends string ? K : never }[ErrorCode];\ntype TemplateErrorCode = Exclude<keyof typeof ERROR_MESSAGES, StaticErrorCode>;\n\nconst haveCode = (code: string): code is ErrorCode => Object.keys(ERROR_MESSAGES).includes(code);\nconst parseMessage = (m: string | ((...x: any) => string), ...args: any) => (typeof m === \"string\" ? m : m(...args));\nconst getErrorMessage = (code: string, ...args: any): string =>\n haveCode(code) ? parseMessage(ERROR_MESSAGES[code], ...args) : args[0];\nexport class DisTubeError<T extends string = any> extends Error {\n errorCode: string;\n constructor(code: T extends StaticErrorCode ? T : never);\n constructor(code: T extends TemplateErrorCode ? T : never, ...args: Parameters<ErrorMessage[typeof code]>);\n constructor(code: TemplateErrorCode, _: never);\n constructor(code: T extends ErrorCode ? never : T, message: string);\n constructor(code: string, ...args: any) {\n super(getErrorMessage(code, ...args));\n\n this.errorCode = code;\n if (Error.captureStackTrace) Error.captureStackTrace(this, DisTubeError);\n }\n\n override get name() {\n return `DisTubeError [${this.errorCode}]`;\n }\n\n get code() {\n return this.errorCode;\n }\n}\n","class Task {\n resolve!: () => void;\n promise: Promise<void>;\n constructor() {\n this.promise = new Promise<void>(res => {\n this.resolve = res;\n });\n }\n}\n\n/**\n * Task queuing system\n */\nexport class TaskQueue {\n /**\n * The task array\n */\n #tasks: Task[] = [];\n\n /**\n * Waits for last task finished and queues a new task\n */\n queuing(): Promise<void> {\n const next = this.remaining ? this.#tasks[this.#tasks.length - 1].promise : Promise.resolve();\n this.#tasks.push(new Task());\n return next;\n }\n\n /**\n * Removes the finished task and processes the next task\n */\n resolve(): void {\n this.#tasks.shift()?.resolve();\n }\n\n /**\n * The remaining number of tasks\n */\n get remaining(): number {\n return this.#tasks.length;\n }\n}\n","import { DisTubeError, formatDuration, isMemberInstance } from \"..\";\nimport type { GuildMember } from \"discord.js\";\nimport type { PlaylistInfo, ResolveOptions, Song } from \"..\";\n\n/**\n * Class representing a playlist.\n */\nexport class Playlist<T = unknown> implements PlaylistInfo {\n /**\n * Playlist source.\n */\n source: string;\n /**\n * Songs in the playlist.\n */\n songs: Song[];\n /**\n * Playlist ID.\n */\n id?: string;\n /**\n * Playlist name.\n */\n name?: string;\n /**\n * Playlist URL.\n */\n url?: string;\n /**\n * Playlist thumbnail.\n */\n thumbnail?: string;\n #metadata!: T;\n #member?: GuildMember;\n /**\n * Create a Playlist\n * @param playlist - Raw playlist info\n * @param options - Optional data\n */\n constructor(playlist: PlaylistInfo, { member, metadata }: ResolveOptions<T> = {}) {\n if (!Array.isArray(playlist.songs) || !playlist.songs.length) throw new DisTubeError(\"EMPTY_PLAYLIST\");\n\n this.source = playlist.source.toLowerCase();\n this.songs = playlist.songs;\n this.name = playlist.name;\n this.id = playlist.id;\n this.url = playlist.url;\n this.thumbnail = playlist.thumbnail;\n this.member = member;\n this.songs.forEach(s => (s.playlist = this));\n this.metadata = metadata as T;\n }\n\n /**\n * Playlist duration in second.\n */\n get duration() {\n return this.songs.reduce((prev, next) => prev + next.duration, 0);\n }\n\n /**\n * Formatted duration string `hh:mm:ss`.\n */\n get formattedDuration() {\n return formatDuration(this.duration);\n }\n\n /**\n * User requested.\n */\n get member() {\n return this.#member;\n }\n\n set member(member: GuildMember | undefined) {\n if (!isMemberInstance(member)) return;\n this.#member = member;\n this.songs.forEach(s => (s.member = this.member));\n }\n\n /**\n * User requested.\n */\n get user() {\n return this.member?.user;\n }\n\n /**\n * Optional metadata that can be used to identify the playlist.\n */\n get metadata() {\n return this.#metadata;\n }\n\n set metadata(metadata: T) {\n this.#metadata = metadata;\n this.songs.forEach(s => (s.metadata = metadata));\n }\n\n toString() {\n return `${this.name} (${this.songs.length} songs)`;\n }\n}\n","import { Playlist } from \".\";\nimport { DisTubeError, formatDuration, isMemberInstance } from \"..\";\nimport type { GuildMember } from \"discord.js\";\nimport type { DisTubePlugin, ResolveOptions, SongInfo } from \"..\";\n\n/**\n * Class representing a song.\n */\nexport class Song<T = unknown> {\n /**\n * The source of this song info\n */\n source: string;\n /**\n * Song ID.\n */\n id: string;\n /**\n * Song name.\n */\n name?: string;\n /**\n * Indicates if the song is an active live.\n */\n isLive?: boolean;\n /**\n * Song duration.\n */\n duration: number;\n /**\n * Formatted duration string (`hh:mm:ss`, `mm:ss` or `Live`).\n */\n formattedDuration: string;\n /**\n * Song URL.\n */\n url?: string;\n /**\n * Song thumbnail.\n */\n thumbnail?: string;\n /**\n * Song view count\n */\n views?: number;\n /**\n * Song like count\n */\n likes?: number;\n /**\n * Song dislike count\n */\n dislikes?: number;\n /**\n * Song repost (share) count\n */\n reposts?: number;\n /**\n * Song uploader\n */\n uploader: {\n name?: string;\n url?: string;\n };\n /**\n * Whether or not an age-restricted content\n */\n ageRestricted?: boolean;\n /**\n * Stream info\n */\n stream:\n | {\n /**\n * The stream of this song will be played from source\n */\n playFromSource: true;\n /**\n * Stream URL of this song\n */\n url?: string;\n }\n | {\n /**\n * The stream of this song will be played from another song\n */\n playFromSource: false;\n /**\n * The song that this song will be played from\n */\n song?: Song<T>;\n };\n /**\n * The plugin that created this song\n */\n plugin: DisTubePlugin | null;\n #metadata!: T;\n #member?: GuildMember;\n #playlist?: Playlist;\n /**\n * Create a Song\n *\n * @param info - Raw song info\n * @param options - Optional data\n */\n constructor(info: SongInfo, { member, metadata }: ResolveOptions<T> = {}) {\n this.source = info.source.toLowerCase();\n this.metadata = <T>metadata;\n this.member = member;\n this.id = info.id;\n this.name = info.name;\n this.isLive = info.isLive;\n this.duration = this.isLive || !info.duration ? 0 : info.duration;\n this.formattedDuration = this.isLive ? \"Live\" : formatDuration(this.duration);\n this.url = info.url;\n this.thumbnail = info.thumbnail;\n this.views = info.views;\n this.likes = info.likes;\n this.dislikes = info.dislikes;\n this.reposts = info.reposts;\n this.uploader = {\n name: info.uploader?.name,\n url: info.uploader?.url,\n };\n this.ageRestricted = info.ageRestricted;\n this.stream = { playFromSource: info.playFromSource };\n this.plugin = info.plugin;\n }\n\n /**\n * The playlist this song belongs to\n */\n get playlist() {\n return this.#playlist;\n }\n\n set playlist(playlist: Playlist | undefined) {\n if (!(playlist instanceof Playlist)) throw new DisTubeError(\"INVALID_TYPE\", \"Playlist\", playlist, \"Song#playlist\");\n this.#playlist = playlist;\n this.member = playlist.member;\n }\n\n /**\n * User requested to play this song.\n */\n get member() {\n return this.#member;\n }\n\n set member(member: GuildMember | undefined) {\n if (isMemberInstance(member)) this.#member = member;\n }\n\n /**\n * User requested to play this song.\n */\n get user() {\n return this.member?.user;\n }\n\n /**\n * Optional metadata that can be used to identify the song. This is attached by the\n * {@link DisTube#play} method.\n */\n get metadata() {\n return this.#metadata;\n }\n\n set metadata(metadata: T) {\n this.#metadata = metadata;\n }\n\n toString() {\n return this.name || this.url || this.id || \"Unknown\";\n }\n}\n","import type { Client } from \"discord.js\";\nimport type {\n DisTube,\n DisTubeEvents,\n DisTubeHandler,\n DisTubePlugin,\n DisTubeVoiceManager,\n Options,\n Queue,\n QueueManager,\n Song,\n} from \"..\";\n\nexport abstract class DisTubeBase {\n distube: DisTube;\n constructor(distube: DisTube) {\n /**\n * DisTube\n */\n this.distube = distube;\n }\n /**\n * Emit the {@link DisTube} of this base\n * @param eventName - Event name\n * @param args - arguments\n */\n emit(eventName: keyof DisTubeEvents, ...args: any): boolean {\n return this.distube.emit(eventName, ...args);\n }\n /**\n * Emit error event\n * @param error - error\n * @param queue - The queue encountered the error\n * @param song - The playing song when encountered the error\n */\n emitError(error: Error, queue: Queue, song?: Song) {\n this.distube.emitError(error, queue, song);\n }\n /**\n * Emit debug event\n * @param message - debug message\n */\n debug(message: string) {\n this.distube.debug(message);\n }\n /**\n * The queue manager\n */\n get queues(): QueueManager {\n return this.distube.queues;\n }\n /**\n * The voice manager\n */\n get voices(): DisTubeVoiceManager {\n return this.distube.voices;\n }\n /**\n * Discord.js client\n */\n get client(): Client {\n return this.distube.client;\n }\n /**\n * DisTube options\n */\n get options(): Options {\n return this.distube.options;\n }\n /**\n * DisTube handler\n */\n get handler(): DisTubeHandler {\n return this.distube.handler;\n }\n /**\n * DisTube plugins\n */\n get plugins(): DisTubePlugin[] {\n return this.distube.plugins;\n }\n}\n","import { Constants } from \"discord.js\";\nimport { TypedEmitter } from \"tiny-typed-emitter\";\nimport { DisTubeError, isSupportedVoiceChannel } from \"..\";\nimport {\n AudioPlayerStatus,\n VoiceConnectionDisconnectReason,\n VoiceConnectionStatus,\n createAudioPlayer,\n entersState,\n joinVoiceChannel,\n} from \"@discordjs/voice\";\nimport type { AudioPlayer, VoiceConnection } from \"@discordjs/voice\";\nimport type { Snowflake, VoiceBasedChannel, VoiceState } from \"discord.js\";\nimport type { DisTubeStream, DisTubeVoiceEvents, DisTubeVoiceManager } from \"..\";\n\n/**\n * Create a voice connection to the voice channel\n */\nexport class DisTubeVoice extends TypedEmitter<DisTubeVoiceEvents> {\n readonly id: Snowflake;\n readonly voices: DisTubeVoiceManager;\n readonly audioPlayer: AudioPlayer;\n connection!: VoiceConnection;\n emittedError!: boolean;\n isDisconnected = false;\n stream?: DisTubeStream;\n #channel!: VoiceBasedChannel;\n #volume = 100;\n constructor(voiceManager: DisTubeVoiceManager, channel: VoiceBasedChannel) {\n super();\n /**\n * The voice manager that instantiated this connection\n */\n this.voices = voiceManager;\n this.id = channel.guildId;\n this.channel = channel;\n this.voices.add(this.id, this);\n this.audioPlayer = createAudioPlayer()\n .on(AudioPlayerStatus.Idle, oldState => {\n if (oldState.status !== AudioPlayerStatus.Idle) this.emit(\"finish\");\n })\n .on(\"error\", (error: NodeJS.ErrnoException) => {\n if (this.emittedError) return;\n this.emittedError = true;\n this.emit(\"error\", error);\n });\n this.connection\n .on(VoiceConnectionStatus.Disconnected, (_, newState) => {\n if (newState.reason === VoiceConnectionDisconnectReason.Manual) {\n // User disconnect\n this.leave();\n } else if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {\n // Move to other channel\n entersState(this.connection, VoiceConnectionStatus.Connecting, 5e3).catch(() => {\n if (\n ![VoiceConnectionStatus.Ready, VoiceConnectionStatus.Connecting].includes(this.connection.state.status)\n ) {\n this.leave();\n }\n });\n } else if (this.connection.rejoinAttempts < 5) {\n // Try to rejoin\n setTimeout(\n () => {\n this.connection.rejoin();\n },\n (this.connection.rejoinAttempts + 1) * 5e3,\n ).unref();\n } else if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) {\n // Leave after 5 attempts\n this.leave(new DisTubeError(\"VOICE_RECONNECT_FAILED\"));\n }\n })\n .on(VoiceConnectionStatus.Destroyed, () => {\n this.leave();\n })\n .on(\"error\", () => undefined);\n this.connection.subscribe(this.audioPlayer);\n }\n /**\n * The voice channel id the bot is in\n */\n get channelId() {\n return this.connection?.joinConfig?.channelId ?? undefined;\n }\n get channel() {\n if (!this.channelId) return this.#channel;\n if (this.#channel?.id === this.channelId) return this.#channel;\n const channel = this.voices.client.channels.cache.get(this.channelId);\n if (!channel) return this.#channel;\n for (const type of Constants.VoiceBasedChannelTypes) {\n if (channel.type === type) {\n this.#channel = channel;\n return channel;\n }\n }\n return this.#channel;\n }\n set channel(channel: VoiceBasedChannel) {\n if (!isSupportedVoiceChannel(channel)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"BaseGuildVoiceChannel\", channel, \"DisTubeVoice#channel\");\n }\n if (channel.guildId !== this.id) throw new DisTubeError(\"VOICE_DIFFERENT_GUILD\");\n if (channel.client.user?.id !== this.voices.client.user?.id) throw new DisTubeError(\"VOICE_DIFFERENT_CLIENT\");\n if (channel.id === this.channelId) return;\n if (!channel.joinable) {\n if (channel.full) throw new DisTubeError(\"VOICE_FULL\");\n else throw new DisTubeError(\"VOICE_MISSING_PERMS\");\n }\n this.connection = this.#join(channel);\n this.#channel = channel;\n }\n #join(channel: VoiceBasedChannel) {\n return joinVoiceChannel({\n channelId: channel.id,\n guildId: this.id,\n adapterCreator: channel.guild.voiceAdapterCreator,\n group: channel.client.user?.id,\n });\n }\n /**\n * Join a voice channel with this connection\n * @param channel - A voice channel\n */\n async join(channel?: VoiceBasedChannel): Promise<DisTubeVoice> {\n const TIMEOUT = 30e3;\n if (channel) this.channel = channel;\n try {\n await entersState(this.connection, VoiceConnectionStatus.Ready, TIMEOUT);\n } catch {\n if (this.connection.state.status === VoiceConnectionStatus.Ready) return this;\n if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) this.connection.destroy();\n this.voices.remove(this.id);\n throw new DisTubeError(\"VOICE_CONNECT_FAILED\", TIMEOUT / 1e3);\n }\n return this;\n }\n /**\n * Leave the voice channel of this connection\n * @param error - Optional, an error to emit with 'error' event.\n */\n leave(error?: Error) {\n this.stop(true);\n if (!this.isDisconnected) {\n this.emit(\"disconnect\", error);\n this.isDisconnected = true;\n }\n if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) this.connection.destroy();\n this.voices.remove(this.id);\n }\n /**\n * Stop the playing stream\n * @param force - If true, will force the {@link DisTubeVoice#audioPlayer} to enter the Idle state even\n * if the {@link DisTubeStream#audioResource} has silence padding frames.\n */\n stop(force = false) {\n this.audioPlayer.stop(force);\n }\n /**\n * Play a {@link DisTubeStream}\n * @param dtStream - DisTubeStream\n */\n play(dtStream: DisTubeStream) {\n this.emittedError = false;\n dtStream.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (this.emittedError || error.code === \"ERR_STREAM_PREMATURE_CLOSE\") return;\n this.emittedError = true;\n this.emit(\"error\", error);\n });\n if (this.audioPlayer.state.status !== AudioPlayerStatus.Paused) this.audioPlayer.play(dtStream.audioResource);\n this.stream?.kill();\n this.stream = dtStream;\n this.volume = this.#volume;\n dtStream.spawn();\n }\n set volume(volume: number) {\n if (typeof volume !== \"number\" || isNaN(volume)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"number\", volume, \"volume\");\n }\n if (volume < 0) {\n throw new DisTubeError(\"NUMBER_COMPARE\", \"Volume\", \"bigger or equal to\", 0);\n }\n this.#volume = volume;\n this.stream?.setVolume(Math.pow(this.#volume / 100, 0.5 / Math.log10(2)));\n }\n /**\n * Get or set the volume percentage\n */\n get volume() {\n return this.#volume;\n }\n /**\n * Playback duration of the audio resource in seconds\n */\n get playbackDuration() {\n return (this.stream?.audioResource?.playbackDuration ?? 0) / 1000;\n }\n pause() {\n this.audioPlayer.pause();\n }\n unpause() {\n const state = this.audioPlayer.state;\n if (state.status !== AudioPlayerStatus.Paused) return;\n if (this.stream?.audioResource && state.resource !== this.stream.audioResource) {\n this.audioPlayer.play(this.stream.audioResource);\n } else {\n this.audioPlayer.unpause();\n }\n }\n /**\n * Whether the bot is self-deafened\n */\n get selfDeaf(): boolean {\n return this.connection.joinConfig.selfDeaf;\n }\n /**\n * Whether the bot is self-muted\n */\n get selfMute(): boolean {\n return this.connection.joinConfig.selfMute;\n }\n /**\n * Self-deafens/undeafens the bot.\n * @param selfDeaf - Whether or not the bot should be self-deafened\n * @returns true if the voice state was successfully updated, otherwise false\n */\n setSelfDeaf(selfDeaf: boolean): boolean {\n if (typeof selfDeaf !== \"boolean\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"boolean\", selfDeaf, \"selfDeaf\");\n }\n return this.connection.rejoin({\n ...this.connection.joinConfig,\n selfDeaf,\n });\n }\n /**\n * Self-mutes/unmutes the bot.\n * @param selfMute - Whether or not the bot should be self-muted\n * @returns true if the voice state was successfully updated, otherwise false\n */\n setSelfMute(selfMute: boolean): boolean {\n if (typeof selfMute !== \"boolean\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"boolean\", selfMute, \"selfMute\");\n }\n return this.connection.rejoin({\n ...this.connection.joinConfig,\n selfMute,\n });\n }\n /**\n * The voice state of this connection\n */\n get voiceState(): VoiceState | undefined {\n return this.channel?.guild?.members?.me?.voice;\n }\n}\n","import { Transform } from \"stream\";\nimport { DisTubeError, Events } from \"..\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { TypedEmitter } from \"tiny-typed-emitter\";\nimport { StreamType, createAudioResource } from \"@discordjs/voice\";\nimport type { TransformCallback } from \"stream\";\nimport type { ChildProcess } from \"child_process\";\nimport type { AudioResource } from \"@discordjs/voice\";\nimport type { Awaitable, DisTube, FFmpegArg, FFmpegOptions } from \"..\";\n\n/**\n * Options for {@link DisTubeStream}\n */\nexport interface StreamOptions {\n /**\n * FFmpeg options\n */\n ffmpeg: FFmpegOptions;\n /**\n * Seek time (in seconds).\n * @default 0\n */\n seek?: number;\n}\n\nlet checked = process.env.NODE_ENV === \"test\";\nexport const checkFFmpeg = (distube: DisTube) => {\n if (checked) return;\n const path = distube.options.ffmpeg.path;\n const debug = (str: string) => distube.emit(Events.FFMPEG_DEBUG, str);\n try {\n debug(`[test] spawn ffmpeg at '${path}' path`);\n const process = spawnSync(path, [\"-h\"], { windowsHide: true, shell: true, encoding: \"utf-8\" });\n if (process.error) throw process.error;\n if (process.stderr && !process.stdout) throw new Error(process.stderr);\n\n const result = process.output.join(\"\\n\");\n const version = /ffmpeg version (\\S+)/iu.exec(result)?.[1];\n if (!version) throw new Error(\"Invalid FFmpeg version\");\n debug(`[test] ffmpeg version: ${version}`);\n } catch (e: any) {\n debug(`[test] failed to spawn ffmpeg at '${path}': ${e?.stack ?? e}`);\n throw new DisTubeError(\"FFMPEG_NOT_INSTALLED\", path);\n }\n checked = true;\n};\n\n/**\n * Create a stream to play with {@link DisTubeVoice}\n */\nexport class DisTubeStream extends TypedEmitter<{\n debug: (debug: string) => Awaitable;\n error: (error: Error) => Awaitable;\n}> {\n #ffmpegPath: string;\n #opts: string[];\n process?: ChildProcess;\n stream: VolumeTransformer;\n audioResource: AudioResource;\n /**\n * Create a DisTubeStream to play with {@link DisTubeVoice}\n * @param url - Stream URL\n * @param options - Stream options\n */\n constructor(url: string, options: StreamOptions) {\n super();\n const { ffmpeg, seek } = options;\n const opts: FFmpegArg = {\n reconnect: 1,\n reconnect_streamed: 1,\n reconnect_delay_max: 5,\n analyzeduration: 0,\n hide_banner: true,\n ...ffmpeg.args.global,\n ...ffmpeg.args.input,\n i: url,\n ar: 48000,\n ac: 2,\n ...ffmpeg.args.output,\n f: \"s16le\",\n };\n\n if (typeof seek === \"number\" && seek > 0) opts.ss = seek.toString();\n\n const fileUrl = new URL(url);\n if (fileUrl.protocol === \"file:\") {\n opts.reconnect = null;\n opts.reconnect_streamed = null;\n opts.reconnect_delay_max = null;\n opts.i = fileUrl.hostname + fileUrl.pathname;\n }\n\n this.#ffmpegPath = ffmpeg.path;\n this.#opts = [\n ...Object.entries(opts)\n .flatMap(([key, value]) =>\n Array.isArray(value)\n ? value.filter(Boolean).map(v => [`-${key}`, String(v)])\n : value == null || value === false\n ? []\n : [value === true ? `-${key}` : [`-${key}`, String(value)]],\n )\n .flat(),\n \"pipe:1\",\n ];\n\n this.stream = new VolumeTransformer();\n this.stream\n .on(\"close\", () => this.kill())\n .on(\"error\", err => {\n this.debug(`[stream] error: ${err.message}`);\n this.emit(\"error\", err);\n })\n .on(\"finish\", () => this.debug(\"[stream] log: stream finished\"));\n\n this.audioResource = createAudioResource(this.stream, { inputType: StreamType.Raw, inlineVolume: false });\n }\n\n spawn() {\n this.debug(`[process] spawn: ${this.#ffmpegPath} ${this.#opts.join(\" \")}`);\n this.process = spawn(this.#ffmpegPath, this.#opts, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: false,\n windowsHide: true,\n })\n .on(\"error\", err => {\n this.debug(`[process] error: ${err.message}`);\n this.emit(\"error\", err);\n })\n .on(\"exit\", (code, signal) => {\n this.debug(`[process] exit: code=${code ?? \"unknown\"} signal=${signal ?? \"unknown\"}`);\n if (!code || [0, 255].includes(code)) return;\n this.debug(`[process] error: ffmpeg exited with code ${code}`);\n this.emit(\"error\", new DisTubeError(\"FFMPEG_EXITED\", code));\n });\n\n if (!this.process.stdout || !this.process.stderr) {\n this.kill();\n throw new Error(\"Failed to create ffmpeg process\");\n }\n\n this.process.stdout.pipe(this.stream);\n this.process.stderr.setEncoding(\"utf8\")?.on(\"data\", (data: string) => {\n const lines = data.split(/\\r\\n|\\r|\\n/u);\n for (const line of lines) {\n if (/^\\s*$/.test(line)) continue;\n this.debug(`[ffmpeg] log: ${line}`);\n }\n });\n }\n\n private debug(debug: string) {\n this.emit(\"debug\", debug);\n }\n\n setVolume(volume: number) {\n this.stream.vol = volume;\n }\n\n kill() {\n if (!this.stream.destroyed) this.stream.destroy();\n if (this.process && !this.process.killed) this.process.kill(\"SIGKILL\");\n }\n}\n\n// Based on prism-media\nclass VolumeTransformer extends Transform {\n private buffer = Buffer.allocUnsafe(0);\n private readonly extrema = [-Math.pow(2, 16 - 1), Math.pow(2, 16 - 1) - 1];\n vol = 1;\n\n override _transform(newChunk: Buffer, _encoding: BufferEncoding, done: TransformCallback): void {\n const { vol } = this;\n if (vol === 1) {\n this.push(newChunk);\n done();\n return;\n }\n\n const bytes = 2;\n const chunk = Buffer.concat([this.buffer, newChunk]);\n const readableLength = Math.floor(chunk.length / bytes) * bytes;\n\n for (let i = 0; i < readableLength; i += bytes) {\n const value = chunk.readInt16LE(i);\n const clampedValue = Math.min(this.extrema[1], Math.max(this.extrema[0], value * vol));\n chunk.writeInt16LE(clampedValue, i);\n }\n\n this.buffer = chunk.subarray(readableLength);\n this.push(chunk.subarray(0, readableLength));\n done();\n }\n}\n","import { DisTubeBase } from \".\";\nimport { request } from \"undici\";\nimport { DisTubeError, Playlist, PluginType, Song, isURL } from \"..\";\nimport type { DisTubePlugin, ResolveOptions } from \"..\";\n\nconst REDIRECT_CODES = new Set([301, 302, 303, 307, 308]);\n\n/**\n * DisTube's Handler\n */\nexport class DisTubeHandler extends DisTubeBase {\n resolve<T = unknown>(song: Song<T>, options?: Omit<ResolveOptions, \"metadata\">): Promise<Song<T>>;\n resolve<T = unknown>(song: Playlist<T>, options?: Omit<ResolveOptions, \"metadata\">): Promise<Playlist<T>>;\n resolve<T = unknown>(song: string, options?: ResolveOptions<T>): Promise<Song<T> | Playlist<T>>;\n resolve<T = unknown>(song: Song, options: ResolveOptions<T>): Promise<Song<T>>;\n resolve<T = unknown>(song: Playlist, options: ResolveOptions<T>): Promise<Playlist<T>>;\n resolve(song: string | Song | Playlist, options?: ResolveOptions): Promise<Song | Playlist>;\n /**\n * Resolve a url or a supported object to a {@link Song} or {@link Playlist}\n * @throws {@link DisTubeError}\n * @param input - Resolvable input\n * @param options - Optional options\n * @returns Resolved\n */\n async resolve(input: string | Song | Playlist, options: ResolveOptions = {}): Promise<Song | Playlist> {\n if (input instanceof Song || input instanceof Playlist) {\n if (\"metadata\" in options) input.metadata = options.metadata;\n if (\"member\" in options) input.member = options.member;\n return input;\n }\n if (typeof input === \"string\") {\n if (isURL(input)) {\n const plugin =\n (await this._getPluginFromURL(input)) || (await this._getPluginFromURL(await this.followRedirectLink(input)));\n if (!plugin) throw new DisTubeError(\"NOT_SUPPORTED_URL\");\n this.debug(`[${plugin.constructor.name}] Resolving from url: ${input}`);\n return plugin.resolve(input, options);\n }\n try {\n const song = await this.#searchSong(input, options);\n if (song) return song;\n } catch {\n // ignore\n }\n }\n throw new DisTubeError(\"CANNOT_RESOLVE_SONG\", input);\n }\n\n async _getPluginFromURL(url: string): Promise<DisTubePlugin | null> {\n for (const plugin of this.plugins) if (await plugin.validate(url)) return plugin;\n return null;\n }\n\n _getPluginFromSong(song: Song): Promise<DisTubePlugin | null>;\n _getPluginFromSong<T extends PluginType>(\n song: Song,\n types: T[],\n validate?: boolean,\n ): Promise<(DisTubePlugin & { type: T }) | null>;\n async _getPluginFromSong<T extends PluginType>(\n song: Song,\n types?: T[],\n validate = true,\n ): Promise<(DisTubePlugin & { type: T }) | null> {\n if (!types || types.includes(<T>song.plugin?.type)) return song.plugin as DisTubePlugin & { type: T };\n if (!song.url) return null;\n for (const plugin of this.plugins) {\n if ((!types || types.includes(<T>plugin?.type)) && (!validate || (await plugin.validate(song.url)))) {\n return plugin as DisTubePlugin & { type: T };\n }\n }\n return null;\n }\n\n async #searchSong(query: string, options: ResolveOptions = {}, getStreamURL = false): Promise<Song | null> {\n for (const plugin of this.plugins) {\n if (plugin.type === PluginType.EXTRACTOR) {\n this.debug(`[${plugin.constructor.name}] Searching for song: ${query}`);\n const result = await plugin.searchSong(query, options);\n if (result) {\n if (getStreamURL && result.stream.playFromSource) result.stream.url = await plugin.getStreamURL(result);\n return result;\n }\n }\n }\n return null;\n }\n\n /**\n * Get {@link Song}'s stream info and attach it to the song.\n * @param song - A Song\n */\n async attachStreamInfo(song: Song) {\n if (song.stream.playFromSource) {\n if (song.stream.url) return;\n this.debug(`[DisTubeHandler] Getting stream info: ${song}`);\n const plugin = await this._getPluginFromSong(song, [PluginType.EXTRACTOR, PluginType.PLAYABLE_EXTRACTOR]);\n if (!plugin) throw new DisTubeError(\"NOT_SUPPORTED_SONG\", song.toString());\n this.debug(`[${plugin.constructor.name}] Getting stream URL: ${song}`);\n song.stream.url = await plugin.getStreamURL(song);\n if (!song.stream.url) throw new DisTubeError(\"CANNOT_GET_STREAM_URL\", song.toString());\n } else {\n if (song.stream.song?.stream?.playFromSource && song.stream.song.stream.url) return;\n this.debug(`[DisTubeHandler] Getting stream info: ${song}`);\n const plugin = await this._getPluginFromSong(song, [PluginType.INFO_EXTRACTOR]);\n if (!plugin) throw new DisTubeError(\"NOT_SUPPORTED_SONG\", song.toString());\n this.debug(`[${plugin.constructor.name}] Creating search query for: ${song}`);\n const query = await plugin.createSearchQuery(song);\n if (!query) throw new DisTubeError(\"CANNOT_GET_SEARCH_QUERY\", song.toString());\n const altSong = await this.#searchSong(query, { metadata: song.metadata, member: song.member }, true);\n if (!altSong || !altSong.stream.playFromSource) throw new DisTubeError(\"NO_RESULT\", query || song.toString());\n song.stream.song = altSong;\n }\n }\n\n async followRedirectLink(url: string, maxRedirect = 5): Promise<string> {\n if (maxRedirect === 0) return url;\n\n const res = await request(url, {\n method: \"HEAD\",\n headers: {\n \"user-agent\":\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \" +\n \"Chrome/125.0.0.0 Safari/537.36\",\n },\n });\n\n if (REDIRECT_CODES.has(res.statusCode ?? 200)) {\n let location = res.headers.location;\n if (typeof location !== \"string\") location = location?.[0] ?? url;\n return this.followRedirectLink(location, --maxRedirect);\n }\n\n return url;\n }\n}\n","import { DisTubeError, checkInvalidKey, defaultOptions } from \"..\";\nimport type { DisTubeOptions, DisTubePlugin, FFmpegArgs, FFmpegOptions, Filters } from \"..\";\n\nexport class Options {\n plugins: DisTubePlugin[];\n emitNewSongOnly: boolean;\n savePreviousSongs: boolean;\n customFilters?: Filters;\n nsfw: boolean;\n emitAddSongWhenCreatingQueue: boolean;\n emitAddListWhenCreatingQueue: boolean;\n joinNewVoiceChannel: boolean;\n ffmpeg: FFmpegOptions;\n constructor(options: DisTubeOptions) {\n if (typeof options !== \"object\" || Array.isArray(options)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"object\", options, \"DisTubeOptions\");\n }\n const opts = { ...defaultOptions, ...options };\n this.plugins = opts.plugins;\n this.emitNewSongOnly = opts.emitNewSongOnly;\n this.savePreviousSongs = opts.savePreviousSongs;\n this.customFilters = opts.customFilters;\n this.nsfw = opts.nsfw;\n this.emitAddSongWhenCreatingQueue = opts.emitAddSongWhenCreatingQueue;\n this.emitAddListWhenCreatingQueue = opts.emitAddListWhenCreatingQueue;\n this.joinNewVoiceChannel = opts.joinNewVoiceChannel;\n this.ffmpeg = this.#ffmpegOption(options);\n checkInvalidKey(opts, this, \"DisTubeOptions\");\n this.#validateOptions();\n }\n\n #validateOptions(options = this) {\n const booleanOptions = new Set([\n \"emitNewSongOnly\",\n \"savePreviousSongs\",\n \"joinNewVoiceChannel\",\n \"nsfw\",\n \"emitAddSongWhenCreatingQueue\",\n \"emitAddListWhenCreatingQueue\",\n ]);\n const numberOptions = new Set();\n const stringOptions = new Set();\n const objectOptions = new Set([\"customFilters\", \"ffmpeg\"]);\n const optionalOptions = new Set([\"customFilters\"]);\n\n for (const [key, value] of Object.entries(options)) {\n if (value === undefined && optionalOptions.has(key)) continue;\n if (key === \"plugins\" && !Array.isArray(value)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"Array<Plugin>\", value, `DisTubeOptions.${key}`);\n } else if (booleanOptions.has(key)) {\n if (typeof value !== \"boolean\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"boolean\", value, `DisTubeOptions.${key}`);\n }\n } else if (numberOptions.has(key)) {\n if (typeof value !== \"number\" || isNaN(value)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"number\", value, `DisTubeOptions.${key}`);\n }\n } else if (stringOptions.has(key)) {\n if (typeof value !== \"string\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"string\", value, `DisTubeOptions.${key}`);\n }\n } else if (objectOptions.has(key)) {\n if (typeof value !== \"object\" || Array.isArray(value)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"object\", value, `DisTubeOptions.${key}`);\n }\n }\n }\n }\n\n #ffmpegOption(opts: DisTubeOptions) {\n const args: FFmpegArgs = { global: {}, input: {}, output: {} };\n if (opts.ffmpeg?.args) {\n if (opts.ffmpeg.args.global) args.global = opts.ffmpeg.args.global;\n if (opts.ffmpeg.args.input) args.input = opts.ffmpeg.args.input;\n if (opts.ffmpeg.args.output) args.output = opts.ffmpeg.args.output;\n }\n const path = opts.ffmpeg?.path ?? \"ffmpeg\";\n if (typeof path !== \"string\") {\n throw new DisTubeError(\"INVALID_TYPE\", \"string\", path, \"DisTubeOptions.ffmpeg.path\");\n }\n for (const [key, value] of Object.entries(args)) {\n if (typeof value !== \"object\" || Array.isArray(value)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"object\", value, `DisTubeOptions.ffmpeg.${key}`);\n }\n for (const [k, v] of Object.entries(value)) {\n if (\n typeof v !== \"string\" &&\n typeof v !== \"number\" &&\n typeof v !== \"boolean\" &&\n !Array.isArray(v) &&\n v !== null &&\n v !== undefined\n ) {\n throw new DisTubeError(\n \"INVALID_TYPE\",\n [\"string\", \"number\", \"boolean\", \"Array<string | null | undefined>\", \"null\", \"undefined\"],\n v,\n `DisTubeOptions.ffmpeg.${key}.${k}`,\n );\n }\n }\n }\n return { path, args };\n }\n}\n","import { DisTubeBase } from \"..\";\nimport { Collection } from \"discord.js\";\n\n/**\n * Manages the collection of a data model.\n */\nexport abstract class BaseManager<V> extends DisTubeBase {\n /**\n * The collection of items for this manager.\n */\n collection = new Collection<string, V>();\n /**\n * The size of the collection.\n */\n get size() {\n return this.collection.size;\n }\n}\n","import { BaseManager } from \".\";\nimport { resolveGuildId } from \"../..\";\nimport type { GuildIdResolvable } from \"../..\";\n\n/**\n * Manages the collection of a data model paired with a guild id.\n */\nexport abstract class GuildIdManager<V> extends BaseManager<V> {\n add(idOrInstance: GuildIdResolvable, data: V) {\n const id = resolveGuildId(idOrInstance);\n const existing = this.get(id);\n if (existing) return this;\n this.collection.set(id, data);\n return this;\n }\n get(idOrInstance: GuildIdResolvable): V | undefined {\n return this.collection.get(resolveGuildId(idOrInstance));\n }\n remove(idOrInstance: GuildIdResolvable): boolean {\n return this.collection.delete(resolveGuildId(idOrInstance));\n }\n has(idOrInstance: GuildIdResolvable): boolean {\n return this.collection.has(resolveGuildId(idOrInstance));\n }\n}\n","import { GuildIdManager } from \".\";\nimport { DisTubeVoice } from \"../DisTubeVoice\";\nimport { DisTubeError, resolveGuildId } from \"../..\";\nimport { VoiceConnectionStatus, getVoiceConnection } from \"@discordjs/voice\";\nimport type { GuildIdResolvable } from \"../..\";\nimport type { VoiceBasedChannel } from \"discord.js\";\n\n/**\n * Manages voice connections\n */\nexport class DisTubeVoiceManager extends GuildIdManager<DisTubeVoice> {\n /**\n * Create a {@link DisTubeVoice} instance\n * @param channel - A voice chann el to join\n */\n create(channel: VoiceBasedChannel): DisTubeVoice {\n const existing = this.get(channel.guildId);\n if (existing) {\n existing.channel = channel;\n return existing;\n }\n if (\n getVoiceConnection(resolveGuildId(channel), this.client.user?.id) ||\n getVoiceConnection(resolveGuildId(channel))\n ) {\n throw new DisTubeError(\"VOICE_ALREADY_CREATED\");\n }\n return new DisTubeVoice(this, channel);\n }\n /**\n * Join a voice channel and wait until the connection is ready\n * @param channel - A voice channel to join\n */\n join(channel: VoiceBasedChannel): Promise<DisTubeVoice> {\n const existing = this.get(channel.guildId);\n if (existing) return existing.join(channel);\n return this.create(channel).join();\n }\n /**\n * Leave the connected voice channel in a guild\n * @param guild - Queue Resolvable\n */\n leave(guild: GuildIdResolvable) {\n const voice = this.get(guild);\n if (voice) {\n voice.leave();\n } else {\n const connection =\n getVoiceConnection(resolveGuildId(guild), this.client.user?.id) ?? getVoiceConnection(resolveGuildId(guild));\n if (connection && connection.state.status !== VoiceConnectionStatus.Destroyed) {\n connection.destroy();\n }\n }\n }\n}\n","import { BaseManager } from \".\";\nimport { DisTubeError } from \"../..\";\nimport type { FFmpegArg as FFmpegArgsValue, Filter, FilterResolvable, Queue } from \"../..\";\n\n/**\n * Manage filters of a playing {@link Queue}\n */\nexport class FilterManager extends BaseManager<Filter> {\n /**\n * The queue to manage\n */\n queue: Queue;\n constructor(queue: Queue) {\n super(queue.distube);\n this.queue = queue;\n }\n\n #resolve(filter: FilterResolvable): Filter {\n if (typeof filter === \"object\" && typeof filter.name === \"string\" && typeof filter.value === \"string\") {\n return filter;\n }\n if (typeof filter === \"string\" && Object.prototype.hasOwnProperty.call(this.distube.filters, filter)) {\n return {\n name: filter,\n value: this.distube.filters[filter],\n };\n }\n throw new DisTubeError(\"INVALID_TYPE\", \"FilterResolvable\", filter, \"filter\");\n }\n\n #apply() {\n this.queue._beginTime = this.queue.currentTime;\n this.queue.play(false);\n }\n\n /**\n * Enable a filter or multiple filters to the manager\n * @param filterOrFilters - The filter or filters to enable\n * @param override - Wether or not override the applied filter with new filter value\n */\n add(filterOrFilters: FilterResolvable | FilterResolvable[], override = false) {\n if (Array.isArray(filterOrFilters)) {\n for (const filter of filterOrFilters) {\n const ft = this.#resolve(filter);\n if (override || !this.has(ft)) this.collection.set(ft.name, ft);\n }\n } else {\n const ft = this.#resolve(filterOrFilters);\n if (override || !this.has(ft)) this.collection.set(ft.name, ft);\n }\n this.#apply();\n return this;\n }\n\n /**\n * Clear enabled filters of the manager\n */\n clear() {\n return this.set([]);\n }\n\n /**\n * Set the filters applied to the manager\n * @param filters - The filters to apply\n */\n set(filters: FilterResolvable[]) {\n if (!Array.isArray(filters)) throw new DisTubeError(\"INVALID_TYPE\", \"Array<FilterResolvable>\", filters, \"filters\");\n this.collection.clear();\n for (const f of filters) {\n const filter = this.#resolve(f);\n this.collection.set(filter.name, filter);\n }\n this.#apply();\n return this;\n }\n\n #removeFn(f: FilterResolvable) {\n return this.collection.delete(this.#resolve(f).name);\n }\n\n /**\n * Disable a filter or multiple filters\n * @param filterOrFilters - The filter or filters to disable\n */\n remove(filterOrFilters: FilterResolvable | FilterResolvable[]) {\n if (Array.isArray(filterOrFilters)) filterOrFilters.forEach(f => this.#removeFn(f));\n else this.#removeFn(filterOrFilters);\n this.#apply();\n return this;\n }\n\n /**\n * Check whether a filter enabled or not\n * @param filter - The filter to check\n */\n has(filter: FilterResolvable) {\n return this.collection.has(typeof filter === \"string\" ? filter : this.#resolve(filter).name);\n }\n\n /**\n * Array of enabled filter names\n */\n get names(): string[] {\n return [...this.collection.keys()];\n }\n\n /**\n * Array of enabled filters\n */\n get values(): Filter[] {\n return [...this.collection.values()];\n }\n\n get ffmpegArgs(): FFmpegArgsValue {\n return this.size ? { af: this.values.map(f => f.value).join(\",\") } : {};\n }\n\n override toString() {\n return this.names.toString();\n }\n}\n","import { GuildIdManager } from \".\";\nimport { DisTubeError, DisTubeStream, Events, Queue, RepeatMode, checkFFmpeg, objectKeys } from \"../..\";\nimport type { Song } from \"../..\";\nimport type { GuildTextBasedChannel, VoiceBasedChannel } from \"discord.js\";\n\n/**\n * Queue manager\n */\nexport class QueueManager extends GuildIdManager<Queue> {\n /**\n * Create a {@link Queue}\n * @param channel - A voice channel\n * @param textChannel - Default text channel\n * @returns Returns `true` if encounter an error\n */\n async create(channel: VoiceBasedChannel, textChannel?: GuildTextBasedChannel): Promise<Queue> {\n if (this.has(channel.guildId)) throw new DisTubeError(\"QUEUE_EXIST\");\n this.debug(`[QueueManager] Creating queue for guild: ${channel.guildId}`);\n const voice = this.voices.create(channel);\n const queue = new Queue(this.distube, voice, textChannel);\n await queue._taskQueue.queuing();\n try {\n checkFFmpeg(this.distube);\n this.debug(`[QueueManager] Joining voice channel: ${channel.id}`);\n await voice.join();\n this.#voiceEventHandler(queue);\n this.add(queue.id, queue);\n this.emit(Events.INIT_QUEUE, queue);\n return queue;\n } finally {\n queue._taskQueue.resolve();\n }\n }\n\n /**\n * Listen to DisTubeVoice events and handle the Queue\n * @param queue - Queue\n */\n #voiceEventHandler(queue: Queue) {\n queue._listeners = {\n disconnect: error => {\n queue.remove();\n this.emit(Events.DISCONNECT, queue);\n if (error) this.emitError(error, queue, queue.songs?.[0]);\n },\n error: error => this.#handlePlayingError(queue, error),\n finish: () => this.#handleSongFinish(queue),\n };\n for (const event of objectKeys(queue._listeners)) {\n queue.voice.on(event, queue._listeners[event]);\n }\n }\n\n /**\n * Whether or not emit playSong event\n * @param queue - Queue\n */\n #emitPlaySong(queue: Queue): boolean {\n if (!this.options.emitNewSongOnly) return true;\n if (queue.repeatMode === RepeatMode.SONG) return queue._next || queue._prev;\n return queue.songs[0].id !== queue.songs[1].id;\n }\n\n /**\n * Handle the queue when a Song finish\n * @param queue - queue\n */\n async #handleSongFinish(queue: Queue): Promise<void> {\n this.debug(`[QueueManager] Handling song finish: ${queue.id}`);\n const song = queue.songs[0];\n this.emit(Events.FINISH_SONG, queue, queue.songs[0]);\n await queue._taskQueue.queuing();\n try {\n if (queue.stopped) return;\n if (queue.repeatMode === RepeatMode.QUEUE && !queue._prev) queue.songs.push(song);\n if (queue._prev) {\n if (queue.repeatMode === RepeatMode.QUEUE) queue.songs.unshift(queue.songs.pop() as Song);\n else queue.songs.unshift(queue.previousSongs.pop() as Song);\n }\n if (queue.songs.length <= 1 && (queue._next || queue.repeatMode === RepeatMode.DISABLED)) {\n if (queue.autoplay) {\n try {\n this.debug(`[QueueManager] Adding related song: ${queue.id}`);\n await queue.addRelatedSong();\n } catch (e: any) {\n this.debug(`[${queue.id}] Add related song error: ${e.message}`);\n this.emit(Events.NO_RELATED, queue, e);\n }\n }\n if (queue.songs.length <= 1) {\n this.debug(`[${queue.id}] Queue is empty, stopping...`);\n if (!queue.autoplay) this.emit(Events.FINISH, queue);\n queue.remove();\n return;\n }\n }\n const emitPlaySong = this.#emitPlaySong(queue);\n if (!queue._prev && (queue.repeatMode !== RepeatMode.SONG || queue._next)) {\n const prev = queue.songs.shift() as Song;\n if (this.options.savePreviousSongs) queue.previousSongs.push(prev);\n else queue.previousSongs.push({ id: prev.id } as Song);\n }\n queue._next = queue._prev = false;\n queue._beginTime = 0;\n if (song !== queue.songs[0]) {\n const playedSong = song.stream.playFromSource ? song : song.stream.song;\n if (playedSong?.stream.playFromSource) delete playedSong.stream.url;\n }\n await this.playSong(queue, emitPlaySong);\n } finally {\n queue._taskQueue.resolve();\n }\n }\n\n /**\n * Handle error while playing\n * @param queue - queue\n * @param error - error\n */\n #handlePlayingError(queue: Queue, error: Error) {\n const song = queue.songs.shift()!;\n try {\n error.name = \"PlayingError\";\n } catch {\n // Emit original error\n }\n this.debug(`[${queue.id}] Error while playing: ${error.stack || error.message}`);\n this.emitError(error, queue, song);\n if (queue.songs.length > 0) {\n this.debug(`[${queue.id}] Playing next song: ${queue.songs[0]}`);\n queue._next = queue._prev = false;\n queue._beginTime = 0;\n this.playSong(queue);\n } else {\n this.debug(`[${queue.id}] Queue is empty, stopping...`);\n queue.stop();\n }\n }\n\n /**\n * Play a song on voice connection with queue properties\n * @param queue - The guild queue to play\n * @param emitPlaySong - Whether or not emit {@link Events.PLAY_SONG} event\n */\n async playSong(queue: Queue, emitPlaySong = true) {\n if (!queue) return;\n if (queue.stopped || !queue.songs.length) {\n queue.stop();\n return;\n }\n try {\n const song = queue.songs[0];\n this.debug(`[${queue.id}] Getting stream from: ${song}`);\n await this.handler.attachStreamInfo(song);\n const willPlaySong = song.stream.playFromSource ? song : song.stream.song;\n const stream = willPlaySong?.stream;\n if (!willPlaySong || !stream?.playFromSource || !stream.url) throw new DisTubeError(\"NO_STREAM_URL\", `${song}`);\n this.debug(`[${queue.id}] Creating DisTubeStream for: ${willPlaySong}`);\n const streamOptions = {\n ffmpeg: {\n path: this.options.ffmpeg.path,\n args: {\n global: { ...queue.ffmpegArgs.global },\n input: { ...queue.ffmpegArgs.input },\n output: { ...queue.ffmpegArgs.output, ...queue.filters.ffmpegArgs },\n },\n },\n seek: willPlaySong.duration ? queue._beginTime : undefined,\n };\n const dtStream = new DisTubeStream(stream.url, streamOptions);\n dtStream.on(\"debug\", data => this.emit(Events.FFMPEG_DEBUG, `[${queue.id}] ${data}`));\n this.debug(`[${queue.id}] Started playing: ${willPlaySong}`);\n queue.voice.play(dtStream);\n if (emitPlaySong) this.emit(Events.PLAY_SONG, queue, song);\n } catch (e: any) {\n this.#handlePlayingError(queue, e);\n }\n }\n}\n","import { DisTubeBase, FilterManager } from \"../core\";\nimport { DisTubeError, Events, RepeatMode, TaskQueue, formatDuration, objectKeys } from \"..\";\nimport type { GuildTextBasedChannel, Snowflake } from \"discord.js\";\nimport type { DisTube, DisTubeVoice, DisTubeVoiceEvents, FFmpegArgs, Song } from \"..\";\n\n/**\n * Represents a queue.\n */\nexport class Queue extends DisTubeBase {\n /**\n * Queue id (Guild id)\n */\n readonly id: Snowflake;\n /**\n * Voice connection of this queue.\n */\n voice: DisTubeVoice;\n /**\n * List of songs in the queue (The first one is the playing song)\n */\n songs: Song[];\n /**\n * List of the previous songs.\n */\n previousSongs: Song[];\n /**\n * Whether stream is currently stopped.\n */\n stopped: boolean;\n /**\n * Whether or not the stream is currently playing.\n */\n playing: boolean;\n /**\n * Whether or not the stream is currently paused.\n */\n paused: boolean;\n /**\n * Type of repeat mode (`0` is disabled, `1` is repeating a song, `2` is repeating\n * all the queue). Default value: `0` (disabled)\n */\n repeatMode: RepeatMode;\n /**\n * Whether or not the autoplay mode is enabled. Default value: `false`\n */\n autoplay: boolean;\n /**\n * FFmpeg arguments for the current queue. Default value is defined with {@link DisTubeOptions}.ffmpeg.args.\n * `af` output argument will be replaced with {@link Queue#filters} manager\n */\n ffmpegArgs: FFmpegArgs;\n /**\n * The text channel of the Queue. (Default: where the first command is called).\n */\n textChannel?: GuildTextBasedChannel;\n #filters: FilterManager;\n /**\n * What time in the song to begin (in seconds).\n */\n _beginTime: number;\n /**\n * Whether or not the last song was skipped to next song.\n */\n _next: boolean;\n /**\n * Whether or not the last song was skipped to previous song.\n */\n _prev: boolean;\n /**\n * Task queuing system\n */\n _taskQueue: TaskQueue;\n /**\n * {@link DisTubeVoice} listener\n */\n _listeners?: DisTubeVoiceEvents;\n /**\n * Create a queue for the guild\n * @param distube - DisTube\n * @param voice - Voice connection\n * @param textChannel - Default text channel\n */\n constructor(distube: DisTube, voice: DisTubeVoice, textChannel?: GuildTextBasedChannel) {\n super(distube);\n this.voice = voice;\n this.id = voice.id;\n this.volume = 50;\n this.songs = [];\n this.previousSongs = [];\n this.stopped = false;\n this._next = false;\n this._prev = false;\n this.playing = false;\n this.paused = false;\n this.repeatMode = RepeatMode.DISABLED;\n this.autoplay = false;\n this.#filters = new FilterManager(this);\n this._beginTime = 0;\n this.textChannel = textChannel;\n this._taskQueue = new TaskQueue();\n this._listeners = undefined;\n this.ffmpegArgs = {\n global: { ...this.options.ffmpeg.args.global },\n input: { ...this.options.ffmpeg.args.input },\n output: { ...this.options.ffmpeg.args.output },\n };\n }\n /**\n * The client user as a `GuildMember` of this queue's guild\n */\n get clientMember() {\n return this.voice.channel.guild.members.me ?? undefined;\n }\n /**\n * The filter manager of the queue\n */\n get filters() {\n return this.#filters;\n }\n /**\n * Formatted duration string.\n */\n get formattedDuration() {\n return formatDuration(this.duration);\n }\n /**\n * Queue's duration.\n */\n get duration() {\n return this.songs.length ? this.songs.reduce((prev, next) => prev + next.duration, 0) : 0;\n }\n /**\n * What time in the song is playing (in seconds).\n */\n get currentTime() {\n return this.voice.playbackDuration + this._beginTime;\n }\n /**\n * Formatted {@link Queue#currentTime} string.\n */\n get formattedCurrentTime() {\n return formatDuration(this.currentTime);\n }\n /**\n * The voice channel playing in.\n */\n get voiceChannel() {\n return this.clientMember?.voice?.channel ?? null;\n }\n /**\n * Get or set the stream volume. Default value: `50`.\n */\n get volume() {\n return this.voice.volume;\n }\n set volume(value: number) {\n this.voice.volume = value;\n }\n /**\n * @throws {DisTubeError}\n * @param song - Song to add\n * @param position - Position to add, \\<= 0 to add to the end of the queue\n * @returns The guild queue\n */\n addToQueue(song: Song | Song[], position = 0): Queue {\n if (this.stopped) throw new DisTubeError(\"QUEUE_STOPPED\");\n if (!song || (Array.isArray(song) && !song.length)) {\n throw new DisTubeError(\"INVALID_TYPE\", [\"Song\", \"Array<Song>\"], song, \"song\");\n }\n if (typeof position !== \"number\" || !Number.isInteger(position)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"integer\", position, \"position\");\n }\n if (position <= 0) {\n if (Array.isArray(song)) this.songs.push(...song);\n else this.songs.push(song);\n } else if (Array.isArray(song)) {\n this.songs.splice(position, 0, ...song);\n } else {\n this.songs.splice(position, 0, song);\n }\n return this;\n }\n /**\n * Pause the guild stream\n * @returns The guild queue\n */\n pause(): Queue {\n if (this.paused) throw new DisTubeError(\"PAUSED\");\n this.paused = true;\n this.voice.pause();\n return this;\n }\n /**\n * Resume the guild stream\n * @returns The guild queue\n */\n resume(): Queue {\n if (!this.paused) throw new DisTubeError(\"RESUMED\");\n this.paused = false;\n this.voice.unpause();\n return this;\n }\n /**\n * Set the guild stream's volume\n * @param percent - The percentage of volume you want to set\n * @returns The guild queue\n */\n setVolume(percent: number): Queue {\n this.volume = percent;\n return this;\n }\n\n /**\n * Skip the playing song if there is a next song in the queue. <info>If {@link\n * Queue#autoplay} is `true` and there is no up next song, DisTube will add and\n * play a related song.</info>\n * @returns The song will skip to\n */\n async skip(): Promise<Song> {\n await this._taskQueue.queuing();\n try {\n if (this.songs.length <= 1) {\n if (this.autoplay) await this.addRelatedSong();\n else throw new DisTubeError(\"NO_UP_NEXT\");\n }\n const song = this.songs[1];\n this._next = true;\n this.voice.stop();\n return song;\n } finally {\n this._taskQueue.resolve();\n }\n }\n\n /**\n * Play the previous song if exists\n * @returns The guild queue\n */\n async previous(): Promise<Song> {\n await this._taskQueue.queuing();\n try {\n if (!this.options.savePreviousSongs) throw new DisTubeError(\"DISABLED_OPTION\", \"savePreviousSongs\");\n if (this.previousSongs?.length === 0 && this.repeatMode !== RepeatMode.QUEUE) {\n throw new DisTubeError(\"NO_PREVIOUS\");\n }\n const song =\n this.repeatMode === 2 ? this.songs[this.songs.length - 1] : this.previousSongs[this.previousSongs.length - 1];\n this._prev = true;\n this.voice.stop();\n return song;\n } finally {\n this._taskQueue.resolve();\n }\n }\n /**\n * Shuffle the queue's songs\n * @returns The guild queue\n */\n async shuffle(): Promise<Queue> {\n await this._taskQueue.queuing();\n try {\n const playing = this.songs.shift();\n if (playing === undefined) return this;\n for (let i = this.songs.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [this.songs[i], this.songs[j]] = [this.songs[j], this.songs[i]];\n }\n this.songs.unshift(playing);\n return this;\n } finally {\n this._taskQueue.resolve();\n }\n }\n /**\n * Jump to the song position in the queue. The next one is 1, 2,... The previous\n * one is -1, -2,...\n * if `num` is invalid number\n * @param position - The song position to play\n * @returns The new Song will be played\n */\n async jump(position: number): Promise<Song> {\n await this._taskQueue.queuing();\n try {\n if (typeof position !== \"number\") throw new DisTubeError(\"INVALID_TYPE\", \"number\", position, \"position\");\n if (!position || position > this.songs.length || -position > this.previousSongs.length) {\n throw new DisTubeError(\"NO_SONG_POSITION\");\n }\n let nextSong: Song;\n if (position > 0) {\n const nextSongs = this.songs.splice(position - 1);\n if (this.options.savePreviousSongs) {\n this.previousSongs.push(...this.songs);\n } else {\n this.previousSongs.push(...this.songs.map(s => ({ id: s.id }) as Song));\n }\n this.songs = nextSongs;\n this._next = true;\n nextSong = nextSongs[1];\n } else if (!this.options.savePreviousSongs) {\n throw new DisTubeError(\"DISABLED_OPTION\", \"savePreviousSongs\");\n } else {\n this._prev = true;\n if (position !== -1) this.songs.unshift(...this.previousSongs.splice(position + 1));\n nextSong = this.previousSongs[this.previousSongs.length - 1];\n }\n this.voice.stop();\n return nextSong;\n } finally {\n this._taskQueue.resolve();\n }\n }\n /**\n * Set the repeat mode of the guild queue.\n * Toggle mode `(Disabled -> Song -> Queue -> Disabled ->...)` if `mode` is `undefined`\n * @param mode - The repeat modes (toggle if `undefined`)\n * @returns The new repeat mode\n */\n setRepeatMode(mode?: RepeatMode): RepeatMode {\n if (mode !== undefined && !Object.values(RepeatMode).includes(mode)) {\n throw new DisTubeError(\"INVALID_TYPE\", [\"RepeatMode\", \"undefined\"], mode, \"mode\");\n }\n if (mode === undefined) this.repeatMode = (this.repeatMode + 1) % 3;\n else if (this.repeatMode === mode) this.repeatMode = RepeatMode.DISABLED;\n else this.repeatMode = mode;\n return this.repeatMode;\n }\n /**\n * Set the playing time to another position\n * @param time - Time in seconds\n * @returns The guild queue\n */\n seek(time: number): Queue {\n if (typeof time !== \"number\") throw new DisTubeError(\"INVALID_TYPE\", \"number\", time, \"time\");\n if (isNaN(time) || time < 0) throw new DisTubeError(\"NUMBER_COMPARE\", \"time\", \"bigger or equal to\", 0);\n this._beginTime = time;\n this.play(false);\n return this;\n }\n async #getRelatedSong(current: Song): Promise<Song[]> {\n const plugin = await this.handler._getPluginFromSong(current);\n if (plugin) return plugin.getRelatedSongs(current);\n return [];\n }\n /**\n * Add a related song of the playing song to the queue\n * @returns The added song\n */\n async addRelatedSong(): Promise<Song> {\n const current = this.songs?.[0];\n if (!current) throw new DisTubeError(\"NO_PLAYING_SONG\");\n const prevIds = this.previousSongs.map(p => p.id);\n const relatedSongs = (await this.#getRelatedSong(current)).filter(s => !prevIds.includes(s.id));\n this.debug(`[${this.id}] Getting related songs from: ${current}`);\n if (!relatedSongs.length && !current.stream.playFromSource) {\n const altSong = current.stream.song;\n if (altSong) relatedSongs.push(...(await this.#getRelatedSong(altSong)).filter(s => !prevIds.includes(s.id)));\n this.debug(`[${this.id}] Getting related songs from streamed song: ${altSong}`);\n }\n const song = relatedSongs[0];\n if (!song) throw new DisTubeError(\"NO_RELATED\");\n song.metadata = current.metadata;\n song.member = this.clientMember;\n this.addToQueue(song);\n return song;\n }\n /**\n * Stop the guild stream and delete the queue\n */\n async stop() {\n await this._taskQueue.queuing();\n try {\n this.playing = false;\n this.paused = false;\n this.stopped = true;\n this.voice.stop();\n this.remove();\n } finally {\n this._taskQueue.resolve();\n }\n }\n /**\n * Remove the queue from the manager\n */\n remove() {\n this.stopped = true;\n this.songs = [];\n this.previousSongs = [];\n if (this._listeners) {\n for (const event of objectKeys(this._listeners)) {\n this.voice.off(event, this._listeners[event]);\n }\n }\n this.queues.remove(this.id);\n this.emit(Events.DELETE_QUEUE, this);\n }\n /**\n * Toggle autoplay mode\n * @returns Autoplay mode state\n */\n toggleAutoplay(): boolean {\n this.autoplay = !this.autoplay;\n return this.autoplay;\n }\n /**\n * Play the queue\n * @param emitPlaySong - Whether or not emit {@link Events.PLAY_SONG} event\n */\n play(emitPlaySong = true) {\n if (this.stopped) throw new DisTubeError(\"QUEUE_STOPPED\");\n this.playing = true;\n return this.queues.playSong(this, emitPlaySong);\n }\n}\n","import type { Awaitable, DisTube, PluginType, Song } from \"..\";\n\n/**\n * DisTube Plugin\n */\nexport abstract class Plugin {\n /**\n * Type of the plugin\n */\n abstract readonly type: PluginType;\n /**\n * DisTube\n */\n distube!: DisTube;\n init(distube: DisTube) {\n this.distube = distube;\n }\n /**\n * Get related songs from a supported url.\n * @param song - Input song\n */\n abstract getRelatedSongs(song: Song): Awaitable<Song[]>;\n}\n","import { Plugin } from \".\";\nimport { PluginType } from \"..\";\nimport type { Awaitable, Playlist, ResolveOptions, Song } from \"..\";\n\n/**\n * This plugin can extract the info, search, and play a song directly from its source\n */\nexport abstract class ExtractorPlugin extends Plugin {\n readonly type = PluginType.EXTRACTOR;\n /**\n * Check if the url is working with this plugin\n * @param url - Input url\n */\n abstract validate(url: string): Awaitable<boolean>;\n /**\n * Resolve the validated url to a {@link Song} or a {@link Playlist}.\n * @param url - URL\n * @param options - Optional options\n */\n abstract resolve<T>(url: string, options: ResolveOptions<T>): Awaitable<Song<T> | Playlist<T>>;\n /**\n * Search for a Song which playable from this plugin's source\n * @param query - Search query\n * @param options - Optional options\n */\n abstract searchSong<T>(query: string, options: ResolveOptions<T>): Awaitable<Song<T> | null>;\n /**\n * Get the stream url from {@link Song#url}. Returns {@link Song#url} by default.\n * Not needed if the plugin plays song from YouTube.\n * @param song - Input song\n */\n abstract getStreamURL<T>(song: Song<T>): Awaitable<string>;\n}\n","import { Plugin } from \".\";\nimport { PluginType } from \"..\";\nimport type { Awaitable, Playlist, ResolveOptions, Song } from \"..\";\n\n/**\n * This plugin only can extract the info from supported links, but not play song directly from its source\n */\nexport abstract class InfoExtractorPlugin extends Plugin {\n readonly type = PluginType.INFO_EXTRACTOR;\n /**\n * Check if the url is working with this plugin\n * @param url - Input url\n */\n abstract validate(url: string): Awaitable<boolean>;\n /**\n * Resolve the validated url to a {@link Song} or a {@link Playlist}.\n * @param url - URL\n * @param options - Optional options\n */\n abstract resolve<T>(url: string, options: ResolveOptions<T>): Awaitable<Song<T> | Playlist<T>>;\n\n /**\n * Create a search query to be used in {@link ExtractorPlugin#searchSong}\n * @param song - Input song\n */\n abstract createSearchQuery<T>(song: Song<T>): Awaitable<string>;\n}\n","import { Plugin } from \".\";\nimport { PluginType } from \"..\";\nimport type { Awaitable, Playlist, ResolveOptions, Song } from \"..\";\n\n/**\n * This plugin can extract and play song from supported links, but cannot search for songs from its source\n */\nexport abstract class PlayableExtractorPlugin extends Plugin {\n readonly type = PluginType.PLAYABLE_EXTRACTOR;\n /**\n * Check if the url is working with this plugin\n * @param url - Input url\n */\n abstract validate(url: string): Awaitable<boolean>;\n /**\n * Resolve the validated url to a {@link Song} or a {@link Playlist}.\n * @param url - URL\n * @param options - Optional options\n */\n abstract resolve<T>(url: string, options: ResolveOptions<T>): Awaitable<Song<T> | Playlist<T>>;\n /**\n * Get the stream url from {@link Song#url}. Returns {@link Song#url} by default.\n * Not needed if the plugin plays song from YouTube.\n * @param song - Input song\n */\n abstract getStreamURL<T>(song: Song<T>): Awaitable<string>;\n}\n","import { URL } from \"url\";\nimport { DisTubeError, DisTubeVoice, Queue } from \".\";\nimport { Constants, GatewayIntentBits, IntentsBitField, SnowflakeUtil } from \"discord.js\";\nimport type { GuildIdResolvable } from \".\";\nimport type {\n Client,\n ClientOptions,\n Guild,\n GuildMember,\n GuildTextBasedChannel,\n Message,\n Snowflake,\n VoiceBasedChannel,\n VoiceState,\n} from \"discord.js\";\n\nconst formatInt = (int: number) => (int < 10 ? `0${int}` : int);\n\n/**\n * Format duration to string\n * @param sec - Duration in seconds\n */\nexport function formatDuration(sec: number): string {\n if (!sec || !Number(sec)) return \"00:00\";\n const seconds = Math.floor(sec % 60);\n const minutes = Math.floor((sec % 3600) / 60);\n const hours = Math.floor(sec / 3600);\n if (hours > 0) return `${formatInt(hours)}:${formatInt(minutes)}:${formatInt(seconds)}`;\n if (minutes > 0) return `${formatInt(minutes)}:${formatInt(seconds)}`;\n return `00:${formatInt(seconds)}`;\n}\nconst SUPPORTED_PROTOCOL = [\"https:\", \"http:\", \"file:\"] as const;\n/**\n * Check if the string is an URL\n * @param input - input\n */\nexport function isURL(input: any): input is `${(typeof SUPPORTED_PROTOCOL)[number]}//${string}` {\n if (typeof input !== \"string\" || input.includes(\" \")) return false;\n try {\n const url = new URL(input);\n if (!SUPPORTED_PROTOCOL.some(p => p === url.protocol)) return false;\n } catch {\n return false;\n }\n return true;\n}\n/**\n * Check if the Client has enough intents to using DisTube\n * @param options - options\n */\nexport function checkIntents(options: ClientOptions): void {\n const intents = options.intents instanceof IntentsBitField ? options.intents : new IntentsBitField(options.intents);\n if (!intents.has(GatewayIntentBits.GuildVoiceStates)) throw new DisTubeError(\"MISSING_INTENTS\", \"GuildVoiceStates\");\n}\n\n/**\n * Check if the voice channel is empty\n * @param voiceState - voiceState\n */\nexport function isVoiceChannelEmpty(voiceState: VoiceState): boolean {\n const guild = voiceState.guild;\n const clientId = voiceState.client.user?.id;\n if (!guild || !clientId) return false;\n const voiceChannel = guild.members.me?.voice?.channel;\n if (!voiceChannel) return false;\n const members = voiceChannel.members.filter(m => !m.user.bot);\n return !members.size;\n}\n\nexport function isSnowflake(id: any): id is Snowflake {\n try {\n return SnowflakeUtil.deconstruct(id).timestamp > SnowflakeUtil.epoch;\n } catch {\n return false;\n }\n}\n\nexport function isMemberInstance(member: any): member is GuildMember {\n return (\n Boolean(member) &&\n isSnowflake(member.id) &&\n isSnowflake(member.guild?.id) &&\n isSnowflake(member.user?.id) &&\n member.id === member.user.id\n );\n}\n\nexport function isTextChannelInstance(channel: any): channel is GuildTextBasedChannel {\n return (\n Boolean(channel) &&\n isSnowflake(channel.id) &&\n isSnowflake(channel.guildId || channel.guild?.id) &&\n Constants.TextBasedChannelTypes.includes(channel.type) &&\n typeof channel.send === \"function\" &&\n (typeof channel.nsfw === \"boolean\" || typeof channel.parent?.nsfw === \"boolean\")\n );\n}\n\nexport function isMessageInstance(message: any): message is Message<true> {\n // Simple check for using distube normally\n return (\n Boolean(message) &&\n isSnowflake(message.id) &&\n isSnowflake(message.guildId || message.guild?.id) &&\n isMemberInstance(message.member) &&\n isTextChannelInstance(message.channel) &&\n Constants.NonSystemMessageTypes.includes(message.type) &&\n message.member.id === message.author?.id\n );\n}\n\nexport function isSupportedVoiceChannel(channel: any): channel is VoiceBasedChannel {\n return (\n Boolean(channel) &&\n isSnowflake(channel.id) &&\n isSnowflake(channel.guildId || channel.guild?.id) &&\n Constants.VoiceBasedChannelTypes.includes(channel.type)\n );\n}\n\nexport function isGuildInstance(guild: any): guild is Guild {\n return Boolean(guild) && isSnowflake(guild.id) && isSnowflake(guild.ownerId) && typeof guild.name === \"string\";\n}\n\nexport function resolveGuildId(resolvable: GuildIdResolvable): Snowflake {\n let guildId: string | undefined;\n if (typeof resolvable === \"string\") {\n guildId = resolvable;\n } else if (isObject(resolvable)) {\n if (\"guildId\" in resolvable && resolvable.guildId) {\n guildId = resolvable.guildId;\n } else if (resolvable instanceof Queue || resolvable instanceof DisTubeVoice || isGuildInstance(resolvable)) {\n guildId = resolvable.id;\n } else if (\"guild\" in resolvable && isGuildInstance(resolvable.guild)) {\n guildId = resolvable.guild.id;\n }\n }\n if (!isSnowflake(guildId)) throw new DisTubeError(\"INVALID_TYPE\", \"GuildIdResolvable\", resolvable);\n return guildId;\n}\n\nexport function isClientInstance(client: any): client is Client {\n return Boolean(client) && typeof client.login === \"function\";\n}\n\nexport function checkInvalidKey(\n target: Record<string, any>,\n source: Record<string, any> | string[],\n sourceName: string,\n) {\n if (!isObject(target)) throw new DisTubeError(\"INVALID_TYPE\", \"object\", target, sourceName);\n const sourceKeys = Array.isArray(source) ? source : objectKeys(source);\n const invalidKey = objectKeys(target).find(key => !sourceKeys.includes(key));\n if (invalidKey) throw new DisTubeError(\"INVALID_KEY\", sourceName, invalidKey);\n}\n\nexport function isObject(obj: any): obj is object {\n return typeof obj === \"object\" && obj !== null && !Array.isArray(obj);\n}\n\nexport type KeyOf<T> = T extends object ? (keyof T)[] : [];\nexport function objectKeys<T>(obj: T): KeyOf<T> {\n if (!isObject(obj)) return [] as KeyOf<T>;\n return Object.keys(obj) as KeyOf<T>;\n}\n\nexport function isNsfwChannel(channel?: GuildTextBasedChannel): boolean {\n if (!isTextChannelInstance(channel)) return false;\n if (channel.isThread()) return channel.parent?.nsfw ?? false;\n return channel.nsfw;\n}\n\nexport type Falsy = undefined | null | false | 0 | \"\";\nexport const isTruthy = <T>(x: T | Falsy): x is T => Boolean(x);\n","import { TypedEmitter } from \"tiny-typed-emitter\";\nimport {\n DisTubeError,\n DisTubeHandler,\n DisTubeVoiceManager,\n Events,\n Options,\n Playlist,\n QueueManager,\n Song,\n checkIntents,\n defaultFilters,\n isClientInstance,\n isMemberInstance,\n isMessageInstance,\n isNsfwChannel,\n isObject,\n isSupportedVoiceChannel,\n isTextChannelInstance,\n isURL,\n} from \".\";\nimport type { Client, VoiceBasedChannel } from \"discord.js\";\nimport type {\n Awaitable,\n CustomPlaylistOptions,\n DisTubeOptions,\n DisTubePlugin,\n Filters,\n GuildIdResolvable,\n PlayOptions,\n Queue,\n RepeatMode,\n TypedDisTubeEvents,\n} from \".\";\n\n// Cannot be `import` as it's not under TS root dir\n// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports\nexport const { version }: { version: string } = require(\"../package.json\");\n\n/**\n * DisTube class\n */\nexport class DisTube extends TypedEmitter<TypedDisTubeEvents> {\n /**\n * @event\n * Emitted after DisTube add a new playlist to the playing {@link Queue}.\n * @param queue - The guild queue\n * @param playlist - Playlist info\n */\n static readonly [Events.ADD_LIST]: (queue: Queue, playlist: Playlist) => Awaitable;\n /**\n * @event\n * Emitted after DisTube add a new song to the playing {@link Queue}.\n * @param queue - The guild queue\n * @param song - Added song\n */\n static readonly [Events.ADD_SONG]: (queue: Queue, song: Song) => Awaitable;\n /**\n * @event\n * Emitted when a {@link Queue} is deleted with any reasons.\n * @param queue - The guild queue\n */\n static readonly [Events.DELETE_QUEUE]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when the bot is disconnected to a voice channel.\n * @param queue - The guild queue\n */\n static readonly [Events.DISCONNECT]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when DisTube encounters an error while playing songs.\n * @param error - error\n * @param queue - The queue encountered the error\n * @param song - The playing song when encountered the error\n */\n static readonly [Events.ERROR]: (error: Error, queue: Queue, song?: Song) => Awaitable;\n /**\n * @event\n * Emitted for logging FFmpeg debug information.\n * @param debug - Debug message string.\n */\n static readonly [Events.FFMPEG_DEBUG]: (debug: string) => Awaitable;\n /**\n * @event\n * Emitted to provide debug information from DisTube's operation.\n * Useful for troubleshooting or logging purposes.\n *\n * @param debug - Debug message string.\n */\n static readonly [Events.DEBUG]: (debug: string) => Awaitable;\n /**\n * @event\n * Emitted when there is no more song in the queue and {@link Queue#autoplay} is `false`.\n * @param queue - The guild queue\n */\n static readonly [Events.FINISH]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when DisTube finished a song.\n * @param queue - The guild queue\n * @param song - Finished song\n */\n static readonly [Events.FINISH_SONG]: (queue: Queue, song: Song) => Awaitable;\n /**\n * @event\n * Emitted when DisTube initialize a queue to change queue default properties.\n * @param queue - The guild queue\n */\n static readonly [Events.INIT_QUEUE]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when {@link Queue#autoplay} is `true`, {@link Queue#songs} is empty, and\n * DisTube cannot find related songs to play.\n * @param queue - The guild queue\n */\n static readonly [Events.NO_RELATED]: (queue: Queue) => Awaitable;\n /**\n * @event\n * Emitted when DisTube play a song.\n * If {@link DisTubeOptions}.emitNewSongOnly is `true`, this event is not emitted\n * when looping a song or next song is the previous one.\n * @param queue - The guild queue\n * @param song - Playing song\n */\n static readonly [Events.PLAY_SONG]: (queue: Queue, song: Song) => Awaitable;\n /**\n * DisTube internal handler\n */\n readonly handler: DisTubeHandler;\n /**\n * DisTube options\n */\n readonly options: Options;\n /**\n * Discord.js v14 client\n */\n readonly client: Client;\n /**\n * Queues manager\n */\n readonly queues: QueueManager;\n /**\n * DisTube voice connections manager\n */\n readonly voices: DisTubeVoiceManager;\n /**\n * DisTube plugins\n */\n readonly plugins: DisTubePlugin[];\n /**\n * DisTube ffmpeg audio filters\n */\n readonly filters: Filters;\n /**\n * Create a new DisTube class.\n * @throws {@link DisTubeError}\n * @param client - Discord.JS client\n * @param opts - Custom DisTube options\n */\n constructor(client: Client, opts: DisTubeOptions = {}) {\n super();\n this.setMaxListeners(1);\n if (!isClientInstance(client)) throw new DisTubeError(\"INVALID_TYPE\", \"Discord.Client\", client, \"client\");\n this.client = client;\n checkIntents(client.options);\n this.options = new Options(opts);\n this.voices = new DisTubeVoiceManager(this);\n this.handler = new DisTubeHandler(this);\n this.queues = new QueueManager(this);\n this.filters = { ...defaultFilters, ...this.options.customFilters };\n this.plugins = [...this.options.plugins];\n this.plugins.forEach(p => p.init(this));\n }\n\n static get version() {\n return version;\n }\n\n /**\n * DisTube version\n */\n get version() {\n return version;\n }\n\n /**\n * Play / add a song or playlist from url.\n * Search and play a song (with {@link ExtractorPlugin}) if it is not a valid url.\n * @throws {@link DisTubeError}\n * @param voiceChannel - The channel will be joined if the bot isn't in any channels, the bot will be\n * moved to this channel if {@link DisTubeOptions}.joinNewVoiceChannel is `true`\n * @param song - URL | Search string | {@link Song} | {@link Playlist}\n * @param options - Optional options\n */\n async play<T = unknown>(\n voiceChannel: VoiceBasedChannel,\n song: string | Song | Playlist,\n options: PlayOptions<T> = {},\n ): Promise<void> {\n if (!isSupportedVoiceChannel(voiceChannel)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"BaseGuildVoiceChannel\", voiceChannel, \"voiceChannel\");\n }\n if (!isObject(options)) throw new DisTubeError(\"INVALID_TYPE\", \"object\", options, \"options\");\n\n const { textChannel, member, skip, message, metadata } = {\n member: voiceChannel.guild.members.me ?? undefined,\n textChannel: options?.message?.channel,\n skip: false,\n ...options,\n };\n const position = Number(options.position) || (skip ? 1 : 0);\n\n if (message && !isMessageInstance(message)) {\n throw new DisTubeError(\"INVALID_TYPE\", [\"Discord.Message\", \"a falsy value\"], message, \"options.message\");\n }\n if (textChannel && !isTextChannelInstance(textChannel)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"Discord.GuildTextBasedChannel\", textChannel, \"options.textChannel\");\n }\n if (member && !isMemberInstance(member)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"Discord.GuildMember\", member, \"options.member\");\n }\n\n const queue = this.getQueue(voiceChannel) || (await this.queues.create(voiceChannel, textChannel));\n await queue._taskQueue.queuing();\n try {\n this.debug(`[${queue.id}] Playing input: ${song}`);\n const resolved = await this.handler.resolve(song, { member, metadata });\n const isNsfw = isNsfwChannel(queue?.textChannel || textChannel);\n if (resolved instanceof Playlist) {\n if (!this.options.nsfw && !isNsfw) {\n resolved.songs = resolved.songs.filter(s => !s.ageRestricted);\n if (!resolved.songs.length) throw new DisTubeError(\"EMPTY_FILTERED_PLAYLIST\");\n }\n if (!resolved.songs.length) throw new DisTubeError(\"EMPTY_PLAYLIST\");\n this.debug(`[${queue.id}] Adding playlist to queue: ${resolved.songs.length} songs`);\n queue.addToQueue(resolved.songs, position);\n if (queue.playing || this.options.emitAddListWhenCreatingQueue) this.emit(Events.ADD_LIST, queue, resolved);\n } else {\n if (!this.options.nsfw && resolved.ageRestricted && !isNsfwChannel(queue?.textChannel || textChannel)) {\n throw new DisTubeError(\"NON_NSFW\");\n }\n this.debug(`[${queue.id}] Adding song to queue: ${resolved.name || resolved.url || resolved.id || resolved}`);\n queue.addToQueue(resolved, position);\n if (queue.playing || this.options.emitAddSongWhenCreatingQueue) this.emit(Events.ADD_SONG, queue, resolved);\n }\n\n if (!queue.playing) await queue.play();\n } catch (e: any) {\n if (!(e instanceof DisTubeError)) {\n this.debug(`[${queue.id}] Unexpected error while playing song: ${e.stack || e.message}`);\n try {\n e.name = \"PlayError\";\n e.message = `${typeof song === \"string\" ? song : song.url}\\n${e.message}`;\n } catch {\n // Throw original error\n }\n }\n throw e;\n } finally {\n queue._taskQueue.resolve();\n }\n }\n\n /**\n * Create a custom playlist\n * @param songs - Array of url or Song\n * @param options - Optional options\n */\n async createCustomPlaylist(\n songs: (string | Song)[],\n { member, parallel, metadata, name, source, url, thumbnail }: CustomPlaylistOptions = {},\n ): Promise<Playlist> {\n if (!Array.isArray(songs)) throw new DisTubeError(\"INVALID_TYPE\", \"Array\", songs, \"songs\");\n if (!songs.length) throw new DisTubeError(\"EMPTY_ARRAY\", \"songs\");\n const filteredSongs = songs.filter(song => song instanceof Song || isURL(song));\n if (!filteredSongs.length) throw new DisTubeError(\"NO_VALID_SONG\");\n if (member && !isMemberInstance(member)) {\n throw new DisTubeError(\"INVALID_TYPE\", \"Discord.Member\", member, \"options.member\");\n }\n let resolvedSongs: Song[];\n if (parallel !== false) {\n const promises = filteredSongs.map((song: string | Song) =>\n this.handler.resolve(song, { member, metadata }).catch(() => undefined),\n );\n resolvedSongs = (await Promise.all(promises)).filter((s): s is Song => s instanceof Song);\n } else {\n resolvedSongs = [];\n for (const song of filteredSongs) {\n const resolved = await this.handler.resolve(song, { member, metadata }).catch(() => undefined);\n if (resolved instanceof Song) resolvedSongs.push(resolved);\n }\n }\n return new Playlist(\n {\n source: source || \"custom\",\n name,\n url,\n thumbnail: thumbnail || resolvedSongs.find(s => s.thumbnail)?.thumbnail,\n songs: resolvedSongs,\n },\n { member, metadata },\n );\n }\n\n /**\n * Get the guild queue\n * @param guild - The type can be resolved to give a {@link Queue}\n */\n getQueue(guild: GuildIdResolvable): Queue | undefined {\n return this.queues.get(guild);\n }\n\n #getQueue(guild: GuildIdResolvable): Queue {\n const queue = this.getQueue(guild);\n if (!queue) throw new DisTubeError(\"NO_QUEUE\");\n return queue;\n }\n\n /**\n * Pause the guild stream\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The guild queue\n */\n pause(guild: GuildIdResolvable): Queue {\n return this.#getQueue(guild).pause();\n }\n\n /**\n * Resume the guild stream\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The guild queue\n */\n resume(guild: GuildIdResolvable): Queue {\n return this.#getQueue(guild).resume();\n }\n\n /**\n * Stop the guild stream\n * @param guild - The type can be resolved to give a {@link Queue}\n */\n stop(guild: GuildIdResolvable): Promise<void> {\n return this.#getQueue(guild).stop();\n }\n\n /**\n * Set the guild stream's volume\n * @param guild - The type can be resolved to give a {@link Queue}\n * @param percent - The percentage of volume you want to set\n * @returns The guild queue\n */\n setVolume(guild: GuildIdResolvable, percent: number): Queue {\n return this.#getQueue(guild).setVolume(percent);\n }\n\n /**\n * Skip the playing song if there is a next song in the queue. <info>If {@link\n * Queue#autoplay} is `true` and there is no up next song, DisTube will add and\n * play a related song.</info>\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The new Song will be played\n */\n skip(guild: GuildIdResolvable): Promise<Song> {\n return this.#getQueue(guild).skip();\n }\n\n /**\n * Play the previous song\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The new Song will be played\n */\n previous(guild: GuildIdResolvable): Promise<Song> {\n return this.#getQueue(guild).previous();\n }\n\n /**\n * Shuffle the guild queue songs\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The guild queue\n */\n shuffle(guild: GuildIdResolvable): Promise<Queue> {\n return this.#getQueue(guild).shuffle();\n }\n\n /**\n * Jump to the song number in the queue. The next one is 1, 2,... The previous one\n * is -1, -2,...\n * @param guild - The type can be resolved to give a {@link Queue}\n * @param num - The song number to play\n * @returns The new Song will be played\n */\n jump(guild: GuildIdResolvable, num: number): Promise<Song> {\n return this.#getQueue(guild).jump(num);\n }\n\n /**\n * Set the repeat mode of the guild queue.\n * Toggle mode `(Disabled -> Song -> Queue -> Disabled ->...)` if `mode` is `undefined`\n * @param guild - The type can be resolved to give a {@link Queue}\n * @param mode - The repeat modes (toggle if `undefined`)\n * @returns The new repeat mode\n */\n setRepeatMode(guild: GuildIdResolvable, mode?: RepeatMode): RepeatMode {\n return this.#getQueue(guild).setRepeatMode(mode);\n }\n\n /**\n * Toggle autoplay mode\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns Autoplay mode state\n */\n toggleAutoplay(guild: GuildIdResolvable): boolean {\n const queue = this.#getQueue(guild);\n queue.autoplay = !queue.autoplay;\n return queue.autoplay;\n }\n\n /**\n * Add related song to the queue\n * @param guild - The type can be resolved to give a {@link Queue}\n * @returns The guild queue\n */\n addRelatedSong(guild: GuildIdResolvable): Promise<Song> {\n return this.#getQueue(guild).addRelatedSong();\n }\n\n /**\n * Set the playing time to another position\n * @param guild - The type can be resolved to give a {@link Queue}\n * @param time - Time in seconds\n * @returns Seeked queue\n */\n seek(guild: GuildIdResolvable, time: number): Queue {\n return this.#getQueue(guild).seek(time);\n }\n\n /**\n * Emit error event\n * @param error - error\n * @param queue - The queue encountered the error\n * @param song - The playing song when encountered the error\n */\n emitError(error: Error, queue: Queue, song?: Song): void {\n this.emit(Events.ERROR, error, queue, song);\n }\n\n /**\n * Emit debug event\n * @param message - debug message\n */\n debug(message: string) {\n this.emit(Events.DEBUG, message);\n }\n}\n\nexport default DisTube;\n"],"mappings":"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","names":["exports","module","Events","RepeatMode","PluginType","_metadata","_member","import_tiny_typed_emitter","import_voice","process","version","import_discord","import_voice","import_discord","import_tiny_typed_emitter"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "distube",
3
- "version": "5.0.1",
3
+ "version": "5.0.2",
4
4
  "description": "A powerful Discord.js module for simplifying music commands and effortless playback of various sources with integrated audio filters.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -41,34 +41,29 @@
41
41
  "undici": "^6.18.2"
42
42
  },
43
43
  "devDependencies": {
44
- "@babel/core": "^7.24.6",
45
- "@babel/plugin-transform-class-properties": "^7.24.6",
46
- "@babel/plugin-transform-object-rest-spread": "^7.24.6",
47
- "@babel/plugin-transform-private-methods": "^7.24.6",
48
- "@babel/preset-env": "^7.24.6",
49
- "@babel/preset-typescript": "^7.24.6",
50
44
  "@commitlint/cli": "^19.3.0",
51
45
  "@commitlint/config-conventional": "^19.2.2",
52
46
  "@discordjs/voice": "^0.17.0",
53
- "@types/jest": "^29.5.12",
54
- "@types/node": "^20.14.1",
47
+ "@types/node": "^20.14.2",
55
48
  "@types/tough-cookie": "^4.0.5",
56
- "@typescript-eslint/eslint-plugin": "^7.12.0",
57
- "@typescript-eslint/parser": "^7.12.0",
58
- "babel-jest": "^29.7.0",
49
+ "@typescript-eslint/eslint-plugin": "^7.13.0",
50
+ "@typescript-eslint/parser": "^7.13.0",
51
+ "@vitest/coverage-v8": "^1.6.0",
59
52
  "discord.js": "^14.15.3",
60
53
  "eslint": "^8.57.0",
61
54
  "eslint-config-distube": "^1.7.0",
62
55
  "husky": "^9.0.11",
63
- "jest": "^29.7.0",
64
56
  "nano-staged": "^0.8.0",
65
- "prettier": "^3.3.0",
57
+ "prettier": "^3.3.2",
66
58
  "sodium-native": "^4.1.1",
67
59
  "ts-node": "^10.9.2",
68
60
  "tsup": "^8.1.0",
69
61
  "typedoc": "^0.25.13",
70
62
  "typedoc-material-theme": "^1.0.2",
71
- "typescript": "^5.4.5"
63
+ "typedoc-plugin-extras": "^3.0.0",
64
+ "typescript": "^5.4.5",
65
+ "vite-tsconfig-paths": "^4.3.2",
66
+ "vitest": "^1.6.0"
72
67
  },
73
68
  "peerDependencies": {
74
69
  "@discordjs/voice": "*",
@@ -87,14 +82,13 @@
87
82
  "node": ">=18.17"
88
83
  },
89
84
  "scripts": {
90
- "test": "jest",
85
+ "test": "VITE_CJS_IGNORE_WARNING=true vitest run",
91
86
  "docs": "typedoc",
92
87
  "lint": "prettier --check . && eslint .",
93
88
  "lint:fix": "eslint . --fix",
94
89
  "prettier": "prettier --write \"**/*.{ts,json,yml,yaml,md}\"",
95
90
  "build": "tsup",
96
- "build:check": "tsc --noEmit",
97
- "update": "pnpm up -L \"!eslint\"",
98
- "dev:add-docs-to-worktree": "git worktree add --track -b docs docs origin/docs"
91
+ "type": "tsc --noEmit",
92
+ "update": "pnpm up -L \"!eslint\""
99
93
  }
100
94
  }