58 lines
2.4 KiB
Markdown
58 lines
2.4 KiB
Markdown
# 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`):
|
||
|
||
```sh
|
||
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.
|
||
- Voice capture uses mono 48 kHz Opus-oriented settings, a 64 kbps audio ceiling,
|
||
and periodic packet-loss, jitter, and RTT quality diagnostics.
|
||
|
||
## 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_TRANSPORT_POLICY` | WebRTC ICE policy: `all`, `relay`, or `none` |
|
||
| `ICE_SERVERS_JSON` | full `{"iceServers":[...]}` override, wins over the above |
|
||
| `PORT` / `HOST` | listen address (default 8081 / 0.0.0.0) |
|
||
|
||
Example with coturn:
|
||
|
||
```sh
|
||
TURN_URLS='turn:turn.example.com:3478?transport=udp,turns:turn.example.com:5349' \
|
||
TURN_USERNAME=mats TURN_CREDENTIAL=secret npm start
|
||
```
|
||
|
||
For deployments where clients are commonly behind separate NATs, set
|
||
`ICE_TRANSPORT_POLICY=relay` so media consistently uses the public TURN
|
||
service instead of depending on NAT hairpinning or direct candidate pairs.
|
||
|
||
## 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.
|
||
- For larger rooms or consistently lower bandwidth, replace the mesh with an SFU;
|
||
the current quality tuning improves the P2P path but does not change its N² cost.
|
||
- Text channels are decorative. No persistence, no rate limiting.
|
||
- Screen-share negotiation storms on join/leave are expected at small scale.
|