Skip to content

Dunkstormen/stream_control

Repository files navigation

Stream Control

Small staff control panel for VATSIM Scandinavia livestream operations. The React client talks to a Node/Socket.IO server, which controls OBS through obs-websocket-js.

Endpoints

  • / - staff control dashboard
  • /overlay/map - OBS browser-source map focused on EKDK / Danish airspace
  • /overlay/bug - OBS browser-source CPH Live 2026 watermark bug
  • /overlay/atc - OBS browser-source watched ATC position panel

Requirements

  • Node.js 18+
  • OBS Studio with the WebSocket server enabled
  • OBS WebSocket reachable from the server host
  • TrackAudio running locally when using the TrackAudio controls

Setup

npm run install:all
cp server/.env.example server/.env

Then edit server/.env:

  • CONTROL_PASSWORD: shared staff password for the control panel
  • JWT_SECRET: long random string used to sign session tokens
  • OBS_HOST, OBS_PORT, OBS_PASSWORD: OBS WebSocket connection details
  • TRACKAUDIO_WS_URL: optional TrackAudio SDK WebSocket URL, default ws://127.0.0.1:49080/ws
  • SCHEDULE_TIME_ZONE: optional schedule clock timezone, default Europe/Copenhagen
  • PORT: HTTP port for the Node server
  • REDIS_URL: optional Redis URL for cached VATSIM snapshots
  • VATSIM_REFRESH_INTERVAL_MS: optional VATSIM polling interval, default 15000
  • AIRCRAFT_HISTORY_LIMIT: optional samples kept per aircraft, default 3
  • AIRCRAFT_HISTORY_MAX_AGE_MS: optional maximum aircraft sample age, default 600000
  • EVENT_STATS_AIRPORT: optional airport counted by the bug stats, default EKCH
  • EVENT_STATS_AIRPORT_LAT, EVENT_STATS_AIRPORT_LON: optional event airport position, defaults to EKCH
  • DEFAULT_TRANSITION_ALTITUDE_FT, DEFAULT_TRANSITION_LEVEL: optional fallback map label transition values, defaults 4000 and 45

Sector map data is generated as GeoJSON during npm run build from the EuroScope files in local-data/sectors and written to server/sectors.json.

Development

npm run dev

The Vite client runs on http://localhost:5173 and proxies API and Socket.IO traffic to the server on http://localhost:3001.

Production

npm run build
npm start

In production, the server serves the built client from client/dist.

Add http://localhost:3001/overlay/map as an OBS browser source to show the EKDK map overlay. Add http://localhost:3001/overlay/bug as a separate OBS browser source for the CPH Live 2026 watermark bug. Add http://localhost:3001/overlay/atc as a separate OBS browser source for the watched ATC position panel. The bug rotates to the stats layout every 5 minutes for 12 seconds by default; tune with ?intervalMinutes=5&showSeconds=12. The stats are live from /api/event-stats; green and red query params can still override the numbers for testing.

Docker

docker compose up --build

Compose starts the production app and Redis. The app uses host networking so it can reach OBS on 127.0.0.1:4455, and listens on http://localhost:3001.

Keep OBS_HOST, OBS_PORT, and OBS_PASSWORD in server/.env. Redis is published on 127.0.0.1:6379 for the app container.

Notes

  • Socket connections require a valid JWT from /api/auth/login.
  • Do not publish a real server/.env; keep only server/.env.example in source control and rotate secrets before sharing deployments.
  • Put the app behind HTTPS before exposing it outside localhost or a trusted LAN.
  • OBS command payloads are validated server-side before being sent to OBS.
  • TrackAudio commands are proxied through the authenticated Socket.IO server; TrackAudio itself only needs its local SDK WebSocket.
  • The server runs a lightweight VATSIM worker and exposes the latest snapshot at /api/vatsim-data.
  • The worker also stores rolling aircraft samples at /api/aircraft-history so overlays can animate between VATSIM updates.
  • Event stats are tracked from the VATSIM feed at /api/event-stats and persisted in Redis when available.
  • Aircraft labels resolve airline logos through /api/airline-logo/:code, backed by Kiwi logos with local overrides in server/airline-logo-overrides.json.
  • When REDIS_URL is set, VATSIM snapshots and aircraft history are cached in Redis; otherwise the server uses in-memory cache.
  • Login attempts are rate-limited in memory. For multiple server instances, move rate limiting to shared storage or put it behind a trusted proxy-level limiter.

About

Stream Control for VATSIM Scandinavias event Copenhagen Live

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages