尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Virtual watch-party: synced YouTube and Twitch, voice, chat and screen sharing in shared rooms.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Watch together, wherever you are. Voice, chat, synced YouTube, Twitch and Kick, and screen sharing in one shared room. Installs as an app on phones and desktops.
Live at nexuslounge.party.
I built it so my friends and I could watch League of Legends Worlds together, but it's general purpose: sports, premieres, VODs, movie nights.
| Phone | Phone: streams | Phone: landscape |
|---|---|---|
| Collapsed side panel | People | Room settings |
|---|---|---|
| Playlists and queue | Landscape with chat open |
|---|---|
| Choose where video plays (TV connected) | Phone player bar: More menu | Account |
|---|---|---|
Rooms and people
Watching
127.0.0.1:11470, or any address you set); links play straight in the browser when they can, and through Stremio when they can't (insecure http redirects, formats your browser can't decode, services that block browsers), which converts them to HLS that plays everywhere. Matroska plays as it is on Chrome and Edge, and HEVC/AC3/E-AC3 are used directly where your browser decodes them. Friends without Stremio watch a live feed from the owner's browser. Friends with Stremio tap to download the torrent themselves, in sync, with no load on the owner, or paste their own link or magnet to the same video (the size and length must match). Links stay in the owner's tab and are never sent to the room or the server, expired ones can be replaced in place, and error clips from link services are flagged. Chrome and Edge ask once to let the site reach devices on your network. Subtitles (tracks inside the video, files that came with a torrent, a file from your computer, or a search by title through OpenSubtitles) are chosen per person.Playback controls
Voice and chat
Phones and tablets
Desktop
\ key) to be fully immersed. Voice controls move into the header and an unread badge keeps you posted on chat.F fullscreen, M mute, and for controllers Space/K play and pause, ←/→ skip 5 seconds, J/L skip 10 seconds. Shortcuts are ignored while typing.Any screen
/account. Terms of Service and Privacy Policy are public at /terms and /privacy (use these URLs in the Discord developer portal).flowchart LR
B[Browser<br/>Next.js app] -- HTTPS --> W[web<br/>Next.js + Auth.js]
W -- signed token --> S[server<br/>Fastify + ws]
B -- WebSocket ticket --> S
B -- WebRTC --> L[(LiveKit)]
S -- grants and tokens --> L
apps/web Next.js app (UI, Discord login via Auth.js, thin API routes)
apps/server Fastify + ws (rooms in memory, LiveKit tokens, sync WebSocket)
packages/shared zod schemas, types and the sync maths shared by both
docs/ Railway notes and screenshots
Requirements: Node 22.18+ (the server runs TypeScript directly), pnpm 10+, and Docker only if you self-host LiveKit locally.
Setup
pnpm installcp .env.example .env and fill it in (below).pnpm dev, then open http://localhost:3000.pnpm dev starts the web app (port 3000) and the server (port 4000). For local voice, run pnpm livekit in another terminal (needs Docker), or use LiveKit Cloud instead.
DISCORD_CLIENT_ID and reset/copy the Client Secret into DISCORD_CLIENT_SECRET.http://localhost:3000/api/auth/callback/discord (add your production URL the same way).AUTH_SECRET with openssl rand -base64 32..env.example): pnpm livekit runs LiveKit in dev mode with key devkey and secret secret, at ws://localhost:7880.wss://….livekit.cloud) into LIVEKIT_URL and an API key/secret pair from Settings → Keys into LIVEKIT_API_KEY / LIVEKIT_API_SECRET.| Variable | Used by | Purpose |
|---|---|---|
DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET | web | Discord OAuth |
AUTH_SECRET | web, server | Session encryption and server token signing (must match) |
AUTH_URL | web | Public URL of the web app |
LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET | server | LiveKit connection and token minting |
NEXT_PUBLIC_SERVER_WS_URL | web | WebSocket URL of the server (wss://<server>/ws); the HTTP URL is derived from it |
SERVER_WS_URL | web | Optional runtime override of the above. Next bakes NEXT_PUBLIC_* values in at build time, this one is read when the app runs |
PORT | server | Server port (default 4000) |
ADMIN_SECRET | web, server | Optional. 32+ random characters, different from AUTH_SECRET; signs admin requests and the admin session cookie |
ADMIN_DISCORD_IDS | web, server | Optional. Comma-separated Discord user IDs allowed to open /admin |
ADMIN_TOTP_SECRET | web | Optional. Base32 key for the authenticator app used to unlock /admin |
AUTH_SECRET) and call the Fastify server, which verifies it. Joining a room returns a LiveKit token plus a room-scoped ticket for the sync WebSocket.packages/shared/src/protocol.ts).position, playing and a server timestamp. Clients estimate the server clock (median of ping samples) and compute the expected position locally. Drift is the median of the last few readings, small drift is fixed by gently changing playback speed, and seeks are rare and debounced. Add ?debug to a room URL to see the live numbers.pnpm typecheck
pnpm --filter @nexus/shared test # URL parsing, drift maths, live-edge helpers, tokens, sound cues
pnpm --filter @nexus/server test # spawns the server; permissions, guest approval, removal, moderation,
# late joiners, passwords, tickets, TV pairing over real WebSockets
CI runs the same checks plus a production build on every push.
Browser end-to-end suites (Chrome plus WebKit for the iPhone-style checks) live in e2e/: rooms, voice, push to talk, fullscreen, the queue and playlists, gestures, phone layouts and "nothing covers the Twitch player".
Two services built from the Dockerfiles in apps/server and apps/web, auto-deployed from main. LiveKit must be LiveKit Cloud, since Railway doesn't support UDP. Step-by-step instructions and config templates are in docs/railway-deploy.md.
Every server deploy or restart ends all rooms, because they live in memory. Keep the server at a single instance.
Copyright (C) 2026 dsameendra
Nexus Lounge is free software under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later). You can use, modify and host it, but if you run a modified version as a service, you must make your version's source available to its users under the same license. Derivative works must stay open source.
If you like it and want to help with hosting costs, you can support it on Ko-fi. It is optional, and a star on the repo helps just as much.