🎬 VideoSync

Watch videos together in real-time. Each user loads a local video file — only sync commands and chat messages travel over the network.

Architecture

This project consists of three main components:

  • Server: A fast, lightweight WebSocket server built with Bun.
  • Web Frontend: A vanilla HTML/CSS/JS single-page application for joining rooms and syncing video playback.
  • Desktop App: A Python/PyQt6 application with embedded VLC (python-vlc). Note: The desktop client was specifically created because web browsers (like Chrome) have issues handling and playing MKV files natively.

Features

  • Room system — create a room, share the 6-character code with friends.
  • File verification — joiners must have the exact same file (matched by name + size).
  • Playback sync — play, pause, seek, and speed changes broadcast to all clients instantly.
  • Drift correction — automatic re-sync every 5 seconds to keep everyone aligned.
  • Live chat — YouTube-style chat sidebar with colored usernames.
  • Local playback — multi-gigabyte files work fine since nothing is uploaded.
  • Broad format support — the desktop app leverages VLC to play MKV and other formats that browsers struggle with.

Quick Start

1. Start the Server

# Install Bun (if not already installed)
curl -fsSL https://bun.sh/install | bash

# Start the server
bun run server.ts

2. Connect via Web Frontend

Once the server is running, open http://localhost:3000 in your browser to access the web app.

  1. Enter your name and select a video file → Create Room
  2. Share the room code with a friend
  3. Friend enters the code → Join Room → selects their copy of the same file
  4. Play/pause/seek in either browser — the other stays in sync

If you are playing MKV files or formats not supported by your browser, use the desktop client:

cd desktop-client

# Install dependencies using uv
uv sync

# Run the app
uv run main.py

You can also build a standalone executable for the desktop app using the provided build.ps1 script (requires PyInstaller).

Quick Run on Linux

If you just want to run the desktop client without cloning the repo manually, use the launcher script. Prerequisites: git and uv.

# Download the script
curl -fsSL https://gitea.peterstockings.com/peterstockings/video-sync/raw/branch/master/desktop-client/run-videosync.sh -o run-videosync.sh
chmod +x run-videosync.sh

# Run (clones on first launch, pulls updates on subsequent runs)
./run-videosync.sh

Deployment

# Run on a custom port
PORT=8080 bun run server.ts

For production, put behind nginx with WebSocket proxy support:

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

Tech Stack

Component Technology
Server Bun (native HTTP + WebSocket)
Web Frontend Vanilla HTML / CSS / JS
Desktop App Python, PyQt6, python-vlc, websockets

Project Structure

├── server.ts          # Bun WebSocket server
├── package.json
├── public/
│   ├── index.html     # Single-page web app
│   ├── style.css      # Dark theme
│   └── app.js         # Client sync + chat logic
└── desktop-client/
    ├── main.py        # Desktop app entry point
    ├── pyproject.toml # Python dependencies (uv)
    └── vlc_player.py  # Embedded VLC player
Description
No description provided
Readme 822 KiB
2026-03-02 11:27:19 +00:00
Languages
Python 55.2%
JavaScript 15.9%
CSS 13.1%
TypeScript 9%
HTML 6.3%
Other 0.5%