Playback & filters
Playing
Section titled “Playing”player.play()
Section titled “player.play()”Accepts either a search string or a pre-resolved source:
// String query — searches and plays the first resultawait player.play("lofi hip hop", { guildId, voiceId });
// Pre-resolved Trackawait player.play(track, { guildId, voiceId });
// Array of Tracksawait player.play([track1, track2], { guildId, voiceId });
// Playlistawait player.play(playlist, { guildId, voiceId });When given a string, it searches using the queue’s node if a queue exists, or the best available node otherwise. If the result is of type query, it takes the first result.
If a queue already exists and is stopped, play() adds the track and calls resume(). If it’s already playing, the track is added to the end of the queue.
Volume
Section titled “Volume”Range is 0–1000. Default is 100. Values above 100 amplify and may clip.
await queue.setVolume(80);await queue.setVolume(0); // muteawait queue.setVolume(150); // amplify (may clip)Queue control
Section titled “Queue control”Every method exists on both Player (requires a guildId) and Queue (operates on itself). They’re identical in behaviour — use whichever is more convenient.
Transport
Section titled “Transport”// Via Playerawait player.pause(guildId);await player.resume(guildId);await player.stop(guildId);await player.seek(guildId, 30_000); // ms from start
// Via Queueconst queue = player.getQueue(guildId)!;await queue.pause();await queue.resume();await queue.stop();await queue.seek(30_000);stop() vs destroy() — stop() halts playback and clears Lavalink’s player track but keeps the queue intact locally.
resume() behaviour — if queue.stopped is true, resumes by calling jump(0) to restart the current track. Otherwise unpauses.
seek() behaviour — seeks to the given position in ms. Also unpauses if paused. Throws if the current track is not seekable or if ms exceeds the current track’s duration.
Navigation
Section titled “Navigation”await queue.next(); // advance one trackawait queue.previous(); // go back one trackawait queue.jump(3); // jump to index 3 in the current listawait queue.jump(0); // restart the current trackawait queue.jump(-1); // jump to the most recent previous trackawait queue.jump(-2); // jump two tracks backjump() always starts playback immediately and triggers trackStart. Throws if the queue is empty or the index is out of range.
next() with repeatMode: 'queue' — when the current list is exhausted and there are previous tracks, next() moves the oldest previous track to the end of the current list and jumps to it, cycling the queue.
next() with autoplay — when the current list is exhausted and autoplay is on, next() calls addRelated() and jumps to the first related track if any are returned.
Manipulation
Section titled “Manipulation”queue.remove(1); // remove by index → Track | undefinedqueue.remove([1, 3, 5]); // remove multiple → Track[]queue.remove(-1); // remove the most recent previous trackIndex 0 (the current track) can only be removed when queue.stopped is true.
queue.clear(); // remove everything (keeps current if playing)queue.clear("current"); // remove upcoming (+current if stopped)queue.clear("previous"); // remove history only
queue.shuffle(); // shuffle current tracks (index 1+), no-op if fewer than 3queue.shuffle(true); // pull all previous tracks into current, then shuffleRepeat and autoplay
Section titled “Repeat and autoplay”queue.setRepeatMode("none"); // play through once (default)queue.setRepeatMode("track"); // loop the current track indefinitelyqueue.setRepeatMode("queue"); // loop the entire queue
queue.setAutoplay(true);queue.setAutoplay(false);
// Add related tracks manually without enabling autoplayawait queue.addRelated();await queue.addRelated(specificTrack);Autoplay calls fetchRelatedTracks when the queue empties after a track finishes. The default returns [] — provide your own implementation to enable it:
const player = new Player({ async fetchRelatedTracks(queue, track) { // track is the one that just finished // DO NOT throw — return [] to stop gracefully return []; },});Filters
Section titled “Filters”Each queue has a FilterManager at queue.filters. Every method sends an update to Lavalink immediately and returns the resulting state — no separate apply step.
Common presets
Section titled “Common presets”// Nightcore — faster, higher pitchawait queue.filters.set("timescale", { speed: 1.3, pitch: 1.3 });
// Vaporwave — slower, lower pitchawait queue.filters.set("timescale", { speed: 0.8, pitch: 0.8 });
// 8D audio — rotating stereo fieldawait queue.filters.set("rotation", { rotationHz: 0.2 });
// Bass boostawait queue.filters.set("equalizer", [ { band: 0, gain: 0.3 }, { band: 1, gain: 0.2 }, { band: 2, gain: 0.1 },]);
// Karaoke — attenuate vocalsawait queue.filters.set("karaoke", { level: 1.0, monoLevel: 1.0, filterBand: 220, filterWidth: 100 });
// Soft tremoloawait queue.filters.set("tremolo", { frequency: 4, depth: 0.3 });Available filters
Section titled “Available filters”| Key | Effect |
|---|---|
volume | Output volume multiplier (0.0–5.0, where 1.0 = 100%). Separate from queue.setVolume() which uses 0–1000 |
equalizer | 15-band EQ. Each band: { band: 0–14, gain: -0.25–1.0 } |
karaoke | Attenuates a frequency band — typically reduces vocals |
timescale | Adjust speed, pitch, and rate independently (all default to 1.0, must be > 0) |
tremolo | Rapidly oscillate volume (frequency > 0, depth > 0 and ≤ 1) |
vibrato | Rapidly oscillate pitch (frequency > 0 and ≤ 14, depth > 0 and ≤ 1) |
rotation | Rotate audio around the stereo field — the 8D effect (rotationHz) |
distortion | Wave-function distortion with sin/cos/tan offset and scale controls |
channelMix | Blend left and right channels (leftToLeft, leftToRight, rightToLeft, rightToRight, each 0–1) |
lowPass | Suppress high frequencies (smoothing > 1.0 — values ≤ 1.0 disable the filter) |
pluginFilters | Filters from Lavalink server plugins |
Reading and checking
Section titled “Reading and checking”queue.filters.get("timescale"); // TimescaleFilter | nullqueue.filters.has("rotation"); // booleanRemoving and composing
Section titled “Removing and composing”// Remove specific filters — returns the updated Filters objectawait queue.filters.remove("timescale", "rotation");
// Clear by type — returns the updated Filters objectawait queue.filters.clear(); // remove everythingawait queue.filters.clear("native"); // built-in filters onlyawait queue.filters.clear("plugin"); // plugin filters only
// Merge — shallow-merges into the current filter state, returns updated Filtersawait queue.filters.merge({ volume: 1.5 });
// Override — replaces the entire filter state, returns updated Filtersawait queue.filters.override({ timescale: { speed: 1.2 } });Use merge when you want to layer effects on top of what’s already active. Use override when you want a clean slate.
set() returns the value that was just applied:
const ts = await queue.filters.set("timescale", { speed: 1.3, pitch: 1.3 });// ts → { speed: 1.3, pitch: 1.3 }Plugin filters
Section titled “Plugin filters”Plugin filters live under pluginFilters in the filter object. Pass true as the third argument to set():
await queue.filters.set("myFilter", { intensity: 0.8 }, true); // isPlugin = trueDeclare the type so it propagates everywhere:
declare module "discolink" { interface CommonPluginFilters { myFilter: { intensity: number }; }}Full type definitions: Filters
Syncing with Lavalink
Section titled “Syncing with Lavalink”If local state drifts — most commonly after a node reconnect:
await queue.sync(); // pull state from Lavalink (default)await queue.sync("remote"); // push local state to Lavalink
// Sync all queues on a node at onceawait player.queues.sync("us-east", "local");await player.queues.sync("us-east", "remote");autoSync: true (the default) calls queues.sync(node, 'remote') automatically when a node reconnects without resuming its session.