VoiceConnection & AudioPlayer
@lunibee/voice provides low-level Discord voice support. VoiceConnection manages the Voice Gateway session, while AudioPlayer drives audio streaming into a voice channel.
[!NOTE] Voice support is at a lower abstraction level than the main
Client. You must wire UDP transport yourself or use a higher-level adapter.
Import
Section titled “Import”import { VoiceConnection, VoiceConnectionState, AudioPlayer, AudioStream, VoiceReceiver, SpeakingFlags,} from "@lunibee/voice";import { VoiceConnection, VoiceConnectionState, AudioPlayer, AudioStream, VoiceReceiver, SpeakingFlags,} from "@lunibee/voice";VoiceConnection
Section titled “VoiceConnection”Manages the Discord Voice Gateway WebSocket session for a single guild.
Constructor
Section titled “Constructor”new VoiceConnection(guildId: string)// or with full options:new VoiceConnection({ guildId, endpoint, token, sessionId, selfDeaf, selfMute })new VoiceConnection(guildId)// or with full options:new VoiceConnection({ guildId, endpoint, token, sessionId, selfDeaf, selfMute })Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
state |
VoiceConnectionState |
Current connection state. |
guildId |
string |
The guild this connection belongs to. |
VoiceConnectionState Values
Section titled “VoiceConnectionState Values”| State | Description |
|---|---|
Disconnected |
Not connected. |
Connecting |
Waiting for READY/SESSION_DESCRIPTION. |
Ready |
Fully connected, audio can be played. |
Destroyed |
Permanently closed. |
Methods
Section titled “Methods”connect(endpoint, token, sessionId)
Section titled “connect(endpoint, token, sessionId)”Starts the Voice WebSocket connection.
await connection.connect(voiceEndpoint, voiceToken, sessionId);await connection.connect(voiceEndpoint, voiceToken, sessionId);attachUdp(transport)
Section titled “attachUdp(transport)”Attaches a VoiceUdpTransport for sending audio packets.
connection.attachUdp(myUdpTransport);connection.attachUdp(myUdpTransport);setSpeaking(flags)
Section titled “setSpeaking(flags)”Updates the speaking state.
connection.setSpeaking(SpeakingFlags.Microphone);connection.setSpeaking(0); // stop speakingconnection.setSpeaking(SpeakingFlags.Microphone);connection.setSpeaking(0); // stop speakingdestroy()
Section titled “destroy()”Closes and destroys the connection.
on(event, listener) / off(event, listener)
Section titled “on(event, listener) / off(event, listener)”| Event | Args | Description |
|---|---|---|
"ready" |
(ssrc: number) |
Connection is fully established. |
"stateChange" |
(prev, next) |
State transition. |
"sessionDescription" |
(data) |
Encryption key/mode received. |
AudioPlayer
Section titled “AudioPlayer”Drives audio from a ReadableStream<Uint8Array> into the voice connection.
Constructor
Section titled “Constructor”new AudioPlayer()new AudioPlayer()Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
state |
AudioPlayerState |
"idle", "playing", "paused", "stopped". |
Methods
Section titled “Methods”play(stream)
Section titled “play(stream)”Starts playing an AudioStream.
const stream = new AudioStream(readableStream, { frameSize: 960 });player.play(stream);const stream = new AudioStream(readableStream, { frameSize: 960 });player.play(stream);pause()
Section titled “pause()”Pauses playback.
resume()
Section titled “resume()”Resumes from paused state.
stop()
Section titled “stop()”Stops playback and enters "stopped" state.
Events
Section titled “Events”| Event | Args | Description |
|---|---|---|
"start" |
() |
Playback began. |
"pause" |
() |
Playback paused. |
"resume" |
() |
Playback resumed. |
"finish" |
() |
Audio stream finished naturally. |
"stop" |
() |
Manually stopped. |
"error" |
(error) |
Playback error. |
AudioStream
Section titled “AudioStream”Wraps a ReadableStream<Uint8Array> for use with AudioPlayer.
import { AudioStream } from "@lunibee/voice";import { createReadStream } from "node:fs";
const fileStream = createReadStream("./music.pcm");const audio = new AudioStream(Readable.toWeb(fileStream), { frameSize: 960 });import { AudioStream } from "@lunibee/voice";import { createReadStream } from "node:fs";
const fileStream = createReadStream("./music.pcm");const audio = new AudioStream(Readable.toWeb(fileStream), { frameSize: 960 });VoiceReceiver
Section titled “VoiceReceiver”Receives and demultiplexes incoming voice audio by SSRC/user ID.
const receiver = new VoiceReceiver(connection);
const userStream = await receiver.subscribe(userId);// userStream: ReadableStream<Uint8Array>const receiver = new VoiceReceiver(connection);
const userStream = await receiver.subscribe(userId);// userStream: ReadableStream<Uint8Array>SpeakingFlags
Section titled “SpeakingFlags”| Flag | Value | Description |
|---|---|---|
SpeakingFlags.Microphone |
1 |
Normal microphone speaking. |
SpeakingFlags.Soundshare |
2 |
Application audio (screen share). |
SpeakingFlags.Priority |
4 |
Priority speaker. |
Example
Section titled “Example”import { VoiceConnection, AudioPlayer, AudioStream, SpeakingFlags } from "@lunibee/voice";
// Get voice state from a Gateway event:client.on(ClientEvent.VoiceStateUpdate, async (data) => { // Use VoiceStateUpdate + VoiceServerUpdate to get endpoint/token/sessionId...});
// Once you have voice credentials:const connection = new VoiceConnection({ guildId });await connection.connect(endpoint, token, sessionId);
connection.on("ready", async (ssrc) => { const player = new AudioPlayer(); const stream = new AudioStream(audioReadableStream, { frameSize: 960 }); connection.setSpeaking(SpeakingFlags.Microphone); player.play(stream); player.on("finish", () => { connection.setSpeaking(0); connection.destroy(); });});import { VoiceConnection, AudioPlayer, AudioStream, SpeakingFlags } from "@lunibee/voice";
// Get voice state from a Gateway event:client.on(ClientEvent.VoiceStateUpdate, async (data) => { // Use VoiceStateUpdate + VoiceServerUpdate to get endpoint/token/sessionId...});
// Once you have voice credentials:const connection = new VoiceConnection({ guildId });await connection.connect(endpoint, token, sessionId);
connection.on("ready", async (ssrc) => { const player = new AudioPlayer(); const stream = new AudioStream(audioReadableStream, { frameSize: 960 }); connection.setSpeaking(SpeakingFlags.Microphone); player.play(stream); player.on("finish", () => { connection.setSpeaking(0); connection.destroy(); });});