UNPKG

lavalink-client

Version:

Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.

1,239 lines (1,232 loc) 139 kB
import { EventEmitter } from 'events'; declare class FilterManager { static EQList: { BassboostEarrape: EQBand[]; BassboostHigh: EQBand[]; BassboostMedium: EQBand[]; BassboostLow: EQBand[]; BetterMusic: EQBand[]; Rock: EQBand[]; Classic: EQBand[]; Pop: EQBand[]; Electronic: EQBand[]; FullSound: EQBand[]; Gaming: EQBand[]; }; /** The Equalizer bands currently applied to the Lavalink Server */ equalizerBands: EQBand[]; /** Private Util for the instaFix Filters option */ filterUpdatedState: boolean; /** All "Active" / "disabled" Player Filters */ filters: PlayerFilters; /** The Filter Data sent to Lavalink, only if the filter is enabled (ofc.) */ data: FilterData; /** The Player assigned to this Filter Manager */ player: Player; private get _LManager(); /** * Returns wether the plugin validations are enabled or not */ private get _checkForPlugins(); /** * Returns wether the source validations are enabled or not */ private get _checkForSources(); /** The Constructor for the FilterManager */ constructor(player: Player); /** * Apply Player filters for lavalink filter sending data, if the filter is enabled / not * * @returns {Promise<void>} * * @example * ```ts * // Apply the filters after changing them manually: * player.filterManager.data.volume = 0.5; * // maybe you wanna manually set a distorition filter? then do it like this... * player.filterManager.data.distortion = { sinOffset: 0.5, sinScale: 2, cosOffset: 0.5, cosScale: 2, tanOffset: 0.5, tanScale: 2, offset: 0.5, scale: 2 }; * await player.filterManager.applyPlayerFilters(); * ``` */ applyPlayerFilters(): Promise<void>; private privateNot0; private getLavalinkFilterData; /** * Checks if the filters are correctly stated (active / not-active) - mostly used internally. * @param oldFilterTimescale * @returns {boolean} True, if the check was successfull * * @example * ```ts * // Check the filter states * player.filterManager.checkFiltersState(); * // Apply the filters after checking * await player.filterManager.applyPlayerFilters(); * ``` */ checkFiltersState(oldFilterTimescale?: Partial<TimescaleFilter>): boolean; /** * Reset all Filters * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Reset all filters * await player.filterManager.resetFilters(); * ``` */ resetFilters(): Promise<FilterManager>; /** * Set the Filter Volume * @param volume the volume (0.0 - 5.0) * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Set Volume to 50% * await player.filterManager.setVolume(0.5); * // note this is a filter, so it will "jump" to the volume, i think it's like a "volume boost effect" so i marketed it as a filter * ``` */ setVolume(volume: number): Promise<this>; /** * Set the AudioOutput Filter * @param {AudioOutputs} type the audio output type * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Set Audio Output to Mono * await player.filterManager.setAudioOutput("mono"); * * // Set Audio Output to Stereo * await player.filterManager.setAudioOutput("stereo"); * * // Set Audio Output to Left * await player.filterManager.setAudioOutput("left"); * * // Set Audio Output to Right * await player.filterManager.setAudioOutput("right"); * ``` */ setAudioOutput(type: AudioOutputs): Promise<FilterManager>; /** * Set custom filter.timescale#speed . This method disabled both: nightcore & vaporwave. use 1 to reset it to normal * @param {number} speed set the speed of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Set Speed to 1.25 (disableds nightcore and vaporwave effect which are pre-made timescale settings of rate,pitch and speed) * await player.filterManager.setSpeed(1.25); * ``` */ setSpeed(speed?: number): Promise<FilterManager>; /** * Set custom filter.timescale#pitch . This method disabled both: nightcore & vaporwave. use 1 to reset it to normal * @param {number} pitch set the pitch of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Set Pitch to 1.25 (disableds nightcore and vaporwave effect which are pre-made timescale settings of rate,pitch and speed) * await player.filterManager.setPitch(1.25); * ``` */ setPitch(pitch?: number): Promise<FilterManager>; /** * Set custom filter.timescale#rate . This method disabled both: nightcore & vaporwave. use 1 to reset it to normal * @param {number} rate set the rate of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Set Rate to 1.25 (disableds nightcore and vaporwave effect which are pre-made timescale settings of rate,pitch and speed) * await player.filterManager.setRate(1.25); * ``` */ setRate(rate?: number): Promise<FilterManager>; /** * Enables / Disables the rotation effect, (Optional: provide your Own Data) * @param {number} rotationHz set the rotationHz of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Rotation filter with custom settings * await player.filterManager.toggleRotation(0.4); * // or use the defaults * await player.filterManager.toggleRotation(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleRotation(rotationHz?: number): Promise<FilterManager>; /** * Enables / Disables the Vibrato effect, (Optional: provide your Own Data) * @param {number} frequency set the frequency of the filter * @param {number} depth set the depth of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Vibrato filter with custom settings * await player.filterManager.toggleVibrato(8, 0.5); * // or use the defaults * await player.filterManager.toggleVibrato(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleVibrato(frequency?: number, depth?: number): Promise<FilterManager>; /** * Enables / Disables the Tremolo effect, (Optional: provide your Own Data) * @param {number} frequency set the frequency of the filter * @param {number} depth set the depth of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Tremolo filter with custom settings * await player.filterManager.toggleTremolo(5, 0.7); * // or use the defaults * await player.filterManager.toggleTremolo(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleTremolo(frequency?: number, depth?: number): Promise<FilterManager>; /** * Enables / Disables the LowPass effect, (Optional: provide your Own Data) * @param {number} smoothing set the smoothing of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle LowPass filter with custom settings * await player.filterManager.toggleLowPass(30); * // or use the defaults * await player.filterManager.toggleLowPass(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleLowPass(smoothing?: number): Promise<FilterManager>; /** * Lavalink LavaDspx Plugin Filters */ lavalinkLavaDspxPlugin: { /** * Enables / Disables the LowPass effect, (Optional: provide your Own Data) * @param {number} boostFactor set the boost factor of the filter * @param {number} cutoffFrequency set the cutoff frequency of the filter * @returns {Promise<boolean>} the state of the filter after execution. * * @example * ```ts * // Toggle LowPass filter with custom settings * await player.filterManager.lavalinkLavaDspxPlugin.toggleLowPass(1.2, 300); * // or use the defaults * await player.filterManager.lavalinkLavaDspxPlugin.toggleLowPass(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleLowPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<FilterManager>; /** * Enables / Disables the HighPass effect, (Optional: provide your Own Data) * @param {number} boostFactor [] set the boost factor of the filter * @param {number} cutoffFrequency set the cutoff frequency of the filter * @returns {Promise<boolean>} the state of the filter after execution. * * @example * ```ts * // Toggle HighPass filter with custom settings * await player.filterManager.lavalinkLavaDspxPlugin.toggleHighPass(1.2, 150); // custom values * // or use the defaults * await player.filterManager.lavalinkLavaDspxPlugin.toggleHighPass(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleHighPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<FilterManager>; /** * Enables / Disables the Normalization effect. * @param {number} [maxAmplitude=0.75] - The maximum amplitude of the audio. * @param {boolean} [adaptive=true] Whether to use adaptive normalization or not. * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Normalization filter with custom settings * await player.filterManager.lavalinkLavaDspxPlugin.toggleNormalization(0.9, false); // custom values * // or use the defaults * await player.filterManager.lavalinkLavaDspxPlugin.toggleNormalization(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleNormalization: (maxAmplitude?: number, adaptive?: boolean) => Promise<FilterManager>; /** * Enables / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data) * @param {number} [decay=0.5] The decay of the echo effect. * @param {number} [echoLength=0.5] The length of the echo effect. * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Echo filter with custom settings * await player.filterManager.lavalinkLavaDspxPlugin.toggleEcho(0.7, 0.6); // custom values * // or use the defaults * await player.filterManager.lavalinkLavaDspxPlugin.toggleEcho(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleEcho: (decay?: number, echoLength?: number) => Promise<FilterManager>; }; /** * LavalinkFilter Plugin specific Filters */ lavalinkFilterPlugin: { /** * Enables / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data) * @param {number} delay set the delay of the echo * @param {number} decay set the decay of the echo * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Echo filter with custom settings * await player.filterManager.lavalinkFilterPlugin.toggleEcho(3, 0.7); // custom values * // or use the defaults * await player.filterManager.lavalinkFilterPlugin.toggleEcho(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleEcho: (delay?: number, decay?: number) => Promise<FilterManager>; /** * Enables / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data) * @param {number} delays set the delays of the reverb * @param {number} gains set the gains of the reverb * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Reverb filter with custom settings * await player.filterManager.lavalinkFilterPlugin.toggleReverb([0.04, 0.045, 0.05, 0.055], [0.85, 0.84, 0.83, 0.82]); * // or use the defaults * await player.filterManager.lavalinkFilterPlugin.toggleReverb(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleReverb: (delays?: number[], gains?: number[]) => Promise<FilterManager>; }; /** * Enables / Disables a Nightcore-like filter Effect. Disables/Overrides both: custom and Vaporwave Filter * @param {number} speed set the speed of the filter * @param {number} pitch set the pitch of the filter * @param {number} rate set the rate of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Nightcore filter with custom settings * await player.filterManager.toggleNightcore(1.3, 1.3, 0.9); * // or use the defaults * await player.filterManager.toggleNightcore(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleNightcore(speed?: number, pitch?: number, rate?: number): Promise<FilterManager>; /** * Enables / Disables a Vaporwave-like filter Effect. Disables/Overrides both: custom and nightcore Filter * @param {number} speed set the speed of the filterq * @param {number} pitch set the pitch of the filter * @param {number} rate set the rate of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Vaporwave filter with custom settings * await player.filterManager.toggleVaporwave(0.9, 0.7, 1); * // or use the defaults * await player.filterManager.toggleVaporwave(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleVaporwave(speed?: number, pitch?: number, rate?: number): Promise<FilterManager>; /** * Enable / Disables a Karaoke like Filter Effect * @param {number} level set the level of the filter * @param {number} monoLevel set the mono level of the filter * @param {number} filterBand set the filter band of the filter * @param {number} filterWidth set the filter width of the filter * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Toggle Karaoke filter with custom settings * await player.filterManager.toggleKaraoke(1.5, 1.0, 220, 100); * // or use the defaults * await player.filterManager.toggleKaraoke(); * // when it's enabled before calling the toggle function, it disables it, so you might need to do some if/else logic. * ``` */ toggleKaraoke(level?: number, monoLevel?: number, filterBand?: number, filterWidth?: number): Promise<FilterManager>; /** * Function to find out if currently there is a custom timescamle etc. filter applied * @returns {boolean} whether a custom filter is active * * @example * ```ts * // Check if a custom filter is active * const isCustom = player.filterManager.isCustomFilterActive(); * console.log(`Is custom filter active? ${isCustom}`); * ``` */ isCustomFilterActive(): boolean; /** * Sets the players equalizer bands using one of the predefined presets. * @param {keyof typeof EQList} preset The preset to use. * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Set EQ preset * await player.filterManager.setEQPreset('BassboostMedium'); * ``` */ setEQPreset(preset: keyof typeof EQList): Promise<this>; /** * Sets the players equalizer band on-top of the existing ones. * @param {number} bands * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Set EQ bands * await player.filterManager.setEQ([ * { band: 0, gain: 0.3 }, * { band: 1, gain: -0.2 }, * { band: 2, gain: 0.1 } * ]); * * // or use one of the templates: * await player.filterManager.setEQ(player.filterManager.EQList.BassboostMedium); // you can also import EQList from somewhere package if wanted. * ``` */ setEQ(bands: EQBand | EQBand[]): Promise<this>; /** * Clears the equalizer bands. * @returns {Promise<FilterManager>} The Filter Manager, for chaining. * * @example * ```ts * // Clear all EQ bands * await player.filterManager.clearEQ(); * ``` */ clearEQ(): Promise<this>; } /** Sourcenames provided by lavalink server */ type LavalinkSourceNames = "youtube" | "youtubemusic" | "soundcloud" | "bandcamp" | "twitch"; /** Source Names provided by lava src plugin */ type LavalinkPlugin_LavaSrc_SourceNames = "deezer" | "spotify" | "applemusic" | "yandexmusic" | "flowery-tts" | "vkmusic" | "tidal" | "qobuz" | "pandora"; /** Source Names provided by jiosaavan plugin */ type LavalinkPlugin_JioSaavn_SourceNames = "jiosaavn"; /** The SourceNames provided by lavalink */ type SourceNames = LavalinkSourceNames | LavalinkPlugin_LavaSrc_SourceNames | LavalinkPlugin_JioSaavn_SourceNames; interface LavalinkTrackInfo { /** The Identifier of the Track */ identifier: string; /** The Track Title / Name */ title: string; /** The Name of the Author */ author: string; /** The duration of the Track */ length: number; /** The URL of the artwork if available */ artworkUrl: string | null; /** The URL (aka Link) of the Track called URI */ uri: string; /** The Source name of the Track, e.g. soundcloud, youtube, spotify */ sourceName: SourceNames; /** Wether the audio is seekable */ isSeekable: boolean; /** Wether the audio is of a live stream */ isStream: boolean; /** If isrc code is available, it's provided */ isrc: string | null; } interface TrackInfo { /** The Identifier of the Track */ identifier: string; /** The Track Title / Name */ title: string; /** The Name of the Author */ author: string; /** The duration of the Track */ duration: number; /** The URL of the artwork if available */ artworkUrl: string | null; /** The URL (aka Link) of the Track called URI */ uri: string; /** The Source name of the Track, e.g. soundcloud, youtube, spotify */ sourceName: SourceNames; /** Wether the audio is seekable */ isSeekable: boolean; /** Wether the audio is of a live stream */ isStream: boolean; /** If isrc code is available, it's provided */ isrc: string | null; } interface PluginInfo { /** The Type provided by a plugin */ type?: "album" | "playlist" | "artist" | "recommendations" | string; /** The Identifier provided by a plugin */ albumName?: string; /** The url of the album */ albumUrl?: string; /** The url of the album art */ albumArtUrl?: string; /** The url of the artist */ artistUrl?: string; /** The url of the artist artwork */ artistArtworkUrl?: string; /** The url of the preview */ previewUrl?: string; /** Whether the track is a preview */ isPreview?: boolean; /** The total number of tracks in the playlist */ totalTracks?: number; /** The Identifier provided by a plugin */ identifier?: string; /** The ArtworkUrl provided by a plugin */ artworkUrl?: string; /** The Author Information provided by a plugin */ author?: string; /** The Url provided by a Plugin */ url?: string; /** The Url provided by a Plugin */ uri?: string; /** You can put specific track information here, to transform the tracks... */ clientData?: { previousTrack?: boolean; [key: string]: any; }; } interface LavalinkTrack { /** The Base 64 encoded String */ encoded?: Base64; /** Track Information */ info: LavalinkTrackInfo; /** Plugin Information from Lavalink */ pluginInfo: Partial<PluginInfo>; /** The userData Object from when you provide to the lavalink request */ userData?: anyObject; } interface Track { /** The Base 64 encoded String */ encoded?: Base64; /** Track Information */ info: TrackInfo; /** Plugin Information from Lavalink */ pluginInfo: Partial<PluginInfo>; /** The Track's Requester */ requester?: unknown; /** The userData Object from when you provide to the lavalink request */ userData?: anyObject; } interface UnresolvedTrackInfo extends Partial<TrackInfo> { /** Required */ title: string; } interface UnresolvedQuery extends UnresolvedTrackInfo { /** The base64 of the unresolved track to "encode" */ encoded?: Base64; } interface UnresolvedTrack { /** Required */ resolve: (player: Player) => Promise<void>; /** The Base 64 encoded String */ encoded?: Base64; /** Track Information */ info: UnresolvedTrackInfo; /** Plugin Information from Lavalink */ pluginInfo: Partial<PluginInfo>; /** The userData Object from when you provide to the lavalink request */ userData?: anyObject; /** The Track's Requester */ requester?: unknown; } interface StoredQueue { current: Track | null; previous: Track[]; tracks: (Track | UnresolvedTrack)[]; } interface QueueStoreManager { /** @async get a Value (MUST RETURN UNPARSED!) */ get: (guildId: string) => Awaitable<StoredQueue | string | undefined>; /** @async Set a value inside a guildId (MUST BE UNPARSED) */ set: (guildId: string, value: StoredQueue | string) => Awaitable<void | boolean>; /** @async Delete a Database Value based of it's guildId */ delete: (guildId: string) => Awaitable<void | boolean>; /** @async Transform the value(s) inside of the QueueStoreManager (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */ stringify: (value: StoredQueue | string) => Awaitable<StoredQueue | string>; /** @async Parse the saved value back to the Queue (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */ parse: (value: StoredQueue | string) => Awaitable<Partial<StoredQueue>>; } interface ManagerQueueOptions { /** Maximum Amount of tracks for the queue.previous array. Set to 0 to not save previous songs. Defaults to 25 Tracks */ maxPreviousTracks?: number; /** Custom Queue Store option */ queueStore?: QueueStoreManager; /** Custom Queue Watcher class */ queueChangesWatcher?: QueueChangesWatcher; } interface QueueChangesWatcher { /** get a Value (MUST RETURN UNPARSED!) */ tracksAdd: (guildId: string, tracks: (Track | UnresolvedTrack)[], position: number, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => void; /** Set a value inside a guildId (MUST BE UNPARSED) */ tracksRemoved: (guildId: string, tracks: (Track | UnresolvedTrack)[], position: number | number[], oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => void; /** Set a value inside a guildId (MUST BE UNPARSED) */ shuffled: (guildId: string, oldStoredQueue: StoredQueue, newStoredQueue: StoredQueue) => void; } declare class QueueSaver { /** * The queue store manager */ private _; /** * The options for the queue saver */ options: { maxPreviousTracks: number; }; constructor(options: ManagerQueueOptions); /** * Get the queue for a guild * @param guildId The guild ID * @returns The queue for the guild */ get(guildId: string): Promise<Partial<StoredQueue>>; /** * Delete the queue for a guild * @param guildId The guild ID * @returns The queue for the guild */ delete(guildId: string): Promise<boolean | void>; /** * Set the queue for a guild * @param guildId The guild ID * @param valueToStringify The queue to set * @returns The queue for the guild */ set(guildId: string, valueToStringify: StoredQueue): Promise<boolean | void>; /** * Sync the queue for a guild * @param guildId The guild ID * @returns The queue for the guild */ sync(guildId: string): Promise<Partial<StoredQueue>>; } declare class DefaultQueueStore implements QueueStoreManager { private data; constructor(); /** * Get the queue for a guild * @param guildId The guild ID * @returns The queue for the guild */ get(guildId: string): StoredQueue | undefined; /** * Set the queue for a guild * @param guildId The guild ID * @param valueToStringify The queue to set * @returns The queue for the guild */ set(guildId: string, valueToStringify: any): boolean; /** * Delete the queue for a guild * @param guildId The guild ID * @returns The queue for the guild */ delete(guildId: string): boolean; /** * Stringify the queue for a guild * @param value The queue to stringify * @returns The stringified queue */ stringify(value: StoredQueue | string): StoredQueue | string; /** * Parse the queue for a guild * @param value The queue to parse * @returns The parsed queue */ parse(value: StoredQueue | string): Partial<StoredQueue>; } declare class Queue { readonly tracks: (Track | UnresolvedTrack)[]; readonly previous: Track[]; current: Track | null; options: { maxPreviousTracks: number; }; private readonly guildId; private readonly QueueSaver; private managerUtils; private queueChanges; /** * Create a new Queue * @param guildId The guild ID * @param data The data to initialize the queue with * @param QueueSaver The queue saver to use * @param queueOptions */ constructor(guildId: string, data?: Partial<StoredQueue>, QueueSaver?: QueueSaver, queueOptions?: ManagerQueueOptions); /** * Utils for a Queue */ utils: { /** * Save the current cached Queue on the database/server (overides the server) */ save: () => Promise<boolean | void>; /** * Sync the current queue database/server with the cached one * @returns {void} */ sync: (override?: boolean, dontSyncCurrent?: boolean) => Promise<void>; destroy: () => Promise<boolean | void>; /** * @returns {{current:Track|null, previous:Track[], tracks:Track[]}}The Queue, but in a raw State, which allows easier handling for the QueueStoreManager */ toJSON: () => StoredQueue; /** * Get the Total Duration of the Queue-Songs summed up * @returns {number} */ totalDuration: () => number; }; /** * Shuffles the current Queue, then saves it * @returns Amount of Tracks in the Queue */ shuffle(): Promise<number>; /** * Add a Track to the Queue, and after saved in the "db" it returns the amount of the Tracks * @param {Track | Track[]} TrackOrTracks * @param {number} index At what position to add the Track * @returns {number} Queue-Size (for the next Tracks) */ add(TrackOrTracks: Track | UnresolvedTrack | (Track | UnresolvedTrack)[], index?: number): any; /** * Splice the tracks in the Queue * @param {number} index Where to remove the Track * @param {number} amount How many Tracks to remove? * @param {Track | Track[]} TrackOrTracks Want to Add more Tracks? * @returns {Track} Spliced Track */ splice(index: number, amount: number, TrackOrTracks?: Track | UnresolvedTrack | (Track | UnresolvedTrack)[]): any; /** * Remove stuff from the queue.tracks array * - single Track | UnresolvedTrack * - multiple Track | UnresovedTrack * - at the index or multiple indexes * - Since v2.7 the removed tracks get unshifted into the previous queue state instead of pushed (indexed at the start instead of end - as it should) * @param removeQueryTrack * @returns null (if nothing was removed) / { removed } where removed is an array with all removed elements * * @example * ```js * // remove single track * * const track = player.queue.tracks[4]; * await player.queue.remove(track); * * // if you already have the index you can straight up pass it too * await player.queue.remove(4); * * * // if you want to remove multiple tracks, e.g. from position 4 to position 10 you can do smt like this * await player.queue.remove(player.queue.tracks.slice(4, 10)) // get's the tracks from 4 - 10, which then get's found in the remove function to be removed * * // I still highly suggest to use .splice! * * await player.queue.splice(4, 10); // removes at index 4, 10 tracks * * await player.queue.splice(1, 1); // removes at index 1, 1 track * * await player.queue.splice(4, 0, ...tracks) // removes 0 tracks at position 4, and then inserts all tracks after position 4. * ``` */ remove<T extends Track | UnresolvedTrack | number | Track[] | UnresolvedTrack[] | number[] | (number | Track | UnresolvedTrack)[]>(removeQueryTrack: T): Promise<{ removed: (Track | UnresolvedTrack)[]; } | null>; /** * Shifts the previous array, to return the last previous track & thus remove it from the previous queue * @returns * * @example * ```js * // example on how to play the previous track again * const previous = await player.queue.shiftPrevious(); // get the previous track and remove it from the previous queue array!! * if(!previous) return console.error("No previous track found"); * await player.play({ clientTrack: previous }); // play it again * ``` */ shiftPrevious(): Promise<Track>; } declare class Player { /** Filter Manager per player */ filterManager: FilterManager; /** circular reference to the lavalink Manager from the Player for easier use */ LavalinkManager: LavalinkManager; /** Player options currently used, mutation doesn't affect player's state */ options: PlayerOptions; /** The lavalink node assigned the the player, don't change it manually */ node: LavalinkNode; /** The queue from the player */ queue: Queue; /** The Guild Id of the Player */ guildId: string; /** The Voice Channel Id of the Player */ voiceChannelId: string | null; /** The Text Channel Id of the Player */ textChannelId: string | null; /** States if the Bot is supposed to be outputting audio */ playing: boolean; /** States if the Bot is paused or not */ paused: boolean; /** Repeat Mode of the Player */ repeatMode: RepeatMode; /** Player's ping */ ping: { lavalink: number; ws: number; }; /** The Display Volume */ volume: number; /** The Volume Lavalink actually is outputting */ lavalinkVolume: number; /** The current Positin of the player (Calculated) */ get position(): number; /** The timestamp when the last position change update happened */ lastPositionChange: number | null; /** The current Positin of the player (from Lavalink) */ lastPosition: number; lastSavedPosition: number; /** When the player was created [Timestamp in Ms] (from lavalink) */ createdTimeStamp: number; /** The Player Connection's State (from Lavalink) */ connected: boolean | undefined; /** Voice Server Data (from Lavalink) */ voice: LavalinkPlayerVoiceOptions; voiceState: { selfDeaf: boolean; selfMute: boolean; serverDeaf: boolean; serverMute: boolean; suppress: boolean; }; /** Custom data for the player */ private readonly data; /** * Emits a debug event to the LavalinkManager * @param name name of the event * @param eventData event data */ private _emitDebugEvent; /** * Create a new Player * @param options * @param LavalinkManager */ constructor(options: PlayerOptions, LavalinkManager: LavalinkManager, dontEmitPlayerCreateEvent?: boolean); /** * Set custom data. * @param key * @param value */ set(key: string, value: unknown): this; /** * Get custom data. * @param key */ get<T>(key: string): T; /** * CLears all the custom data. */ clearData(): this; /** * Get all custom Data */ getAllData(): Record<string, unknown>; /** * Play the next track from the queue / a specific track, with playoptions for Lavalink * @param options */ play(options?: Partial<PlayOptions>): any; /** * Set the Volume for the Player * @param volume The Volume in percent * @param ignoreVolumeDecrementer If it should ignore the volumedecrementer option */ setVolume(volume: number, ignoreVolumeDecrementer?: boolean): Promise<this>; /** * Search for a track * @param query The query to search for * @param requestUser The user that requested the track * @param throwOnEmpty If an error should be thrown if no track is found * @returns The search result */ lavaSearch(query: LavaSearchQuery, requestUser: unknown, throwOnEmpty?: boolean): Promise<LavaSearchResponse | SearchResult>; /** * Set the SponsorBlock * @param segments The segments to set */ setSponsorBlock(segments?: SponsorBlockSegment[]): Promise<void>; /** * Get the SponsorBlock */ getSponsorBlock(): Promise<SponsorBlockSegment[]>; /** * Delete the SponsorBlock */ deleteSponsorBlock(): Promise<void>; /** * * @param query Query for your data * @param requestUser */ search(query: SearchQuery, requestUser: unknown, throwOnEmpty?: boolean): Promise<UnresolvedSearchResult | SearchResult>; /** * Pause the player */ pause(): Promise<this>; /** * Resume the Player */ resume(): Promise<this>; /** * Seek to a specific Position * @param position */ seek(position: number): Promise<this>; /** * Set the Repeatmode of the Player * @param repeatMode */ setRepeatMode(repeatMode: RepeatMode): Promise<this>; /** * Skip the current song, or a specific amount of songs * @param amount provide the index of the next track to skip to */ skip(skipTo?: number, throwError?: boolean): Promise<this>; /** * Clears the queue and stops playing. Does not destroy the Player and not leave the channel * @returns */ stopPlaying(clearQueue?: boolean, executeAutoplay?: boolean): Promise<this>; /** * Connects the Player to the Voice Channel * @returns */ connect(): Promise<this>; changeVoiceState(data: { voiceChannelId?: string; selfDeaf?: boolean; selfMute?: boolean; }): Promise<this>; /** * Disconnects the Player from the Voice Channel, but keeps the player in the cache * @param force If false it throws an error, if player thinks it's already disconnected * @returns */ disconnect(force?: boolean): Promise<this>; /** * Destroy the player and disconnect from the voice channel */ destroy(reason?: DestroyReasons | string, disconnect?: boolean): Promise<this>; /** * Get the current lyrics of the track currently playing on the guild * @param guildId The guild id to get the current lyrics for * @param skipTrackSource If true, it will not try to get the lyrics from the track source * @returns The current lyrics * @example * ```ts * const lyrics = await player.getCurrentLyrics(); * ``` */ getCurrentLyrics(skipTrackSource?: boolean): Promise<LyricsResult>; /** * Get the lyrics of a specific track * @param track The track to get the lyrics for * @param skipTrackSource If true, it will not try to get the lyrics from the track source * @returns The lyrics of the track * @example * ```ts * const lyrics = await player.getLyrics(player.queue.tracks[0], true); * ``` */ getLyrics(track: Track, skipTrackSource?: boolean): Promise<LyricsResult>; /** * Subscribe to the lyrics event on a specific guild to active live lyrics events * @returns The unsubscribe function * @example * ```ts * const lyrics = await player.subscribeLyrics(); * ``` */ subscribeLyrics(): Promise<unknown>; /** * Unsubscribe from the lyrics event on a specific guild to disable live lyrics events * @returns The unsubscribe function * @example * ```ts * const lyrics = await player.unsubscribeLyrics(); * ``` */ unsubscribeLyrics(): Promise<void>; /** * Move the player on a different Audio-Node * @param newNode New Node / New Node Id * @param checkSources If it should check if the sources are supported by the new node @default true * @return The new Node Id * @example * ```ts * const changeNode = await player.changeNode(newNode, true); * ``` */ changeNode(newNode: LavalinkNode | string, checkSources?: boolean): Promise<string>; /** * (Wrapper-FN for changeNode) Move the player to a different node. If no node is provided, it will find the least used node that is not the same as the current node. * @param node the id of the node to move to * @returns the player * @throws RangeError if there is no available nodes. * @throws Error if the node to move to is the same as the current node. * @example * ```ts * const newNodeMovedTo = await player.moveNode(); // no need to specify the new node, it will find a least used node automatically, but you can ofc. use a custom node id. * ``` */ moveNode(node?: string): Promise<string | this>; /** Converts the Player including Queue to a Json state */ toJSON(): PlayerJson; } declare const TrackSymbol: unique symbol; declare const UnresolvedTrackSymbol: unique symbol; declare const QueueSymbol: unique symbol; declare const NodeSymbol: unique symbol; /** * Parses Node Connection Url: "lavalink://<nodeId>:<nodeAuthorization(Password)>@<NodeHost>:<NodePort>" * @param connectionUrl * @returns */ declare function parseLavalinkConnUrl(connectionUrl: string): { authorization: string; id: string; host: string; port: number; }; declare class ManagerUtils { LavalinkManager: LavalinkManager | undefined; constructor(LavalinkManager?: LavalinkManager); buildPluginInfo(data: any, clientData?: any): any; buildTrack(data: LavalinkTrack | Track, requester: unknown): Track; /** * Builds a UnresolvedTrack to be resolved before being played . * @param query * @param requester */ buildUnresolvedTrack(query: UnresolvedQuery | UnresolvedTrack, requester: unknown): UnresolvedTrack; /** * Validate if a data is equal to a node * @param data */ isNode(data: LavalinkNode): boolean; getTransformedRequester(requester: unknown): unknown; /** * Validate if a data is equal to node options * @param data */ isNodeOptions(data: LavalinkNodeOptions): boolean; /** * Validate tracks based on duration wether they are playble or broken tracks. * most tracks should be longer than 30s, so you can put a minDuration of 29e3 (cause preview tracks are exactly 30s) or put 0. * This check is not done automatically, you need to check it yourself by doing: * @example * ```ts * const res = await player.search("Adele"); * * // short hand: * const validTracks = res.tracks.filter(client.lavalink.utils.isNotBrokenTrack) * // or with options: * const validTracks = res.tracks.filter(t => client.lavalink.utils.isNotBrokenTrack(t, 29e3)); * * // then you can add it to the queue. * await player.queue.add(validTracks); * ``` */ isNotBrokenTrack(data: Track | UnresolvedTrack, minDuration?: number): data is Track; /** * Validate if a data is equal to a track * @param data the Track to validate * @returns */ isTrack(data: Track | UnresolvedTrack): data is Track; /** * Checks if the provided argument is a valid UnresolvedTrack. * @param track */ isUnresolvedTrack(data: UnresolvedTrack | Track): data is UnresolvedTrack; /** * Checks if the provided argument is a valid UnresolvedTrack. * @param track */ isUnresolvedTrackQuery(data: UnresolvedQuery): boolean; getClosestTrack(data: UnresolvedTrack, player: Player): Promise<Track | undefined>; validateQueryString(node: LavalinkNode, queryString: string, sourceString?: LavalinkSearchPlatform): void; transformQuery(query: SearchQuery): { query: string; extraQueryUrlParams: URLSearchParams; source: any; }; transformLavaSearchQuery(query: LavaSearchQuery): { query: string; types: string[]; source: any; }; validateSourceString(node: LavalinkNode, sourceString: SearchPlatform): void; } /** * Separate interface for the constructor so that emitted js does not have a constructor that overwrites itself * * @internal */ interface MiniMap<K, V> extends Map<K, V> { constructor: MiniMapConstructor; } declare class MiniMap<K, V> extends Map<K, V> { constructor(data?: [K, V][]); /** * Identical to * [Array.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), * but returns a MiniMap instead of an Array. * * @param fn The function to test with (should return boolean) * @param thisArg Value to use as `this` when executing function * * @example * miniMap.filter(user => user.username === 'Bob'); */ filter<K2 extends K>(fn: (value: V, key: K, miniMap: this) => key is K2): MiniMap<K2, V>; filter<V2 extends V>(fn: (value: V, key: K, miniMap: this) => value is V2): MiniMap<K, V2>; filter(fn: (value: V, key: K, miniMap: this) => boolean): MiniMap<K, V>; filter<This, K2 extends K>(fn: (this: This, value: V, key: K, miniMap: this) => key is K2, thisArg: This): MiniMap<K2, V>; filter<This, V2 extends V>(fn: (this: This, value: V, key: K, miniMap: this) => value is V2, thisArg: This): MiniMap<K, V2>; filter<This>(fn: (this: This, value: V, key: K, miniMap: this) => boolean, thisArg: This): MiniMap<K, V>; toJSON(): [K, V][]; /** * Maps each item to another value into an array. Identical in behavior to * [Array.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map). * * @param fn Function that produces an element of the new array, taking three arguments * @param thisArg Value to use as `this` when executing function * * @example * miniMap.map(user => user.tag); */ map<T>(fn: (value: V, key: K, miniMap: this) => T): T[]; map<This, T>(fn: (this: This, value: V, key: K, miniMap: this) => T, thisArg: This): T[]; } declare function queueTrackEnd(player: Player, dontShiftQueue?: boolean): Promise<Track>; declare function safeStringify(obj: any, padding?: number): string; /** Helper for generating Opaque types. */ type Opaque<T, K> = T & { __opaque__: K; }; /** Opqaue tyep for integernumber */ type IntegerNumber = Opaque<number, 'Int'>; /** Opqaue tyep for floatnumber */ type FloatNumber = Opaque<number, 'Float'>; type LavaSrcSearchPlatformBase = "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "dzrec" | "ymsearch" | "ymrec" | "vksearch" | "vkrec" | "tdsearch" | "tdrec" | "qbsearch" | "qbisrc" | "qbrec" | "pdsearch" | "pdisrc" | "pdrec"; type LavaSrcSearchPlatform = LavaSrcSearchPlatformBase | "ftts"; type JioSaavnSearchPlatform = "jssearch" | "jsrec"; type DuncteSearchPlatform = "speak" | "phsearch" | "pornhub" | "porn" | "tts"; type LavalinkClientSearchPlatform = "bcsearch"; type LavalinkClientSearchPlatformResolve = "bandcamp" | "bc"; type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | "bcsearch" | LavaSrcSearchPlatform | DuncteSearchPlatform | JioSaavnSearchPlatform | LavalinkClientSearchPlatform; type ClientCustomSearchPlatformUtils = "local" | "http" | "https" | "link" | "uri"; type ClientSearchPlatform = ClientCustomSearchPlatformUtils | // for file/link requests "youtube" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "musicyoutube" | "music youtube" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "musicapple" | "music apple" | "sp" | "spsuggestion" | "spotify" | "spotify.com" | "spotifycom" | "dz" | "deezer" | "yandex" | "yandex music" | "yandexmusic" | "vk" | "vk music" | "vkmusic" | "tidal" | "tidal music" | "qobuz" | "pandora" | "pd" | "pandora music" | "pandoramusic" | "flowerytts" | "flowery" | "flowery.tts" | LavalinkClientSearchPlatformResolve | LavalinkClientSearchPlatform | "js" | "jiosaavn" | "td" | "tidal" | "tdrec"; type SearchPlatform = LavalinkSearchPlatform | ClientSearchPlatform; type SourcesRegex = "YoutubeRegex" | "YoutubeMusicRegex" | "SoundCloudRegex" | "SoundCloudMobileRegex" | "DeezerTrackRegex" | "DeezerArtistRegex" | "DeezerEpisodeRegex" | "DeezerMixesRegex" | "DeezerPageLinkRegex" | "DeezerPlaylistRegex" | "DeezerAlbumRegex" | "AllDeezerRegex" | "AllDeezerRegexWithoutPageLink" | "SpotifySongRegex" | "SpotifyPlaylistRegex" | "SpotifyArtistRegex" | "SpotifyEpisodeRegex" | "SpotifyShowRegex" | "SpotifyAlbumRegex" | "AllSpotifyRegex" | "mp3Url" | "m3uUrl" | "m3u8Url" | "mp4Url" | "m4aUrl" | "wavUrl" | "aacpUrl" | "tiktok" | "mixcloud" | "musicYandex" | "radiohost" | "bandcamp" | "jiosaavn" | "appleMusic" | "tidal" | "PandoraTrackRegex" | "PandoraAlbumRegex" | "PandoraArtistRegex" | "PandoraPlaylistRegex" | "AllPandoraRegex" | "TwitchTv" | "vimeo"; interface PlaylistInfo { /** The playlist name */ name: string; /** The playlist title (same as name) */ title: string; /** The playlist Author */ author?: string; /** The playlist Thumbnail */ thumbnail?: string; /** A Uri to the playlist */ uri?: string; /** The playlist selected track. */ selectedTrack: Track | null; /** The duration of the entire playlist. (calcualted) */ duration: number; } interface SearchResult { loadType: LoadTypes; exception: Exception | null; pluginInfo: PluginInfo; playlist: PlaylistInfo | null; tracks: Track[]; } interface UnresolvedSearchResult { loadType: LoadTypes; exception: Exception | null; pluginInfo: PluginInfo; playlist: PlaylistInfo | null; tracks: UnresolvedTrack[]; } /** * @internal */ interface MiniMapConstructor { new (): MiniMap<unknown, unknown>; new <K, V>(entries?: ReadonlyArray<readonly [K, V]> | null): MiniMap<K, V>; new <K, V>(iterable: Iterable<readonly [K, V]>): MiniMap<K, V>; readonly prototype: MiniMap<unknown, unknown>; readonly [Symbol.species]: MiniMapConstructor; } type PlayerEvents = TrackStartEvent | TrackEndEvent | TrackStuckEvent | TrackExceptionEvent | WebSocketClosedEvent | SponsorBlockSegmentEvents | LyricsEvent; type Severity = "COMMON" | "SUSPICIOUS" | "FAULT"; interface Exception { /** Severity of the error */ severity: Severity; /** Nodejs Error */ error?: Error; /** Message by lavalink */ message: string; /** Cause by lavalink */ cause: string; /** causeStackTrace by lavalink */ causeStackTrace: string; } interface PlayerEvent { op: "event"; type: PlayerEventType; guildId: string; } interface TrackStartEvent extends PlayerEvent { type: "TrackStartEvent"; track: LavalinkTrack; } interface TrackEndEvent extends PlayerEvent { type: "TrackEndEvent"; track: LavalinkTrack; reason: TrackEndReason; } interface TrackExceptionEvent extends PlayerEvent { type: "TrackExceptionEvent"; exception?: Exception; track: LavalinkTrack; error: string; } interface TrackStuckEvent exte