lavalink-client
Version:
Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.
1,239 lines (1,232 loc) • 139 kB
TypeScript
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