Skip to main content
The Player class is the heart of Discord Player. It manages all music operations, queue management, and audio connections across your bot’s guilds.

Creating a Player

The Player instance is typically created once when your bot starts:
import { Player } from 'discord-player';
import { Client } from 'discord.js';

const client = new Client({
  intents: ['Guilds', 'GuildVoiceStates']
});

const player = new Player(client, {
  skipFFmpeg: false,
  lagMonitor: 30000
});
The GuildVoiceStates intent is required for Discord Player to function properly.

Player Options

The Player accepts several configuration options:
OptionTypeDefaultDescription
connectionTimeoutnumber20000Voice connection timeout in ms
lagMonitornumber30000Event loop lag monitoring interval
blockExtractorsstring[][]List of extractors to disable for metadata
blockStreamFromstring[][]List of extractors to disable for streaming
queryCacheQueryCacheProviderBuilt-in cacheQuery cache provider (use null to disable)
skipFFmpegbooleantrueSkip FFmpeg processing when possible
probeTimeoutnumber5000Probe timeout in milliseconds
ffmpegPathstringAuto-detectedCustom FFmpeg binary path

Key Methods

play()

Play a track in a voice channel. This is the main method for music playback:
const { track } = await player.play(voiceChannel, 'Never Gonna Give You Up', {
  nodeOptions: {
    metadata: {
      channel: interaction.channel
    }
  }
});

console.log(`Now playing: ${track.title}`);
Signature:
player.play<T>(
  channel: GuildVoiceChannelResolvable,
  query: TrackLike,
  options?: PlayerNodeInitializerOptions<T>
): Promise<PlayerNodeInitializationResult<T>>
Search for tracks without playing them:
const result = await player.search('Imagine Dragons', {
  requestedBy: interaction.user,
  searchEngine: QueryType.YOUTUBE
});

if (result.hasTracks()) {
  console.log(`Found ${result.tracks.length} tracks`);
}
Signature:
player.search(
  query: TrackLike,
  options?: SearchOptions
): Promise<SearchResult>

extractors

Manage extractors for fetching music from different sources:
import { YouTubeExtractor } from '@discord-player/extractor';

// Register an extractor
await player.extractors.register(YouTubeExtractor, {});

// Load default extractors
await player.extractors.loadDefault();

Properties

nodes

Access to the guild node manager (queue manager):
// Get a specific queue
const queue = player.nodes.get(guildId);

// Create a new queue
const queue = player.nodes.create(guild, {
  metadata: { channel: interaction.channel }
});

// Delete a queue
player.nodes.delete(guildId);

events

The global event emitter for all queue events:
player.events.on('playerStart', (queue, track) => {
  console.log(`Started playing ${track.title}`);
});

player.events.on('error', (queue, error) => {
  console.error(`Queue error: ${error.message}`);
});

lyrics

Access to the lyrics API powered by LrcLib:
const results = await player.lyrics.search({
  q: 'Alan Walker Faded'
});

if (results.length > 0) {
  console.log(results[0].plainLyrics);
}

Voice State Handler

Customize how the player handles voice state updates:
player.onVoiceStateUpdate((player, queue, oldState, newState) => {
  // Custom voice state handling logic
  if (oldState.channelId && !newState.channelId) {
    console.log('User left the channel');
  }
});

Utility Methods

scanDeps()

Generate a diagnostic report of dependencies:
console.log(player.scanDeps());
// Outputs version info for discord-player, discord-voip, discord.js, FFmpeg, etc.

generateStatistics()

Get statistics about active queues:
const stats = player.generateStatistics();
console.log(`Active queues: ${stats.queuesCount}`);
console.log(`Cache enabled: ${stats.queryCacheEnabled}`);

destroy()

Clean up all resources when shutting down:
await player.destroy();

Player Events

The Player emits the following events:
EventParametersDescription
debug(message: string)Debug information
error(error: Error)Player-level errors
voiceStateUpdate(queue, oldState, newState)Voice state changes
player.on('debug', (message) => {
  console.log('[Player Debug]', message);
});

player.on('error', (error) => {
  console.error('[Player Error]', error);
});

Advanced Features

Query Cache

The Player includes a built-in query cache to avoid redundant searches:
// Disable query cache
const player = new Player(client, {
  queryCache: null
});

// Custom cache provider
const player = new Player(client, {
  queryCache: new CustomQueryCache()
});

Stream Interceptor

Intercept and modify streams before playback:
const interceptor = player.createStreamInterceptor({
  // Your interceptor logic
});

Event Loop Monitoring

Monitor event loop lag to detect performance issues:
const lag = player.eventLoopLag;
if (lag > 20) {
  console.warn(`High event loop lag detected: ${lag}ms`);
}

Example: Complete Setup

import { Client, GatewayIntentBits } from 'discord.js';
import { Player, QueryType } from 'discord-player';

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildVoiceStates
  ]
});

const player = new Player(client, {
  skipFFmpeg: false,
  lagMonitor: 30000
});

// Load default extractors
await player.extractors.loadDefault();

// Global event handling
player.events.on('playerStart', (queue, track) => {
  queue.metadata.channel.send(`Now playing: **${track.title}**`);
});

player.events.on('error', (queue, error) => {
  console.error(`Queue error: ${error.message}`);
});

client.login(process.env.DISCORD_TOKEN);

See Also

  • GuildQueue - Learn about queue management
  • Track - Understanding track objects
  • Events - Complete event reference

Build docs developers (and LLMs) love