LiveKit-based streaming infrastructure for live music performances.
Overview¶
The streaming stack is built on LiveKit, an open-source WebRTC Selective Forwarding Unit (SFU). LiveKit handles real-time audio/video streaming with low latency, supporting multiple participants and recording.
A custom SvelteKit dashboard at stream.spacemusic.tv provides a web interface for managing rooms, streams, and tokens.
Components¶
| Component | Image | Port | Purpose |
|---|---|---|---|
| LiveKit Server | livekit/livekit-server:v1.6.1 |
7880 | SFU core -- routes WebRTC media between participants |
| Redis | redis:7-alpine |
6379 | Session state and coordination |
| Egress | livekit/egress:latest |
-- | Recording and restreaming (outputs to MinIO) |
| Ingress | livekit/ingress:latest |
8080 (WHIP), 1935 (RTMP) | Ingest streams from OBS, GStreamer, browsers |
All four LiveKit containers run with network_mode: host -- they bind directly to the host network, not Docker bridge networking. This is required for WebRTC's UDP port ranges to work correctly.
Network and Ports¶
| Endpoint | Port(s) | Protocol | Purpose |
|---|---|---|---|
livekit.spacemusic.tv |
7880 | TCP | LiveKit API and WebSocket signaling |
livekit-whip.spacemusic.tv |
8080 | TCP | WHIP ingest (browser-based WebRTC push) |
| RTMP Ingest | 1935 | TCP | RTMP ingest from OBS or similar |
livekit-turn.spacemusic.tv |
5349 (TLS), 3478 (UDP) | TCP/UDP | TURN server for NAT traversal |
| WebRTC Media | 50000-60000 | UDP | RTC peer connections |
| Prometheus Metrics | 7889 | TCP | Internal metrics endpoint |
Stream Dashboard¶
The stream dashboard at stream.spacemusic.tv is a custom SvelteKit application that wraps the LiveKit server SDK. It is deployed via devpush on a Node.js 20 runner.
Stack: SvelteKit 2.x, Svelte 5 (runes), shadcn-svelte, Tailwind CSS v4, livekit-server-sdk v2.15.0
Features:
- Room management (create, list, delete rooms)
- Participant list with mute/kick controls
- Token generation for room access
- Ingress management (create RTMP/WHIP/URL ingress streams)
- Egress controls (start/stop recording)
- Authentication via Authentik forward auth
Dashboard API routes:
| Route | Methods | Purpose |
|---|---|---|
/api/health |
GET | LiveKit connectivity check |
/api/rooms |
GET, POST | List / create rooms |
/api/rooms/[name] |
GET, DELETE | Room detail / delete |
/api/rooms/[name]/participants |
GET, POST | List / remove / mute participants |
/api/ingress |
GET, POST, DELETE | Ingress stream management |
/api/tokens |
POST | Generate JWT access tokens |
Ingress (Stream Input)¶
LiveKit Ingress accepts streams from external sources and publishes them into LiveKit rooms.
RTMP -- Push from OBS or similar software to rtmp://livekit.spacemusic.tv:1935/live/<stream-key>. Configure in OBS as a custom RTMP server.
WHIP -- Browser-based WebRTC ingest at livekit-whip.spacemusic.tv. Supported by OBS 30+ and GStreamer. Lower latency than RTMP.
URL Pull -- LiveKit can pull from an existing RTMP/HLS/WHIP URL and republish into a room.
Egress (Recording)¶
LiveKit Egress records room audio/video and outputs to the MinIO recordings bucket (30-day lifecycle). Recordings can be triggered via the stream dashboard or the API gateway.
The Egress service uses a headless Chrome instance internally to composite room layouts, so it requires more resources than other LiveKit components.
Token Authentication¶
LiveKit uses JWT tokens for room access. The stream dashboard generates tokens via the livekit-server-sdk:
const token = new AccessToken(API_KEY, API_SECRET, {
identity: username,
ttl: '6h'
});
token.addGrant({
room: roomName,
roomJoin: true,
canPublish: true,
canSubscribe: true,
canPublishData: true
});
Environment variables required: LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL (internal WebSocket), LIVEKIT_WS_URL (public WebSocket).
Monitoring¶
Prometheus scrapes LiveKit metrics at 172.17.0.1:7889/metrics (Docker gateway IP, since LiveKit runs on host network). These metrics power the "LiveKit Streaming" Grafana dashboard at dashboard.spacemusic.tv, showing:
- Active rooms and participants
- Track bandwidth (audio/video)
- Connection quality scores
- Egress/Ingress status