# Watch Party for Emby An Emby Server plugin that lets a group of users on the same server watch the same title together. Nobody switches players: everyone keeps using their normal Emby app (web, mobile, TV, whatever), and the plugin nudges playback back in sync using the same remote-control commands Emby already uses for casting / "play on another device". See [docs/architecture.md](docs/architecture.md) for the full design, including which parts are solidly confirmed against Emby's SDK docs and which still need verification against your exact server build. ## How it's meant to work 1. You start playing a title in your normal Emby app. 2. In Emby's web client (or the Electron desktop app), open **Watch Party** from the menu and start a party. You get a 6-character join code. No separate login — it's a real page inside Emby, using your existing session. 3. Friends open the same **Watch Party** menu item, start playing the *same* title in their own Emby app, and enter the code to join. 4. The server treats one member (the host, by default) as the reference position, and periodically nudges everyone else's session back in sync (seek correction, and mirroring pause/unpause) — see [docs/architecture.md](docs/architecture.md#sync-algorithm). The Watch Party page is a companion panel, not a video player — it never touches the actual video stream, playback stays in your normal Emby app. **Known limitation**: the menu item shows up on Web and Electron clients. Official mobile/TV apps don't surface arbitrary plugin pages, so Watch Party won't appear there — see [docs/architecture.md](docs/architecture.md#components). ## Status Builds clean (0 errors, 0 warnings) against the real `MediaBrowser.Server.Core` / `MediaBrowser.Common` 4.9.1.90 assemblies from NuGet, and is installed on a real Emby Server (Docker) — the plugin loads and its admin page shows up. The actual feature (`partyPage.html`, reached via `EnableInUserMenu`) hasn't been exercised live yet. See [docs/architecture.md](docs/architecture.md#assumptions-to-verify) for exactly what was wrong on the first guess, what was fixed, and what's still open. ## Requirements - Emby Server (developed against 4.9.5.0; should work on nearby 4.9.x/4.8.x builds, but the plugin ABI does shift between versions) - [.NET SDK](https://dotnet.microsoft.com/download) 8.0 to build (installed per-user under `%USERPROFILE%\.dotnet` in this environment, since the machine-wide winget install needed admin elevation that wasn't available — see git history if you need to redo this on another machine) ## Project layout ``` src/WatchParty/ the plugin itself (C#, netstandard2.0) Plugin.cs plugin registration + both plugin pages Configuration/ plugin settings, the admin settings page, and partyPage.html - the actual user-facing feature, integrated into Emby's own menu (not a separate app) Parties/ Party / PartyMember model + in-memory PartyManager Sync/ the drift-correction background loop Api/ REST endpoints, called from partyPage.html docs/architecture.md full design doc ``` ## Building ```bash dotnet build src/WatchParty/WatchParty.csproj ``` To have a build drop the DLL straight into a local Emby Server's plugin folder, set `EMBY_PLUGINS_DIR` before building, e.g.: ```bash EMBY_PLUGINS_DIR="C:/ProgramData/Emby-Server/programdata/plugins" dotnet build src/WatchParty/WatchParty.csproj ``` Adjust the path for however your server is installed (Windows service vs. portable install vs. Docker volume). ## Roadmap - [x] Design doc + scaffold - [x] Build against the real SDK, fix whatever the `TODO(verify)` spots got wrong - [x] Install on a real Emby Server (Docker) - [x] Integrate into Emby's own UI instead of a standalone web app (`EnableInUserMenu` — see [docs/architecture.md](docs/architecture.md#components)) - [ ] Try a full party end-to-end with two accounts - [ ] Live (WebSocket) updates in the party page instead of polling - [ ] Per-party override of sync settings instead of only server-wide defaults No chat/reactions — deliberately out of scope, not just deferred. ## License MIT — see [LICENSE](LICENSE).