1 GrumpyMusic
darksoon edited this page 2026-05-10 16:46:29 +02:00

Music — Internet-Radio im Voice-Channel

GrumpyMusic streamt Internet-Radio (SHOUTcast / Icecast) in einen Voice-Channel — entweder interaktiv (User startet aus seinem Voice-Channel) oder passiv (Bot lebt permanent in einem festen Channel und pausiert, wenn niemand zuhört).

Beim Track-Wechsel zeigt der Bot „🎵 Station · Artist - Title" als Voice-Channel-Status unter dem Channel-Namen — sichtbar in der Voice-Liste.


Aktivierung

In configs/config.yml:

addons:
  music: true

channels:
  radio: "VOICE_CHANNEL_ID"   # Optional — Fallback-Channel für Passive-Mode

Beim ersten Start wird configs/modules/music.yml aus dem Template erzeugt. Anschließend /radio reload oder Bot neu starten.


music.yml

configs/modules/music.yml:

enabled: true
autoLeaveSeconds: 60         # Interactive: wie lange bleiben, wenn alle Listener weg sind
defaultVolume: 80            # Lautstärke 0-200 (Discord-Skala; 100 = Originallautstärke)

presets:
  - id: technobase
    label: TechnoBase.FM
    url: https://listen.technobase.fm/tunein-mp3
    description: Hands Up & Dance — der Klassiker
    color: '#FF1F4A'
  - id: hardbase
    label: HardBase.FM
    url: https://listen.hardbase.fm/tunein-mp3
    description: Hardstyle / Hardcore — keine Schonkost
    color: '#FF6F00'
  - id: housetime
    label: HouseTime.FM
    url: https://listen.housetime.fm/tunein-mp3
    description: House — entspannt bis treibend
    color: '#1E88E5'
  - id: trancebase
    label: TranceBase.FM
    url: https://listen.trancebase.fm/tunein-mp3
    description: Trance — episch & uplifting
    color: '#7B1FA2'
  - id: clubtime
    label: ClubTime.FM
    url: https://listen.clubtime.fm/tunein-mp3
    description: Club & EDM — Party-Sound
    color: '#E91E63'
  - id: coretime
    label: CoreTime.FM
    url: https://listen.coretime.fm/tunein-mp3
    description: Hardcore & Frenchcore
    color: '#B71C1C'
  - id: replayfm
    label: ReplayFM
    url: https://listen.replay.fm/tunein-mp3
    description: 90s/2000s Throwback Hits
    color: '#00897B'

passive:
  enabled: false
  channelId: "0"            # 0 = Fallback auf channels.radio aus config.yml
  stationId: technobase
  pauseWhenEmpty: true

Felder

Feld Default Bedeutung
enabled true Master-Toggle. Auch bei addons.music: true lässt sich das Modul hier ausschalten.
autoLeaveSeconds 60 Interactive-Mode: Wie lange der Bot bleibt, wenn niemand mehr im Channel ist (0 = sofort gehen).
defaultVolume 80 Lautstärke 0-200 (Discord-Skala; 100 = Originallautstärke).
presets 7 Default-Stationen Liste der verfügbaren Radio-Stationen (siehe oben). Beliebig erweiterbar.
presets[].id Eindeutige ID für /radio start (lowercase, keine Leerzeichen).
presets[].url Direkte Stream-URL (Icecast/SHOUTcast — .mp3/.aac).
presets[].color Hex-Farbe #RRGGBB für die Embed-Farbe.
passive.enabled false Passive-Mode aktivieren (Bot lebt permanent in einem Channel).
passive.channelId "0" Voice-Channel für Passive-Mode. 0 → nutzt channels.radio aus config.yml.
passive.stationId technobase Welche Preset-Station permanent gespielt wird.
passive.pauseWhenEmpty true Pausiert den Stream, wenn niemand zuhört — entlastet CPU + Bandbreite.

Modi

Interactive

User joint einen Voice-Channel und ruft /radio start <station> auf — der Bot joint denselben Channel und spielt den Stream. Sobald der Channel leer ist, läuft autoLeaveSeconds ab und der Bot disconnected automatisch.

1. User in #voice-3 → /radio start station: technobase
2. Bot joint #voice-3, spielt TechnoBase.FM
3. User leavt → 60s Timer startet
4. Niemand kommt zurück → Bot disconnected, Status wird gecleart

Passive

Der Bot lebt permanent im konfigurierten Channel und spielt immer den Passive-Stream. pauseWhenEmpty: true pausiert den Stream, wenn keiner zuhört, und resumed sobald jemand joint.

Steuerung:

/radio passive enable channel: <voice-channel> station: technobase
/radio passive disable
/radio passive status

/radio passive enable schreibt die Settings in music.yml und joint den Channel sofort.


Commands

Command Berechtigung Funktion
/radio start <station> Alle (im Voice-Channel) Startet einen Stream im aktuellen Voice-Channel
/radio stop Alle Stoppt den Stream und cleart den Channel-Status
/radio info Alle Aktueller Stream + Now-Playing
/radio list Alle Liste aller verfügbaren Stationen
/radio reload Server verwalten music.yml neu laden
/radio passive enable channel:<ch> station:<id> Server verwalten Passive-Mode aktivieren
/radio passive disable Server verwalten Passive-Mode deaktivieren, Bot disconnected
/radio passive status Server verwalten Aktueller Passive-Status

Voice-Channel-Status (Now-Playing)

Bei jedem Track-Wechsel updated der Bot den Voice-Channel-Status auf:

🎵 TechnoBase.FM · Cascada - Everytime We Touch

Der Status erscheint unter dem Channel-Namen in der Discord-Voice-Liste — keine zusätzliche Text-Message nötig. Bei /radio stop wird der Status gecleart.

Permission: Der Bot braucht SET_VOICE_CHANNEL_STATUS (1<<48) für den Channel oder den Server. Ohne diese Permission läuft das Radio normal weiter — nur der Now-Playing-Status fehlt.

Die Track-Info kommt aus dem Icecast-Inline-Metadata-Stream (icy-metaint-Header). Der Bot liest die Metadata-Frames parallel zum Audio.


Robustheit

GrumpyMusic ist auf instabile Streams ausgelegt:

  • Pre-Buffer 1 MB (≈ 60 s @ 128 kbps) absorbiert CDN-Jitter — Playback bleibt smooth, auch wenn der Stream kurz wackelt.
  • Browser-User-Agent beim HTTP-Fetch. Manche CDNs blocken ffmpeg's Default Lavf/... UA — der Bot stellt sich als normaler Player vor.
  • Exponential-Backoff bei Stream-Errors: 1s → 2s → 4s → 8s → 16s. Maximal 5 Versuche in einem 60s-Fenster, dann Stop mit Log-Eintrag.
  • Per-Guild Start-Lock: Klickt jemand /radio start mehrfach hintereinander, wird die Race-Condition gelockt — keine geleakten Voice-Connections.
  • Color-coded Embeds: Jede Station hat ihre eigene color — Embeds bei /radio start, /radio info etc. sind direkt visuell zuordenbar.

Permissions

Der Bot braucht im Voice-Channel:

Permission Pflicht? Grund
View Channel Channel sichtbar
Connect In den Channel joinen
Speak Audio senden
Set Voice Channel Status (1<<48) optional Now-Playing-Status — ohne läuft Audio normal weiter

FAQ

Was passiert, wenn die Station-URL einen 403/404 wirft? Der Bot loggt den Fehler, versucht 5x mit Exponential-Backoff und gibt dann auf. /radio info zeigt den letzten Fehler.

Kann ich eigene Stationen hinzufügen? Ja — neuen Block in presets: einfügen, /radio reload ausführen. Wichtig: id muss eindeutig sein (lowercase, kein Leerzeichen).

Funktioniert das mit YouTube / Spotify? Nein — GrumpyMusic ist explizit auf Internet-Radio-Streams (Icecast/SHOUTcast) ausgelegt. Kein Search, keine Queue, keine YouTube-Integration. Für solche Use-Cases ist SinusBot oder ein dedizierter Music-Bot besser.

Was passiert beim Bot-Restart im Passive-Mode? Der Bot rejoined automatisch den konfigurierten Channel und startet den Stream neu — ohne weiteren Eingriff.

Wie ändere ich den Passive-Channel? /radio passive enable channel: <neuer-channel> station: <id> — der Bot disconnected vom alten und joint den neuen.