Files
d4rkbot/package.json
D4rkst3randClaude Opus 5 1154e7a6a5
Deploy / check (push) Canceled after 0s
Deploy / deploy (push) Canceled after 0s
Radio: Lautstaerke im Panel -- und leise reinkommen statt erschrecken
Der Anlass ist eine Beobachtung aus dem Betrieb: der Bot kam mit voller
Aussteuerung in den Kanal, und wer schon drin sass, ist erschrocken. Dass
sich jeder den Bot fuer sich leiser drehen kann, hilft erst *nachdem* es zu
laut war. Also liegt die Vorgabe jetzt bei 50 %, und lauter machen kostet
zwei Knopfdruecke.

Dafuer musste die Tonkette umgebaut werden. Bisher lief Opus unveraendert
durch (ffmpeg -> Ogg/Opus -> Discord). Das war eine Stufe sparsamer, aber an
fertigen Opus-Paketen laesst sich die Lautstaerke nicht drehen -- dafuer muss
man an die Abtastwerte. Jetzt: ffmpeg gibt PCM aus, die Sprachbibliothek
regelt und kodiert.

Der alte Einwand im Dateikopf ("sonst muesste @discordjs/opus mit ins Image,
und das will gebaut werden") stimmt weiterhin -- fuer @discordjs/opus.
Nachgemessen am 14.08.2026 in node:22-slim:

  @discordjs/opus  npm i bricht ab, kein Prebuild fuer node-v127/glibc-2.36,
                   node-gyp will bauen, im Image fehlen die Werkzeuge
  opusscript       reines JavaScript, installiert in 740 ms, kein Compiler
                   0,3 % eines Kerns fuers Kodieren eines Dauerstroms

Der Umweg ueber Opus-Dekodieren entfaellt dabei ganz, ffmpeg liefert ja schon
Abtastwerte. Deshalb 0,3 % und nicht 2,9 %, was Dekodieren und Kodieren
zusammen gekostet haetten.

Die Kette ist mit echtem ffmpeg gegen einen Sinuston geprueft: 200
Opus-Pakete fuer 4,0 s Ton, kein Versatz, und die Lautstaerke laesst sich
mitten im Strom aendern. Genau darum geht der Weg ueber PCM und nicht ueber
ffmpegs volume-Filter -- der haette bei jedem Klick einen Neustart des
Prozesses gebraucht, also eine hoerbare Luecke.

Am Panel zwei Knoepfe in der bestehenden Reihe, Schritte von 10, Bereich 10
bis 200. Am Anschlag graut der Knopf aus, statt sich druecken zu lassen und
nichts zu tun. Die Rueckmeldung ist die neu gezeichnete Tafel mit dem neuen
Prozentwert.

Der Wert steht in den Einstellungen, nicht in radio_state: der Merker dort
wird beim Stoppen geloescht, die Lautstaerke soll das ueberleben.

Dazu der Kanal-Status: was laeuft, steht jetzt auch in der Statuszeile des
Sprachkanals und wird mit dem Titel nachgefuehrt.

  ACHTUNG, das ist ein UNDOKUMENTIERTER Endpunkt.
  PUT /channels/{id}/voice-status -- Discord hat ihn nie in die API-Doku
  aufgenommen, die Pull Requests dazu liegen seit 2023 offen, und discord.js
  hat die Umsetzung als "not planned" geschlossen. Roher Aufruf ueber
  client.rest also, und er kann ohne Ankuendigung verschwinden.

Deshalb ist er als Beiwerk gebaut: faellt er aus, sagt er einmal warum und
schweigt dann -- ein Fehler alle 30 Sekunden waere kein Hinweis mehr,
sondern Rauschen. Das Radio laeuft in jedem Fall weiter. Der naechste
Sender-Start versucht es erneut, falls das Recht inzwischen erteilt wurde.

Das Recht heisst "Kanalstatus festlegen" und sitzt auf Bit 48. discord.js
kennt es nicht einmal als Konstante, deshalb steht die Zahl im Quelltext.
Ungeprueft, weil dafuer ein echter Sprachkanal noetig ist: ob das Recht dem
Bot hier tatsaechlich erteilt ist. Faellt es aus, steht der Grund im Log.

Beim Stoppen wird die Zeile geleert -- sonst behauptet sie stundenlang, es
liefe ein Lied, das laengst vorbei ist.

Nebenbei: prism-media wurde direkt importiert, stand aber nie in der
package.json. Der Import ist mit dem Ogg-Auspacker weggefallen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 12:53:16 +02:00

31 lines
775 B
JSON

{
"name": "d4rkbot",
"version": "0.1.0",
"description": "D4RKST3R Community-Bot: Devlogs, Commits, Releases, Bug-Reports + API für eigene Dienste",
"author": "D4rkst3r",
"license": "MIT",
"type": "module",
"main": "src/index.js",
"engines": {
"node": ">=22.12.0"
},
"scripts": {
"start": "node src/index.js",
"dev": "node --watch src/index.js"
},
"dependencies": {
"@discordjs/voice": "^0.19.2",
"@fastify/cookie": "^11.1.2",
"@fastify/multipart": "^10.1.0",
"@fastify/static": "^10.1.2",
"better-sqlite3": "^12.11.1",
"discord.js": "^14.16.3",
"dotenv": "^16.4.7",
"fastify": "^5.10.0",
"gamedig": "^5.3.3",
"libsodium-wrappers": "^0.8.4",
"opusscript": "^0.0.8",
"sharp": "^0.35.3"
}
}