Overview
The VoiceUtils class provides utilities for managing voice connections, joining voice channels, and creating stream dispatchers. It’s the core interface for voice connectivity in Discord Player.
Constructor
new VoiceUtils(player: Player)
The Discord Player instance
VoiceUtils is automatically instantiated by the Player. Access it via player.voiceUtils.
Properties
player
The Discord Player instance.
voiceUtils.player: Player
cache
This property is deprecated and will be removed in a future version. It only exists for compatibility reasons.
Voice connection cache storing stream dispatchers.
voiceUtils.cache: Collection<Snowflake, StreamDispatcher>
Methods
connect()
Joins a voice channel and creates a stream dispatcher for audio playback.
await voiceUtils.connect(
channel: VoiceChannel | StageChannel,
options?: ConnectOptions
): Promise<StreamDispatcher>
channel
VoiceChannel | StageChannel
required
The voice or stage channel to join
Whether the bot should be deafened
Maximum connection time in milliseconds
Custom audio player instance
Connection group identifier
Enable DAVE E2E encryption
options.decryptionFailureTolerance
Number of consecutive decryption failures before disconnecting
The stream dispatcher for managing audio playback
Example
const channel = interaction.member.voice.channel;
const queue = player.queues.cache.get(interaction.guildId);
const dispatcher = await player.voiceUtils.connect(channel, {
queue: queue,
deaf: true
});
console.log('Connected to voice channel');
join()
Joins a voice channel and returns the voice connection (without creating a stream dispatcher).
await voiceUtils.join(
channel: VoiceChannel | StageChannel,
options?: JoinOptions
): Promise<VoiceConnection>
channel
VoiceChannel | StageChannel
required
The voice or stage channel to join
Whether the bot should be deafened
Maximum connection time in milliseconds
Connection group identifier
Enable DAVE E2E encryption for voice data
options.decryptionFailureTolerance
Number of consecutive decryption failures allowed before automatic disconnect
The voice connection instance
Example
const channel = interaction.member.voice.channel;
// Join without creating a dispatcher
const connection = await player.voiceUtils.join(channel, {
deaf: true,
daveEncryption: true,
decryptionFailureTolerance: 50
});
console.log('Joined voice channel');
If an existing connection to the same channel exists and is not destroyed, it will be reused instead of creating a new connection.
disconnect()
Disconnects from a voice channel.
voiceUtils.disconnect(connection: VoiceConnection | StreamDispatcher): void
connection
VoiceConnection | StreamDispatcher
required
The voice connection or stream dispatcher to disconnect
Example
const connection = player.voiceUtils.getConnection(guildId);
if (connection) {
player.voiceUtils.disconnect(connection);
console.log('Disconnected from voice');
}
// Or disconnect a dispatcher
const dispatcher = queue.dispatcher;
if (dispatcher) {
player.voiceUtils.disconnect(dispatcher);
}
If you pass a StreamDispatcher, it will automatically extract and destroy the underlying VoiceConnection.
getConnection()
Retrieves an active voice connection for a guild.
voiceUtils.getConnection(guild: Snowflake, group?: string): VoiceConnection | undefined
The connection group identifier (if using groups)
connection
VoiceConnection | undefined
The voice connection if it exists, otherwise undefined
Example
const connection = player.voiceUtils.getConnection(interaction.guildId);
if (connection) {
console.log(`Connected to channel: ${connection.joinConfig.channelId}`);
console.log(`Status: ${connection.state.status}`);
} else {
console.log('Not connected to any voice channel');
}
// With connection groups
const groupedConnection = player.voiceUtils.getConnection(
interaction.guildId,
'music-bot'
);
Complete Usage Example
import { Player, GuildQueue } from 'discord-player';
import { VoiceConnectionStatus } from 'discord-voip';
const player = new Player(client);
// Play command handler
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName !== 'play') return;
const channel = interaction.member.voice.channel;
if (!channel) {
return interaction.reply('You need to be in a voice channel!');
}
const query = interaction.options.getString('song', true);
// Create or get queue
let queue = player.queues.cache.get(interaction.guildId);
if (!queue) {
queue = player.queues.create(interaction.guildId);
}
// Connect to voice channel
try {
const dispatcher = await player.voiceUtils.connect(channel, {
queue: queue,
deaf: true,
daveEncryption: true // Enable E2E encryption
});
// Search and play
const result = await player.search(query);
queue.addTrack(result.tracks[0]);
if (!queue.isPlaying()) {
await queue.node.play();
}
await interaction.reply(`Now playing: ${result.tracks[0].title}`);
} catch (error) {
console.error('Failed to connect:', error);
await interaction.reply('Could not join voice channel!');
}
});
// Disconnect command
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName !== 'disconnect') return;
const connection = player.voiceUtils.getConnection(interaction.guildId);
if (!connection) {
return interaction.reply('Not connected to voice!');
}
player.voiceUtils.disconnect(connection);
await interaction.reply('Disconnected from voice channel');
});
// Monitor connection status
const connection = player.voiceUtils.getConnection(guildId);
if (connection) {
connection.on('stateChange', (oldState, newState) => {
console.log(`Connection state changed: ${oldState.status} -> ${newState.status}`);
if (newState.status === VoiceConnectionStatus.Disconnected) {
console.log('Connection lost, attempting to reconnect...');
}
});
}
Connection Groups
Connection groups allow you to manage multiple voice connections per guild (useful for multi-instance bots).
// Connect to a specific group
const dispatcher = await player.voiceUtils.connect(channel, {
queue: queue,
group: 'music-bot-1'
});
// Get connection from a specific group
const connection = player.voiceUtils.getConnection(guildId, 'music-bot-1');
// Each group maintains its own connection
const secondDispatcher = await player.voiceUtils.connect(otherChannel, {
queue: otherQueue,
group: 'music-bot-2'
});
DAVE Encryption
DAVE (Discord Audio/Video E2EE) provides end-to-end encryption for voice data.
// Enable DAVE encryption (default: true)
const dispatcher = await player.voiceUtils.connect(channel, {
queue: queue,
daveEncryption: true,
decryptionFailureTolerance: 50 // Allow 50 consecutive failures
});
When enabled, voice data is end-to-end encrypted
decryptionFailureTolerance
Number of consecutive decryption failures before automatic disconnect. Higher values are more tolerant of network issues but may result in longer periods of garbled audio.
Types
ConnectOptions
interface ConnectOptions {
deaf?: boolean;
maxTime?: number;
queue: GuildQueue;
audioPlayer?: AudioPlayer;
group?: string;
daveEncryption?: boolean;
decryptionFailureTolerance?: number;
}
JoinOptions
interface JoinOptions {
deaf?: boolean;
maxTime?: number;
group?: string;
daveEncryption?: boolean;
decryptionFailureTolerance?: number;
}