Głos
Boty głosowe, w tym Lavalink i @discordjs/voice, działają bez zmian w kodzie. GameVox obsługuje protokół voice gateway Discorda słowo w słowo, a następnie przekazuje strumień AEAD-RTP do natywnego WebRTC SFU jako syntetyczny uczestnik.
Zgodne biblioteki
- Lavalink v3 + v4 (Java, boty JVM korzystające z niego przez JDA / discord4j / itd.)
- @discordjs/voice (Node)
- discord.py z dodatkami głosowymi (
PyNaCl) - JDA z modułem audio
- discord4j
- Eris z opcjonalnymi zależnościami głosowymi
Endpointy
Osobne dla każdego regionu: bot łączy się z regionem wskazanym w zdarzeniu VOICE_SERVER_UPDATE.
compatible-voice-gateway-us.gamevox.comcompatible-voice-gateway-eu.gamevox.comcompatible-voice-gateway-ap.gamevox.com
Główny gateway wskazuje właściwy region na podstawie lokalizacji SFU kanału. Twoja biblioteka odczytuje endpoint ze zdarzenia i tam się łączy. Nie trzeba niczego ręcznie routować.
Przebieg połączenia
- Bot wysyła
op:4 Update Voice Stateprzez główny gateway (gateway.gamevox.com) zchannel_id. - Główny gateway wysyła
VOICE_STATE_UPDATE+VOICE_SERVER_UPDATEz endpointem i tokenem sesji. - Bot otwiera WSS do
wss://{endpoint}/?v=8i wysyłaop:0 Identifyz{server_id, user_id, session_id, token}. - Voice gateway odpowiada
op:2 Readyzssrc,ip,porti obsługiwanymi trybami szyfrowania. - Bot wykonuje UDP IP discovery (74-bajtowy pakiet typu
0x0001→ odpowiedź typu0x0002). - Bot wysyła
op:1 Select Protocolz wybranym trybem szyfrowania. - Voice gateway odpowiada
op:4 Session Descriptionz 32-bajtowymsecret_key. - Bot przesyła strumień Opus przez RTP, zaszyfrowany AEAD w wynegocjowanym trybie.
Tryby szyfrowania
Obsługiwane są dwa tryby AEAD-RTPSize, tak jak na Discordzie:
aead_aes256_gcm_rtpsize: preferowany. AES-256-GCM z nonce wyprowadzanym z 4-bajtowego licznika dołączanego do zaszyfrowanego payloadu.aead_xchacha20_poly1305_rtpsize: tryb zapasowy dla bibliotek bez AES-NI.
Starsze tryby (xsalsa20_poly1305, _lite, _suffix) nie są oferowane: Discord wycofał je w 2024 roku, a główne biblioteki już z nich zrezygnowały. Jeśli twoja biblioteka jest przypięta do starego trybu, zaktualizuj ją.
Uwagi o Lavalinku
Lavalink odczytuje endpoint bezpośrednio z VOICE_SERVER_UPDATE i sam łączy się przez UDP. Dopóki endpoint jest osiągalny (a jest), Lavalink nie wie, że nie rozmawia z Discordem.
Przetestowane wersje: Lavalink v3.7.x i v4.0.x. Jeśli trafisz na problem specyficzny dla wersji, zgłoś go w portalu deweloperskim, a dodamy twoją wersję do testów w CI.
Budżet opóźnień
Docelowe opóźnienie dodawane przez most: poniżej 5 ms, mierzone od przychodzącego UDP do wyjścia z SFU. Powyżej 5 ms muzyka brzmi źle (dryf w czasie ataku nut, drgania hi-hatu). Most przekazuje Opus bez zmian, bez transkodowania, więc główna wartość to odszyfrowanie + ponowne pakietowanie.
Zdarzenia mówienia
op:5 Speaking działa w obie strony i jest identyczne jak na Discordzie. Voice gateway mapuje SSRC mówiących ludzi na ich identyfikatory użytkowników i wysyła op:5 z {ssrc, user_id}, żeby bot mógł je powiązać.
Czyste zakończenie
Wysłanie op:4 Update Voice State z channel_id: null przez główny gateway zamyka sesję. Voice gateway zamyka gniazdo UDP i usuwa syntetycznego uczestnika SFU; słuchacze natychmiast przestają otrzymywać dźwięk.
Jeszcze nieobsługiwane
- DAVE / E2EE: tryb głosu Discorda z szyfrowaniem end-to-end dla każdego kanału. Na razie bez terminu.
- Soundboard: boty nie mogą odtwarzać dźwięków z soundboardu.
- Kanały Stage: akceptowane przez protokół, ale bez osobnej obsługi publiczności i mówców.