aboutsummaryrefslogtreecommitdiffstats

Teamspeak 6 Web Server Status

A simple webview of your Teamspeak 6 Server. This is a Python re-write of ts6-web-explorer along with a visual overhaul

image

Visitors who know the server password can also join voice straight from the browser, no TeamSpeak client needed.

Running

Requires Python 3.13+ (uv) and, for browser voice, Node.js 22.12+.

uv sync
uv run run.py

That one command starts the dashboard and the voice gateway (gateway npm dependencies are installed automatically on first run). Open http://<host>:5000.

  • Copy .env.template to .env and fill in the secrets (TS_HOST, TS_API_KEY, TS_SERVER_PASSWORD)
  • Everything else is configured in config.toml, which is shared by the dashboard and the voice gateway
  • Images in config.toml are referenced based on the root of this repo
  • Spacer channels are hidden
  • Channels with the text AFK are shown, the number of users in this channel is used as the AFK users indicator
  • uv run app.py still runs the dashboard alone (no voice)

Browser voice

browser ──HTTP/WS :5000──▶ gateway (Node) ──proxy──▶ dashboard (Flask, 127.0.0.1:5001)
                              │
                              └──UDP voice──▶ TeamSpeak server :9987
  • The gateway owns the public port: it serves /ws/voice and forwards everything else to Flask, so there is only one port to expose / reverse-proxy.
  • Each browser gets its own TeamSpeak client inside the gateway (via @honeybbq/teamspeak, pure JS). Mic audio is sent as 20 ms PCM frames over the WebSocket and encoded to Opus on the gateway; incoming Opus is decoded in the browser with WebCodecs (or on the gateway for browsers without it). No WebRTC.
  • Access control: voice is only offered when TS_SERVER_PASSWORD is set. Visitors must type the server password; the gateway checks it (constant time) before opening any TeamSpeak connection, and the TeamSpeak server checks it again. Repeated wrong passwords lock the IP out ([voice] max_failed_logins, lockout_minutes). Cross-origin WebSocket connections are rejected.
  • Limits for small machines: [voice] max_sessions and max_sessions_per_ip.
  • While connected, the channel list is rendered live from the voice session (talking indicators, join buttons per channel, password-protected channels prompt for their password).
  • Controls: mute, deafen, voice activity (with sensitivity) or push-to-talk (hold the button or V), output volume.

Deployment notes

  • Browsers only allow microphone access on HTTPS or localhost. Put the app behind a TLS reverse proxy (Caddy, nginx, ...) and forward WebSocket upgrades for /ws/voice. If your proxy rewrites the Host header, add your public origin to [voice] allowed_origins; set trust_proxy = true so per-IP limits use X-Forwarded-For.
  • arm64 / SBCs: everything is pure JS/WASM (Opus via opusscript), so npm needs no compiler. If you want lower CPU use, cd gateway && npm install @discordjs/opus (native addon) and the gateway will pick it up automatically.
  • The gateway needs outbound UDP to the TeamSpeak voice port (TS_VOICE_PORT, default 9987).
  • Gateway tests: cd gateway && npm test.
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage