Life cycles

Two of the main components that you'll interact with when using @discordjs/voice are:

  • VoiceConnection – maintains a network connection to a Discord voice server
  • AudioPlayer – plays audio resources across a voice connection

Both voice connections and audio players are stateful, and you can subscribe to changes in their state as they progress through their respective life cycles.

It's important to listen for state change events, as they will likely require you to take some action. For example, a voice connection entering the Disconnected state will probably require you to attempt to reconnect it.

Their individual life cycles with descriptions of their states are documented on their respective pages.

Listening to changes in the life cycles of voice connections and audio players can be done in two ways:

Subscribing to individual events

const { VoiceConnectionStatus, AudioPlayerStatus } = require('@discordjs/voice');

connection.on(VoiceConnectionStatus.Ready, (oldState, newState) => {
	console.log('Connection is in the Ready state!');
});

player.on(AudioPlayerStatus.Playing, (oldState, newState) => {
	console.log('Audio player is in the Playing state!');
});
1
2
3
4
5
6
7
8
9

TIP

One advantage of listening for transitions to individual states is that it becomes a lot easier to write sequential logic. This is made easy using our state transition helperopen in new window. An example is shown below.

const { AudioPlayerStatus, entersState } = require('@discordjs/voice');

async function start() {
	player.play(resource);
	try {
		await entersState(player, AudioPlayerStatus.Playing, 5_000);
		// The player has entered the Playing state within 5 seconds
		console.log('Playback has started!');
	} catch (error) {
		// The player has not entered the Playing state and either:
		// 1) The 'error' event has been emitted and should be handled
		// 2) 5 seconds have passed
		console.error(error);
	}
}

void start();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Subscribing to all state transitions

If you would prefer to keep a single event listener for all possible state transitions, then you can also listen to the stateChange event:

connection.on('stateChange', (oldState, newState) => {
	console.log(`Connection transitioned from ${oldState.status} to ${newState.status}`);
});

player.on('stateChange', (oldState, newState) => {
	console.log(`Audio player transitioned from ${oldState.status} to ${newState.status}`);
});
1
2
3
4
5
6
7