A real-time synchronized video watching application for two remote users. Both parties watch the same local video file through the browser — no video streaming involved. Only play/pause/seek commands and chat messages are synced via WebSocket.
- Frontend: React + Vite
- Backend: Node.js + Express + Socket.io
- Sync: WebSocket (real-time bidirectional)
cd backend
npm install
npm startServer runs on port 3001.
cd frontend
npm install
npm run devOpen http://localhost:5173 in your browser.
- Open
http://localhost:5173in two different browser tabs (or two different machines). - Enter the same Room Name (e.g.
movie-night), use different display names, and click "Join Room". - Select the same video file on both sides (the file is not uploaded to the server — it plays locally via
URL.createObjectURL). - When one side plays/pauses/seeks, the other side mirrors the action with ~100-200ms delay.
- Use the chat panel on the right for real-time messaging.
To connect from different networks, expose the backend via a VPS, ngrok, or Cloudflare Tunnel. Then update the SOCKET_URL constant in frontend/src/App.jsx to your server address.
CORS is configured with origin: "*" for development. Restrict this in production.
An isIncomingSignal ref flag prevents feedback loops:
- When a video action arrives from the server, the flag is set to
true, the video updates, then resets after 100ms. - User-triggered
onPlay/onPause/onSeekedevents skip server emission when the flag istrue.
- This project is for development/personal use. Restrict CORS
originin production. - Both sides must use the exact same video file (same encoding, same duration) for perfect sync.