← Проекты

Starsync

Поставьте любое видео, и все смотрят его синхронно: ретрансляция читает его один раз и раздаёт всей компании.

ВышлоLinuxWindowsFlutterDesktopmpvJellyfinAnime4K
Плеер Starsync на паузе со сценой из фильма и открытым рядом общим чатом
Сообщения чата пролетают поверх видео (данмаку) во время совместного просмотра
Библиотека сериалов Jellyfin в Starsync со списком серий выбранного сериала
Участники сеанса просмотра, все готовы, и быстрое сообщение в чат поверх видео
Настройки плеера Starsync, видео продолжает играть в мини-плеере

Видео на скриншотах: Sintel © Blender Foundation, durian.blender.org, CC BY 3.0.

Я сделал Starsync, потому что мне надоели Syncplay и стримы в Discord. Вот что в нём по-другому.

Почему не Syncplay и не Discord?

Syncplay — это два окна, у каждого должна быть своя копия файла, и каждое видео переключается вручную. Discord сделан для прямых трансляций: стоит одному потерять связь, и видео обрывается, а качество падает вместе с ним.

SyncplayDiscordStarsync
Всё в одном окне✕✓✓
Друзьям не нужна своя копия файла✕✓✓
Оригинальное качество у всех✓✕✓
Обрыв связи не прерывает видео~✕✓
Следующее видео без ручного переключения✕~✓
Мгновенная синхронизация и нормальная проверка готовности~✕✓

Ретрансляция: один поток на всех

Сердце Starsync. Один человек ставит видео, оно читается один раз, а хост раздаёт этот один поток всем. Никому не нужна копия файла, ничего не загружается заранее, и открытый порт нужен только хосту. Хостом может быть ПК любого из вас или маленький отдельный сервер на постоянно включённой машине. Выберите способ ниже, чтобы увидеть, куда идут байты и во что это обходится каждому соединению.

Ваше приложение читает видео с сайта один раз. Этот же поток играет у вас и уходит на хост, а хост раздаёт его всем. Если играет у вас — играет и у них, вместе с вашими куки.

1×1×1× каждомуСайт (yt-dlp)Вы↓1× ↑1×↺ у вас играет из этого же потокаХост↓1× ↑1× на другадержит несколько минут в памятиДрузья↓1×

Тот же путь, что и у ссылки: приложение отдаёт файл хосту, хост передаёт его дальше. Ничего не загружается заранее и ничего не перекодируется.

1×1× каждомуВаш дискВы↑1×↺ у вас файл играет напрямуюХост↓1× ↑1× на другадержит несколько минут в памятиДрузья↓1×

Если хост — вы, файл идёт всем прямо с вашего диска. Используется только исходящий канал хоста.

1×1× каждомуДиск хостаВы↓1×Хост↑1× на зрителяДрузья↓1×

Хост один раз скачивает ссылку в память и раздаёт всем, включая вас. Удобно, когда быстрый интернет у хоста.

1×1×1× каждомуСайт (yt-dlp)Вы↓1×Хост↓1× ↑1× на зрителядержит несколько минут в памятиДрузья↓1×

Каждое приложение загружает ссылку само. Хост вообще не передаёт видео, только время.

1×1× каждомуСайт (yt-dlp)Вы↓1×Хосттолько синхр.Друзья↓1×

У кого есть аккаунт, смотрят прямо из Jellyfin под своим входом. Друзья без аккаунта получают видео через вход хоста, и он никуда с хоста не уходит.

1×свой аккаунт1× на гостягостьJellyfinВы↓1×Хост↓↑ 1× на гостяДрузья↓1×

1× — битрейт самого видео; серия в 1080p обычно около 3–10 Мбит/с. Отдельно у каждого есть крошечное соединение синхронизации с хостом: только «позиция, играет».

Как это устроено

Что на самом деле происходит между нажатием «Играть» на ссылке и тем, как друзья её смотрят.

  1. 1

    Ваше приложение само подключается к хосту

    Соединение идёт от вашего ПК наружу, поэтому делиться можно за любым роутером, NAT или мобильным интернетом: на вашей стороне порты не нужны. Слушает только хост.

    WebSocketDart
  2. 2

    Видео читается один раз

    Один последовательный читатель берёт видео с сайта (через yt-dlp для страниц вроде YouTube) и держит 64 МиБ впереди. Эти же байты идут и в ваш плеер по локальному соединению, и на хост, так что ничего не скачивается дважды. YouTube читается кусками по 10 МиБ: так он отдаёт на полной скорости, а не урезает.

    yt-dlpHTTP ranges
  3. 3

    Хост держит его в памяти

    Хост хранит поток кусками по 256 КиБ: до 256 МиБ впереди самого быстрого зрителя и 64 МиБ позади самого медленного, плюс начало и конец файла, которые плеер читает при перемотке. Каждый байт уходит с вашего ПК примерно один раз, сколько бы друзей ни смотрело. На диск ничего не пишется.

    Dart serverin-memory buffer
  4. 4

    Друзья играют его как обычное видео из сети

    mpv каждого друга запрашивает у хоста диапазоны байтов по обычному HTTP, поэтому перемотка просто работает, а прыжок внутри буфера мгновенный. Отдельные видео и звук YouTube передаются двумя потоками и играют вместе; потоки HLS и DASH передаются по сегментам. В тестах перемотка 1080p YouTube через ретрансляцию занимала меньше 0,8 с — быстрее, чем mpv читает YouTube напрямую.

    mpvHTTP rangesHLS / DASH
  5. 5

    Готово к плохому интернету

    Отдача подстраивается под скорость и задержку вашего соединения. Если вы отвалились, друзья продолжают смотреть из буфера хоста, а ваше приложение само переподключается и продолжает с того же байта. Прямые трансляции и видео с DRM не ретранслируются.

    flow controlauto-reconnect
  6. 6

    Следующее видео уже прогрето

    «Далее» — одна общая очередь. Пока играет видео, хост уже начинает получать первый пункт от того, кто его добавил (или сам скачивает ссылку), и каждое приложение заранее грузит его первые секунды. Поэтому когда закончится 10-секундный отсчёт или кто-то пропустит видео, следующее начинается сразу.

    warm relaypreload

Обрыв связи не останавливает фильм

Пропадание интернета переживается, пока хватает буфера. Отвалится сервер или зритель — оба плавно восстанавливаются и не мешают просмотру, а синхронизация настолько точная, что часто кажется, будто на той стороне никого нет.

ВидеоСвязьсвязь пропалаиграет из буфера↻ снова синхронно

Аниме-неделя одним взглядом

Библиотека Jellyfin с отметками о просмотре для всего. Недельное расписание показывает, когда выходит каждая серия, что уже есть в Jellyfin и что вы посмотрели, и позволяет заказать новые тайтлы в автозагрузчик или Sonarr.

Недельное расписание аниме в Starsync: колонка на каждый день с постерами и временем выхода, серии из Jellyfin с отметкой о просмотре и обратный отсчёт до новых.

Возможности

  • Ретрансляция: что может воспроизвести один, смогут смотреть все
  • Пауза, перемотка и воспроизведение синхронны у всех
  • Общая очередь «Далее»: любой добавляет, переставляет или включает следующее, с отсчётом у всех
  • Видео по ссылке скачивается один раз для всех
  • Чат, быстрый чат и данмаку поверх видео
  • Приглашение одной ссылкой starsync://, без аккаунтов
  • Обновляется сам и показывает, что нового
  • Апскейл Anime4K встроен, плюс свои шейдеры .glsl; каждый зритель выбирает себе сам
  • Лёгкий отдельный сервер (starsync-server) для постоянно включённой машины: экран не нужен, юнит systemd в комплекте

Список изменений

Список изменений ведётся на английском.

  1. 1.4.0НоваяLinks 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 изменений
    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
  2. 1.3.2Fixes Windows closing by itself about 3 seconds after every start.1 изменение
    Fixed
    • Windows: the app no longer closes by itself about 3 seconds after starting (1.3.0 and 1.3.1)
  3. 1.3.1Joining another server no longer opens an empty player, a cleaner mini player and a softer Minimal progress line.3 изменения
    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
Все версии