Skip to main content
Version: v2.10.3 (current)

Voice Receive and Events

Enable Voice Receiveโ€‹

The server must enable voiceReceive.enabled and choose a supported format such as opus or pcm_s16le. The player must be connected to the intended Discord voice channel before receiving speaker audio.

import { ManagerEventTypes } from "magmastream";

if (!player.node.isNodeLink) {
throw new Error("Voice receive requires NodeLink.");
}

manager.on(ManagerEventTypes.VoiceReceiverData, (eventPlayer, frame) => {
if (eventPlayer.guildId !== player.guildId) return;
// frame.data is binary audio in frame.type, not a text/base64 payload.
console.log(frame.userId, frame.type, frame.data.length);
});

manager.on(ManagerEventTypes.VoiceReceiverError, (eventPlayer, error) => {
console.error(eventPlayer.guildId, error);
});

await player.setupVoiceReceiver();

The receiver uses the node's authenticated /v4/websocket/voice/<guildId> socket. Binary start/audio/stop frames are parsed by the client. Legacy JSON speaking payloads remain accepted.

Receiver Eventsโ€‹

EventArguments
voiceReceiverConnectplayer
voiceReceiverDisconnectplayer
voiceReceiverErrorplayer, error
voiceReceiverStartSpeakingplayer, data
voiceReceiverDataplayer, frame: VoiceReceiverData
voiceReceiverEndSpeakingplayer, data

Speaking refers to the received speaker, not the bot beginning playback. Live frames contain guildId, userId, data: Buffer, format, SSRC, and timestamp. Binary stop events include accumulated audio as a Buffer. The public start/end callback tuples remain typed as unknown, so validate them before use.

Opus packets are not automatically a playable Ogg/WAV file. PCM needs the server's sample-rate/channel configuration. Do not blindly concatenate either format and label it as a different codec.

The client buffers speaking chunks until a stop event. Process live frames promptly, apply your own recording limits, and remove the receiver when it is no longer needed:

await player.removeVoiceReceiver();

Destroying a player also clears receiver resources. Handle reconnect/error events and obtain appropriate consent before recording Discord users.

Native Gateway Eventsโ€‹

The dedicated manager callbacks cover mixer, connection diagnostics, worker failure, volume/filter/seek/pause updates, player lifecycle, Eternal Box, and stream metadata. See the exact argument tuples in ManagerEvents.

import { ManagerEventTypes } from "magmastream";

manager.on(ManagerEventTypes.NodeLinkVolumeChanged, (eventPlayer, payload) => {
console.log(eventPlayer.guildId, payload);
});

manager.on(ManagerEventTypes.NodeLinkEvent, (node, payload) => {
console.log(node.options.identifier, payload.type);
});

Recognized volume, pause, seek, filter, and lifecycle events synchronize local player state. Global events without a guild ID are supported where applicable.

nodeLinkEvent forwards native events and unknown/plugin event payloads. Unknown NodeLink event names are not reported as ordinary unknown-event nodeError failures. Use dedicated callbacks for typed handling; the generic callback does not replace every standard track/lyrics callback.

Standard Player Updatesโ€‹

playerUpdate is emitted for both Lavalink and NodeLink:

import { ManagerEventTypes } from "magmastream";

manager.on(ManagerEventTypes.PlayerUpdate, (eventPlayer, message) => {
console.log(eventPlayer.guildId, message.state.position);
});

Lyrics, chapter, and SponsorBlock callbacks may have no usable current track. Check for null; do not assume those events always accompany active playback.