No description
  • JavaScript 86.4%
  • CSS 8.2%
  • HTML 5.1%
  • Dockerfile 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Raphael f74222cef9 feat: auto-hide non-error status notifications after 3 seconds
Transient hints like 'saved' now fade away on their own; errors keep
staying visible until the user deals with them. A new status cancels
the pending timer so a fresh message is never cut short by an old one.
2026-10-12 20:32:11 +02:00
test feat: add Slide a Lama game, game stop/switch, persistent auto-login 2026-10-12 12:37:12 +02:00
web feat: auto-hide non-error status notifications after 3 seconds 2026-10-12 20:32:11 +02:00
.env.example webMVF: online conference tool (voice/video rooms, screen share, whiteboard, watch-together) 2026-10-09 15:30:49 +02:00
.gitignore webMVF: online conference tool (voice/video rooms, screen share, whiteboard, watch-together) 2026-10-09 15:30:49 +02:00
db.js feat: chat history, @mentions, room-list game indicator, admin activity log, mobile layout, PWA 2026-10-12 00:47:24 +02:00
docker-compose.yml webMVF: online conference tool (voice/video rooms, screen share, whiteboard, watch-together) 2026-10-09 15:30:49 +02:00
Dockerfile fix: copy games.js into the runtime image 2026-10-12 00:27:21 +02:00
games.js feat: add Slide a Lama game, game stop/switch, persistent auto-login 2026-10-12 12:37:12 +02:00
package-lock.json webMVF: online conference tool (voice/video rooms, screen share, whiteboard, watch-together) 2026-10-09 15:30:49 +02:00
package.json webMVF: online conference tool (voice/video rooms, screen share, whiteboard, watch-together) 2026-10-09 15:30:49 +02:00
README.md webMVF: online conference tool (voice/video rooms, screen share, whiteboard, watch-together) 2026-10-09 15:30:49 +02:00
server.js feat: add Slide a Lama game, game stop/switch, persistent auto-login 2026-10-12 12:37:12 +02:00
watch.js watch-together: extract YouTube stream URLs in-room via clients 2026-10-09 22:02:22 +02:00

webMVF

Online conference tool like Discord: voice/video rooms with screen share, room chat with media, per-room whiteboards, and watch-Youtube-together. Entry with just a name; optionally register the name (password) and use the admin panel.

Features

  • Voice/video rooms - P2P WebRTC mesh (server only relays signaling, never touches media), per-room chat, talking indicator, member list with mic + voice-activity, room list with per-room user counts, create/join rooms.
  • Screen share - getDisplayMedia (full desktop selectable, no tab-only picker), replaces camera while sharing, stops automatically on room change.
  • Room chat + media - send text plus images/video/audio attachments (uploaded to the server, 25 MB cap, extension whitelist).
  • Whiteboard - per room: pen, eraser, color, 3 brush sizes, drop images (drag to move), clear. Persisted per room, shared live.
  • Watch together - paste a YouTube URL, the server resolves it with yt-dlp, transcodes in real time with ffmpeg to HLS, and all clients in the room follow the same live edge (hls.js). Play / pause / resume / seek / stop are shared room state.
  • Accounts - register your name with a password (first registered user becomes admin). Registered names must enter their password on join. Passwords are remembered per browser (localStorage).
  • Roles + admin panel - manage registered users (role, reset password, delete), set/remove the server-wide password, set/remove per-room passwords. Admins enter all rooms without a password.
  • Password-protected rooms - admins set a room password; users can be invited in (invitee bypasses the password).
  • Profile pictures - pick an avatar on the landing page (stored per browser), shown in chat, member list and video tiles.
  • Device test - modal to pick/test microphone + camera before joining.
  • Reconnect - identity (uuid + name) survives page reloads and socket drops.
  • Config via .env - server name, port, DB/HLS/upload/whiteboard paths, STUN/TURN (ICE) servers, yt-dlp/ffmpeg binaries.

Quickstart (local)

npm install
cp .env.example .env   # adjust ICE servers etc.
npm start              # http://localhost:3000

Requires yt-dlp and ffmpeg on the PATH (for watch together; voice/video, chat and the whiteboard work without them).

Docker

cp .env.example .env   # adjust ICE servers etc.
docker compose up -d --build
  • Image: multi-stage node:22-slim (builds native deps, installs ffmpeg + python3 + ca-certificates + yt-dlp; ca-certificates fixes yt-dlp's SSL: CERTIFICATE_VERIFY_FAILED on YouTube).
  • Data (DB, HLS segments, uploads, whiteboards) persists in ./data (volume /data).
  • Healthcheck on /healthz.

Configuration (.env)

Variable Default Meaning
PORT 3000 HTTP port
SERVER_NAME webMVF Name shown to clients
DB_FILE data/webmvf.db SQLite database (users, roles, room passwords, invites)
HLS_DIR data/hls HLS segment storage
UPLOADS_DIR data/uploads Chat attachment storage (served at /uploads/)
WB_DIR data/whiteboards Per-room whiteboard JSON
ICE_STUN_URLS stun:stun.l.google.com:19302 Comma separated STUN urls
ICE_TURN_URLS - Comma separated TURN urls
ICE_TURN_USERNAME - TURN username
ICE_TURN_SECRET - With username: time-based creds (RFC 5389 style), generated per client
ICE_TURN_CREDENTIAL - Static credential, used when ICE_TURN_SECRET is empty
ICE_TTL_SEC 43200 Lifetime of generated TURN credentials
YTDLP_COOKIES - Path to cookies file for yt-dlp (fixes bot-check blocks)
YTDLP_BIN yt-dlp yt-dlp binary
FFMPEG_BIN ffmpeg ffmpeg binary

TURN notes: with ICE_TURN_SECRET set, the server issues a temporary <expiry>:<username> / HMAC-SHA1 credential pair to every client (works with coturn use-auth-secret). Without it, ICE_TURN_CREDENTIAL is passed through.

Tests

npm install
npm test
  • test/db.test.js - SQLite storage: users/roles, settings, room passwords, invites, scrypt hash/verify (module test)
  • test/ice.test.js - ICE server building + TURN credentials (module test)
  • test/watch.test.js - watch state machine with fake yt-dlp/ffmpeg (module test)
  • test/e2e.test.js - full server: HTTP + config/upload REST + sockets + rooms
    • passwords + invites + signaling relay + whiteboard + watch pipeline + HLS serving + traversal guards (e2e)

No network access needed: e2e uses fake yt-dlp/ffmpeg scripts.

Layout

server.js          express + socket.io server (signaling, rooms, chat, whiteboard,
                   accounts/admin, uploads, HLS)
db.js              SQLite storage (better-sqlite3): users, roles, settings,
                   room passwords, invites
watch.js           per-room YouTube -> HLS state machine (yt-dlp + ffmpeg)
web/               vanilla JS client (no build step)
  js/ezWebRTC.js   RTCPeerConnection wrapper (copied from basicwebrtc)
  js/hls.min.js    vendored hls.js
  js/adapter.min.js vendored webrtc-adapter
test/              node:test suites