@sonata-sdk/voice
v1.0.13
Published
Discord voice connection library — WebSocket gateway, UDP, RTP, encryption, DAVE/MLS
Readme
Pure TypeScript Discord voice library. Connects to Discord's voice gateway, handles UDP audio, RTP packetization, encryption, and DAVE/MLS E2EE. No native dependencies, no C++.
📥 Install
npm install @sonata-sdk/voiceOptional (for DAVE/E2EE)
npm install @snazzah/davey libsodium-wrappers🔌 Subpath imports
import { joinVoiceChannel } from '@sonata-sdk/voice'
import { VoiceGateway } from '@sonata-sdk/voice/gateway'
import { UdpSocket } from '@sonata-sdk/voice/udp'
import { AudioEncryption } from '@sonata-sdk/voice/encryption'
import type { VoiceConnection, EncryptionMode } from '@sonata-sdk/voice/types'🚀 Usage
import { joinVoiceChannel } from '@sonata-sdk/voice'
const connection = joinVoiceChannel({
guildId: '123',
userId: '456',
channelId: '789',
encryption: 'aead_aes256_gcm_rtpsize',
})
connection.voiceStateUpdate({ sessionId: 'abc' })
connection.voiceServerUpdate({ token: 'xyz', endpoint: 'gateway.discord.audio' })
connection.on('stateChange', (old, next) => {
if (next.status === 'connected') {
// Send audio every 20ms
setInterval(() => {
connection.sendAudioFrame(opusFrame)
}, 20)
}
})
connection.setSpeaking(1)📖 API
joinVoiceChannel(options)
| Option | Type | Description |
|--------|------|-------------|
| guildId | string | Discord guild ID |
| userId | string | Bot user ID |
| channelId | string | Voice channel ID |
| encryption | string \| null | Encryption mode or null for auto |
Returns a VoiceConnection.
VoiceConnection
| Property | Description |
|----------|-------------|
| state | { status, reason, code } — connection state |
| playerState | { status, reason } — playback state |
| ping | Voice websocket latency |
| statistics | { packetsSent, packetsLost, packetsExpected } |
| udpInfo | { ssrc, ip, port, secretKey } or null |
| Method | Description |
|--------|-------------|
| voiceStateUpdate(obj) | Feed Discord voice state |
| voiceServerUpdate(obj) | Feed Discord voice server |
| sendAudioFrame(frame) | Send an Opus frame |
| setSpeaking(value) | Set speaking flag (1 = speaking) |
| destroy() | Clean up connection |
| on(event, fn) | Listen to events |
| removeAllListeners(event?) | Remove listeners |
Events
| Event | Payload | Description |
|-------|---------|-------------|
| stateChange | (old, next) | Connection state changed |
| playerStateChange | (old, next) | Player state changed |
| error | (Error) | An error occurred |
| ready | () | Voice connection established |
🔒 Encryption Modes
| Mode | Algorithm |
|------|-----------|
| aead_aes256_gcm_rtpsize | AES-256-GCM |
| aead_xchacha20_poly1305_rtpsize | XChaCha20-Poly1305 |
| xsalsa20_poly1305_lite_rtpsize | XSalsa20-Poly1305 (lite) |
| xsalsa20_poly1305_suffix_rtpsize | XSalsa20-Poly1305 (suffix) |
| normal | XSalsa20-Poly1305 (legacy) |
📦 Related
- Sonata — Lavalink-compatible audio server
- @sonata-sdk/plugin-sdk — SDK for Sonata plugins
- sonata-sdk-packages — Monorepo
