Starsync
Put up any video and everyone watches it in sync: the relay reads it once and passes it to the whole group.
Video in the screenshots: Sintel © Blender Foundation, durian.blender.org, CC BY 3.0.
I made Starsync because I'd had it with Syncplay and Discord streaming. Here is what it does differently.
Why not Syncplay or Discord?
Syncplay means two windows, everyone needing their own copy of the file and switching every video by hand. Discord is built for live streams: one dropped connection cuts the video, and the quality drops with it.
| Syncplay | Discord | Starsync | |
|---|---|---|---|
| Everything in one window | ✕ | ✓ | ✓ |
| Friends don't need their own copy | ✕ | ✓ | ✓ |
| Original quality for everyone | ✓ | ✕ | ✓ |
| A dropped connection doesn't cut the video | ~ | ✕ | ✓ |
| Next video without switching by hand | ✕ | ~ | ✓ |
| Instant sync and a proper ready check | ~ | ✕ | ✓ |
The relay: one stream for everyone
The heart of Starsync. One person puts up a video and it is read once; the host passes that one stream to everyone. Nobody needs a copy of the file, nothing is uploaded first, and only the host needs an open port. The host can be anyone's PC or a small dedicated server on an always-on box. Pick a way of sharing to see where the bytes go and what each connection pays.
Your app reads the video from the site once. The same stream plays for you and goes up to the host, which sends it on to everyone. If it plays for you, it plays for them, your cookies included.
The same path as a link: your app streams the file to the host, the host passes it on. Nothing is uploaded anywhere first, and nothing is converted.
When you are the host, the file streams straight from your disk to everyone. Only the host's upload is used.
The host downloads the link once into memory and serves everyone, you included. Handy when the host has the fast connection.
Each app loads the link by itself. The host carries no video at all, only the clock.
Everyone with an account plays it straight from Jellyfin with their own sign-in. Friends without one get it through the host's login, which never leaves the host.
1× = the video's own bitrate; a 1080p episode is usually about 3–10 Mbit/s. Separately, everyone keeps a tiny sync connection to the host: just "position, playing".
Under the hood
What actually happens between pressing Play on a link and your friends watching it.
- 1
Your app dials the host
The connection goes out from your PC, so sharing works behind any router, NAT or mobile network: no port forwarding on your side. Only the host listens.
WebSocketDart - 2
The video is read once
One sequential reader pulls the video from the site (through yt-dlp for pages like YouTube) and keeps 64 MiB ahead. The same bytes feed your own player over a local connection and the upload to the host, so nothing is downloaded twice. YouTube is read in 10 MiB ranges, which it serves at full speed instead of throttling.
yt-dlpHTTP ranges - 3
The host keeps it in memory
The host stores the stream in 256 KiB slices: up to 256 MiB ahead of the furthest viewer and 64 MiB behind the slowest, plus the start and end of the file that players read for seeking. Each byte leaves your PC about once, however many friends watch. Nothing is written to disk.
Dart serverin-memory buffer - 4
Friends play it like any web video
Each friend's mpv asks the host for byte ranges over plain HTTP, so seeking just works and a skip inside the buffer is instant. YouTube's separate video and audio are relayed as two streams and played together; HLS and DASH streams are relayed segment by segment. In tests a 1080p YouTube seek through the relay took under 0.8 s, faster than mpv reading YouTube directly.
mpvHTTP rangesHLS / DASH - 5
Built to survive bad connections
The upload adapts to your connection's speed and latency. If you drop, friends keep playing from the host's buffer while your app reconnects by itself and carries on from the exact byte it reached. Live streams and DRM-protected video are not relayed.
flow controlauto-reconnect - 6
The next video is already warm
Up next is one shared queue. While a video plays, the host already starts getting the first item from whoever added it (or fetches the link itself), and every app loads its first seconds. So when the 10-second countdown ends, or someone skips, the next video starts at once.
warm relaypreload
Drops don't stop the movie
It rides out internet drops for as long as there's buffer. Whether the server or a viewer drops, both recover smoothly without getting in the way of the video, and the sync is so tight it often feels like nobody is on the other end.
The anime week at a glance
Browse the Jellyfin library with watch tracking on everything. The weekly schedule shows when each episode airs, what's already on Jellyfin and what you've watched, and lets you request new shows from your auto-downloader or Sonarr.

Features
- The relay: anything one person can play, everyone can watch
- Play, pause and seek stay in sync for everyone
- Shared Up next queue: anyone adds, reorders or plays next, with a countdown everyone sees
- Links you put up are downloaded once for everyone
- Chat, quick chat and danmaku over the video
- Invite with one starsync:// link, no accounts
- Updates itself, with a What's new list
- Anime4K upscaling built in, plus your own .glsl shaders; each viewer picks their own
- A lightweight dedicated server (starsync-server) for an always-on box: no display needed, systemd unit included
Changelog
1.4.0LatestLinks you put up are downloaded once for everyone, quick chat and danmaku in the player, plus What's new and fixes for Windows, the relay and chat.20 changes
Added- What's new: the update band shows what changed, and after an update the app shows the full list once (also in Settings → About)
- Update channel in Settings → Updates: Stable, or Dev for test builds; Dev stays on test builds after a release and still gets the newer release when there is one
- Sharper subtitles and picture: the video and its subtitles are drawn at your screen's resolution instead of the video's (Settings → Player → Sharp video and subtitles, on by default)
- Invite links: Invite copies just a starsync:// link, password included, so a friend just clicks it (or copies it and switches to Starsync) and the app asks "Join Bob's server?"
- Invite finds your internet address on its own and says when your router needs the port forwarded; Other addresses picks your home-network or VPN address instead
- Starsync runs once: a link clicked while it is open goes to the open window
- Quick chat: press Enter in the big player to type a message in a small box at the bottom, without opening the chat panel and without the mouse pointer or the controls popping up; it shares its draft with the chat panel, closes by itself when you stop typing, and subtitles move up out of its way
- Danmaku notifications: chat, joins, leaves and Up next can fly across the top of the picture instead of popping up (Settings → Notifications & sounds → Notifications: Danmaku, off by default), with speed, how many at once, where, opacity, size, boldness, outline and avatars all adjustable and a live preview
- Player panel: ⚙ → Player settings opens a panel at the right of the player that stays open while you watch, with tracks, subtitle size, picture, volume and notification settings
- Subtitles can move up above the controls while they show (Settings → Player → Subtitles above the controls, off by default), and their size can be changed
Changed- A link you put up is downloaded once: you and everyone else watch the same stream, so nobody drifts ahead or stalls alone, and sites like Bilibili are far less likely to block it
Fixed- Upscaling shaders (Anime4K, the HQ modes) no longer shift the colours or draw a grid over the picture, which showed most in a large window or fullscreen
- Sharp video: resizing the window or opening the chat panel no longer shrinks the picture for a moment before it jumps back
- Joining while something plays on Windows: the video opens again by itself when it was too early
- Relay: players no longer get stuck after a slow or stalled source
- Relay: X (Twitter) clips play through the relay
- Relay: gentler retries, so Bilibili stops blocking the server
- Relay: a source that refuses the old link (412) gets a fresh address and keeps playing
- Chat pop-ups stay away while the chat panel is open (the sound still plays)
- Bilibili and other sites no longer stop a video halfway when you watch alone or with "Everyone fetches it": a cut connection picks up where it left off
1.3.2Fixes Windows closing by itself about 3 seconds after every start.1 change
Fixed- Windows: the app no longer closes by itself about 3 seconds after starting (1.3.0 and 1.3.1)
1.3.1Joining another server no longer opens an empty player, a cleaner mini player and a softer Minimal progress line.3 changes
Changed- A cleaner mini player: just the picture, play and a plain progress bar
- Minimal controls: the progress line shown while the controls hide is softer and easier on the eyes
Fixed- Joining another server no longer opens an empty player




