"signalling" sagt nur, dass etwas fehlt, nicht was. Ein Beitritt zum
Sprachkanal ist ein Dreischritt:
1. Der Bot bittet Discord ueber die bestehende Verbindung um den Beitritt.
2. Discord antwortet mit dem eigenen Sprachstatus (darin die Sitzungs-ID).
3. Discord nennt den Sprachserver.
Der Adapter zwischen Verbindung und Sprachbibliothek haelt jetzt fest,
welcher davon stattgefunden hat. Aus den drei Haekchen wird ein Satz, der
sagt, was zu tun ist — fehlende Berechtigung, fehlender Intent, oder ein
Netz, das UDP nicht rauslaesst. Fuenf Faelle, fuenf verschiedene Antworten;
der Test besteht darauf, dass keine zwei gleich lauten.
Dazu eine Pruefung vorweg, die genau dasselbe Bild erzeugt haette: ein
voller Sprachkanal. Discord nimmt die Anfrage entgegen und antwortet dann
einfach nicht mehr — das sieht aus wie ein Rechteproblem. Wer Mitglieder
verschieben darf, kommt am Limit vorbei, sonst nicht.
Nachgesehen und ausgeschlossen: discord.js 14.27 verdrahtet beide
Sprachereignisse (VOICE_STATE_UPDATE ueber die Action, VOICE_SERVER_UPDATE
ueber den Handler), und GuildVoiceStates steht in den Intents.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Sachen, alle vom selben Bericht ausgeloest.
1. Der Schalter war nur im Modul-Reiter zu finden, die Meldung schickte aber
nach "Community". Beim Nachsehen kam heraus: Modul-Schalter haben in
/api/settings gar keinen Weg — jeder stand von Hand in api.js, und fuenf
fehlten dort (radio, automod, anti_raid, linked_roles, ls_farm). Die
liessen sich nur ueber den Modulreiter umlegen. Jetzt kommen sie wie
Kanaele, Rollen und Texte aus dem Register; jeder neue ist damit von
allein speicherbar. Dazu steht der Haken jetzt oben im Radio-Abschnitt,
wo auch die Sender stehen.
2. Der Bot sass im Sprachkanal und schwieg. Ursache im Code: nach
joinVoiceChannel wurde sofort losgespielt. Der Aufruf kommt zurueck,
sobald der Bot sichtbar im Kanal steht — der UDP-Weg wird danach erst
ausgehandelt. Wer vorher sendet, sendet ins Leere. Jetzt wird auf
VoiceConnectionStatus.Ready gewartet, und schlaegt das fehl, sagt der
Befehl es statt still dazustehen.
3. Stille erklaert sich. Fehlt ffmpeg im Container, setzte sich der Bot
bisher hin und schwieg — nichts stuerzte ab, nichts fehlte sichtbar.
ffmpeg wird jetzt beim Start geprueft, /radio verweigert mit klarer
Ansage, und kommt binnen acht Sekunden kein Ton, steht der Grund in der
Tafel: fehlendes ffmpeg oder ein Sender, der nichts liefert.
Nebenbei: -analyzeduration stand hinter -i und wurde damit als
Ausgabe-Option gelesen, also ignoriert.
Geprueft: die Tonkette laeuft lokal gegen einen echten Sender durch bis zum
Abspieler (4,1 s Ton in 6 s Laufzeit, Status bleibt playing). Alle 16
Modul-Schalter gehen angemeldet durch /api/settings hin und zurueck.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
/radio holt den Bot in den Sprachkanal und postet eine Tafel: Auswahlmenue
mit allen Sendern, Stopp, und ein Embed mit dem laufenden Titel, das sich
alle 30 Sekunden selbst nachfuehrt.
Der Titel kommt aus dem Icecast-Strom selbst (Icy-MetaData). Bewusst so und
nicht ueber eine Sender-API: das funktioniert bei jedem Strom, den jemand
eintraegt, und nicht nur bei den drei, die ich kenne. Leere Titel-Bloecke
heissen "unveraendert", deshalb werden bis zu drei gelesen.
Die Tonkette braucht keine Opus-Bibliothek: ffmpeg holt das MP3 und gibt
direkt Ogg/Opus aus, prism-media packt nur noch aus. Gemessen: 600 Pakete in
fuenf Sekunden. Sonst muesste @discordjs/opus mit ins Image, und das will
gebaut werden. Neu im Image ist nur ffmpeg.
44 RauteMusik-Sender sind ab Werk eingetragen — dieselben, die im LS25 und
ETS als Bordradio laufen. Die Liste ist nicht abgeschrieben, sondern
gemessen: jede Adresse einzeln angefragt, der Name kommt aus icy-name.
Doppelgaenger sind raus (deutschrap-charts und wackenradio liefern denselben
Strom wie deutschrap und metal). Eingetragen wird einmal, solange die Liste
leer ist — wer loescht, behaelt es geloescht.
Ein Auswahlmenue fasst nur 25 Eintraege. Bei 44 Sendern haette ein Deckel
die letzten 19 stillschweigend verschluckt; stattdessen mehrere Menues,
benannt nach ihrem ersten und letzten Sender.
Der Bot geht raus, wenn der Kanal leer ist, und kommt nach einem Neustart in
den Kanal zurueck — sonst beendet jeder Deploy die Musik endgueltig.
Kein YouTube. Genau daran sind Groovy und Rythm gestorben, und was davon
uebrig ist, ist ein Dauerlauf gegen kaputte Extraktoren.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>