diff --git a/Voice-and-Video.md b/Voice-and-Video.md new file mode 100644 index 0000000..0e154a9 --- /dev/null +++ b/Voice-and-Video.md @@ -0,0 +1,125 @@ +# Voice & Video + +Dumpster uses LiveKit for real-time voice and video communication. LiveKit is an open-source WebRTC SFU (Selective Forwarding Unit) that handles media routing between participants. + +## Architecture + +``` +Client ──(WS)──> Dumpster API ──(token)──> Client +Client ──(WebRTC)──> LiveKit SFU ──(WebRTC)──> Other Clients +``` + +- **Dumpster backend** generates room tokens and enforces permissions +- **LiveKit** handles all media (audio, video, screen share) +- **coturn** provides TURN relay for clients behind NAT + +## Setup + +### 1. Generate LiveKit API Keys + +```bash +# Generate a random API key and secret +echo "API_KEY: $(openssl rand -hex 12)" +echo "API_SECRET: $(openssl rand -hex 24)" +``` + +Add to `.env`: +``` +LIVEKIT_API_KEY= +LIVEKIT_API_SECRET= +LIVEKIT_URL=wss://livekit.your.domain +``` + +### 2. Start Services + +```bash +docker compose -f docker/compose.yml up -d livekit coturn +``` + +### 3. Verify + +```bash +# Check LiveKit is running +curl http://localhost:7880 + +# Check coturn is running +docker logs dumpster-coturn +``` + +## API Endpoints + +### Get Voice Token + +``` +POST /api/v1/voice/token +Authorization: session cookie + +{ + "room_name": "voice-channel-id" +} + +Response: +{ + "token": "", + "livekit_url": "wss://livekit.your.domain" +} +``` + +### List Participants + +``` +GET /api/v1/voice/rooms/{roomID}/participants +Authorization: session cookie + +Response: +[ + { "identity": "username", "state": "connected" }, + { "identity": "username2", "state": "disconnected" } +] +``` + +## WebSocket Events + +| Event | Data | Description | +|-------|------|-------------| +| `VOICE_JOIN` | `{ room_name, user_id, username }` | User joined voice channel | +| `VOICE_LEAVE` | `{ room_name, user_id, username }` | User left voice channel | +| `VOICE_MUTE` | `{ room_name, user_id, muted }` | User muted/unmuted | +| `VOICE_DEAFEN` | `{ room_name, user_id, deafened }` | User deafened/undeafened | + +## Frontend Components + +| Component | Location | Description | +|-----------|----------|-------------| +| `VoiceChannel.tsx` | Sidebar | `🔊 channel-name` with participant count | +| `VoicePanel.tsx` | Chat area | Box-drawn frame with participant list | +| `VoiceControls.tsx` | VoicePanel | `[m]` mute, `[d]` deafen, `[cam]` video, `[share]` screen, `[x]` disconnect | +| `stores/voice.ts` | Stores | Zustand store for voice state management | + +## NAT Traversal + +coturn runs as a TURN relay for clients behind restrictive NAT (carrier NAT, corporate firewalls). LiveKit is configured to use coturn automatically. + +**Ports required:** +- 3478/tcp+udp (TURN) +- 5349/tcp+udp (TURNS) +- 10000-20000/udp (TURN relay range) +- 7880-7882 (LiveKit) +- 50000-50100/udp (LiveKit relay) + +## Troubleshooting + +### Can't connect to voice channel +1. Check LiveKit is running: `docker logs dumpster-livekit` +2. Check API keys match in `.env` and `docker/livekit.yaml` +3. Check browser console for WebRTC errors + +### No audio +1. Check browser permissions for microphone +2. Check device selection in settings +3. Try deafen/undeafen toggle + +### NAT issues +1. Check coturn is running: `docker logs dumpster-coturn` +2. Verify TURN ports are open (3478, 5349, 10000-20000) +3. Check `DUMPSTER_HOST` is set to your public domain diff --git a/_Sidebar.md b/_Sidebar.md index 4d2cba3..f5ede5b 100644 --- a/_Sidebar.md +++ b/_Sidebar.md @@ -5,6 +5,7 @@ - [Architecture](Architecture) - [API Reference](API-Reference) - [Profiles](Profiles) +- [Voice & Video](Voice-and-Video) - [Frontend Design](Frontend-Design) - [Self-Hosting](Self-Hosting) - [Roadmap](Roadmap)