Skip to content

v0.3.0 — Self-hosted first, artwork-forward redesign

Choose a tag to compare

@SAKMZ SAKMZ released this 26 Jul 14:50

Note

Superseded on the cloud-hosting question. The finding below — that YouTube
refuses datacenter IPs and cookies don't lift it — still holds. The conclusion
drawn from it does not: the refusal isn't uniform, and
v0.5.0 makes cloud
hosting work by falling back through a pool of proxies. Home hosting is still
the simplest path.

Syncwave is now self-hosted first — it runs on a machine you own, and it looks the part.

🏠 Runs at home, by design

Cloud one-click deploys were removed. Testing on a cloud host with a valid logged-in cookies.txt, a working JS runtime, and all five yt-dlp player clients, every request was refused with "Sign in to confirm you're not a bot" — YouTube blocks datacenter IP ranges, and cookies don't lift it. The same build on a home connection works with no cookies at all. Shipping those buttons would have sent people to an app that can't play music.

Three ways to run it now:

  • 🖱️ Double-click a filestart.bat (Windows) or ./start.sh (macOS/Linux). Installs, builds, starts, opens your browser, and prints the LAN address to share. Rebuilds itself when you update.
  • 🐳 Dockerdocker compose up -d --build
  • 🐧 One commandcurl -fsSL .../scripts/install.sh | sudo bash

ffmpeg now ships with it, so a desktop user needs nothing but Node.

🎨 Redesigned around the artwork

  • Now Playing panel — large cover art with a colour halo, live equalizer, and who's listening. Its own tab on mobile, a dedicated column on wide screens.
  • Rebuilt player — identity left, transport centred, volume and reactions right. The old 4px hairline is a real scrubber with elapsed/remaining, keyboard support, and buffer fill while a track caches.
  • Fixed the ambient backdrop — a saturated album cover used to flood the whole app and wreck text contrast. It's now mood lighting under a two-layer scrim.
  • Volume control, per listener, remembered across visits. Position stays shared; loudness is yours.
  • Real empty states, queue numbering and run time, and prefers-reduced-motion support.

🔐 Setup and security

  • First-run wizard at /setup — set an admin password, optionally upload YouTube cookies, optionally enable the AI DJ.
  • /admin is now behind that password. It previously wasn't: anyone who could reach the instance could read your LLM configuration and change it. /api/settings is gated too.
  • Upload cookies.txt from the browser — validated on upload, stored 0600, applied to the very next track without a restart. Clear messages for the usual mistakes (JSON export, wrong site, exported while signed out).

🛠️ Fixes

  • yt-dlp failures say what went wrong. Its stderr was read for progress then discarded, so any failure produced an empty trace. Bot-checks, unavailable tracks, and everything else now report a real reason.
  • Deno is installed in the image — yt-dlp needs a JS runtime for YouTube's player challenge and was silently falling back to limited clients.
  • YTDLP_PROXY for anyone who must run on a datacenter IP.
  • Join with a room code from the home page. Guests told a code aloud previously had no way in.

Upgrading

git pull && docker compose up -d --build

Your rooms, settings, and cache are preserved. On first load you'll be sent to /setup to claim the instance with an admin password — do this before sharing the address.