SnailSync · VLC

Two computers, one playhead.

You play the film in VLC on your own machine. Your friend plays the same file in their own VLC, and stays in step. Anyone can pause, seek or open a different file — everyone follows within a fraction of a second. Nothing is streamed and nothing is uploaded.

VLC 3.x · Python 3.8+ · no dependencies

Your machine

Alien.mkv · VLC

playing · 00:00:05.9

0.00–0.15 s apart after a pause
Their machine

Alien.mkv · VLC

playing · 00:00:05.9

Why this exists

Watch together without handing the film to anybody.

Every watch-party tool wants the movie uploaded to their servers or streamed through their player. That is a strange thing to do with a file you already own, for a group of three friends. SnailSync shares one number instead of the film: where the playhead is right now. Your movie never leaves your disk.

01 · Your file

Nothing is streamed

Everybody plays their own copy. Only the position travels — a few hundred bytes a second, so a 40 GB remux costs as much bandwidth as a text message.

02 · Your VLC

A normal VLC window

No custom player. SnailSync drives the VLC you already have, through its control interface on 127.0.0.1. Keyboard, subtitles and volume stay yours.

03 · Anyone drives

No host privilege

Anyone can pause, seek, resume or change the file. Whoever moves first wins, and two people pressing pause at the same instant cannot corrupt anything.

04 · No server

The host is the server

The person who starts the night also runs the little coordinator. If they close their laptop, the others keep watching and keep control.

How it works

A shared projection, not a stream.

One number is the whole protocol. Everyone computes the same projection of it, which is what makes two machines agree without either knowing when the other showed a frame.

  1. 1

    The timeline is an anchor

    “Position 412.0 s at wall clock 17:31:07, playing, rate 1.0.” That is the entire shared state. Where the movie should be is anchor + (now − at), and every client computes it independently.

  2. 2

    Each client measures its own clock

    Position error is clock error: a machine a second out is a second out in the movie. A five-sample round trip against the coordinator pins the offset to single-digit milliseconds on a home network.

  3. 3

    Corrections are graduated

    Under 0.12 s: do nothing. A few hundred milliseconds: nudge the playback rate by at most 3%, which also soaks up the slow drift between two machines' audio clocks over a two-hour film. Only a real seek, a late join or a stalled buffer moves the playhead.

  4. 4

    The client decides, the coordinator referees

    A peer that wants to move the movie computes the whole new state itself and posts it with the sequence number it believed it was replacing. The coordinator accepts it or rejects it with the state that won — so a race simply means the loser redoes its work on top of the winner's.

How close it actually gets

Numbers from two real VLC instances.

Not estimates. Two VLC 3.0.21 players and one coordinator on a local network, driven by the built-in smoke test — including pressing keys in the host's own VLC window the way a person would.

What happensResult
Someone pauses0.00–0.15 s apart
Someone drags the timeline0.00–0.25 s apart
A guest joins a film already runninglands within 0.25–0.5 s
Left alone while playingunder 0.6 s, rate 1.000
The host closes VLCguests keep playing

A pleasant side effect of graduated corrections: once the group has settled, the playback rate sits at exactly 1.000 instead of permanently running 2% fast. A constant offset — VLC reports the playhead a fraction behind where it is really showing — is learned and left alone rather than chased, because no amount of rate will ever remove it.

Using it

Two commands, once.

  1. A

    The host

    Point it at the film. It starts VLC, starts the coordinator, and prints one line to send everyone.

    $ vlcsync host ~/Movies/Alien.mkv
  2. B

    Everyone else

    Paste what the host printed. Their VLC opens, loads the same film, and lands where the host is.

    $ vlcsync join http://192.168.1.42:8790 --name Sam --token kQ3f9Zx1aB
  3. C

    Then just use VLC

    No new player to learn, no window to keep in front. Everything happens in the VLC you already have open.

In the VLC window
You doEveryone else
Space / pausepauses at the same place
Click the timelinejumps there too
Space againresumes together
Open another fileis asked to load it too
Turn your volume upnothing — volume is never shared
Honest limits

What it does not do.

VLC will not say which frame it is displaying, only roughly where the playhead is. That one fact sets the ceiling on all of this, and it is worth saying plainly rather than hiding behind a demo.

Not frame-perfect

Peers agree on the same projection of the timeline, which is why they stay with each other. They do not lock to each other's video. Expect a few hundred milliseconds, not the frame.

A seek can leave half a second

VLC's seek command takes whole seconds only — a decimal is silently mangled. Two peers rounding the same target can land on different seconds. A pause is far tighter than a seek, for that reason.

Everyone needs the same file

Same film, each on their own disk. Different rips, different cuts or a different release will not line up, and nothing can fix that from the outside.

Same network

Same Wi-Fi, or the same VPN (Tailscale, WireGuard and friends). There is no relay on purpose — a relay would put somebody else's computer in the middle of your film.

Questions

The ones that come up.

Does it work with a film that is still downloading?

Partly. VLC will play what it has, but a peer cannot land on a position that has not been downloaded yet, and seeking around an incomplete file behaves badly. Let it finish first.

What if my friend has a different copy?

It will drift, because the two files are different lengths and the timestamps do not line up. Nothing can detect that from the outside, so SnailSync keeps trying to make two different films agree.

Can someone in another country join?

Over the same VPN mesh, yes — and the clock measurement handles the latency. What it does not handle is a bad link: measure the round trip across a stalling connection and the offset is coarse. On a home network it is single-digit milliseconds.

Does anyone see what I am watching?

The people in your session see the file name and the position, because that is the point. Nobody else does, and nothing is logged anywhere — the coordinator holds one number in memory and it is gone when the night ends.

Do I need a server?

No. The host's machine runs the coordinator. You can run it somewhere else if you want, but there is no reason to.

What do I need installed?

VLC 3.x and Python 3.8 or newer — nothing else, no packages. macOS ships a suitable Python already.

Get it

Source, free to read and run.

About 1,200 lines of Python: the VLC control client, the timeline arithmetic, the clock measurement, the coordinator and the client loop. No dependencies outside the standard library.

Read it

The whole thing

Every file on GitHub, including the four VLC behaviours that silently break a sync tool and how each one is handled.

→ github.com/Snail3D/snailsync
Run it

Three lines

Clone, then point it at a film. Nothing to build, nothing to install.

$ git clone \ https://github.com/Snail3D/snailsync $ cd snailsync $ python3 -m vlcsync host film.mkv
Prove it

Check the numbers

The test that produced the table above ships with it: two real headless VLC instances, driven end to end.

$ python3 tools/smoke.py