Files
gibbz/README.md
T
mats 5757156843
Build and Publish / Metadata (push) Successful in 1s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 18s
feat: migrate voice app, add otel/rum, dockerfile, k8s deployment with ingress
2026-09-22 09:43:47 +02:00

1.8 KiB
Raw Blame History

gibbz voice — POC

Discord-clone proof of concept: peer-to-peer WebRTC voice chat + screen sharing with position-based spatial audio and pluggable STUN/TURN.

Run (Node 18+, only dep is ws):

npm install
PORT=8081 npm start
# open http://localhost:8081, click a voice channel, allow mic

What works

  • Mesh WebRTC voice (perfect negotiation; lowest peer id initiates)
  • Screen share with audio (mic is spatialized, screen audio plays direct)
  • Spatial audio: drag your avatar on the plane; remote mics run through a PannerNode (HRTF, inverse distance). Positions sync over signaling.
  • Custom STUN/TURN: gear icon → JSON override in localStorage, applied on next join. Server default comes from env (below).
  • Mute (M), deafen (D), per-peer volume, speaking indicators.

ICE configuration (server side)

Env var Meaning
STUN_URLS comma-separated stun: urls (Google defaults)
TURN_URLS comma-separated turn:/turns: urls
TURN_USERNAME / TURN_CREDENTIAL static TURN creds
ICE_SERVERS_JSON full {"iceServers":[...]} override, wins over the above
PORT / HOST listen address (default 8081 / 0.0.0.0)

Example with coturn:

TURN_URLS='turn:turn.example.com:3478?transport=udp,turns:turn.example.com:5349' \
TURN_USERNAME=mats TURN_CREDENTIAL=secret npm start

POC shortcuts (productionize later)

  • No auth, no reconnection, rooms are in-memory, signaling is unencrypted ws behind the preview ingress (use wss/TLS in front for real deploys).
  • No media server: N² mesh — fine for small rooms, needs SFU (mediasoup/livekit) beyond ~6–8 participants.
  • Text channels are decorative. No persistence, no rate limiting.
  • Screen-share negotiation storms on join/leave are expected at small scale.