Design: coordinate parties on top of Emby's existing session remote-control commands (SendPlaystateCommand) rather than building a new player. Each member keeps their own Emby app/controls; the server periodically corrects drift and mirrors pause/unpause against one reference member's reported position. - src/WatchParty: plugin skeleton (BasePlugin, IServerEntryPoint, IService/[Route] API, in-memory party store, drift-correction loop) - web/control-panel: plain HTML/JS/CSS companion page to create/join parties and resync, served by the plugin itself - docs/architecture.md: full design, sources consulted, and an explicit list of SDK details that still need verifying against a real build (no .NET SDK / Emby SDK assemblies available in this environment to compile against) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| .github/workflows | ||
| docs | ||
| src/WatchParty | ||
| web/control-panel | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
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 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
- You start playing a title in your normal Emby app.
- You open the Watch Party control panel (a small web page the plugin serves) and start a party. You get a 6-character join code.
- Friends open the control panel, sign in with their own Emby account, start playing the same title in their own Emby app, and enter the code to join.
- 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.
The control panel is a companion page, not a video player — it never touches the actual video stream.
Status
Early scaffold, not yet built or run against a real server. It's structured
around Emby's documented plugin patterns (BasePlugin<T>, IServerEntryPoint,
the IService/[Route] API style) and the confirmed
ISessionManager.SendPlaystateCommand remote-control API, but several SDK
details are marked TODO(verify) in the code — see
docs/architecture.md before
expecting it to compile as-is.
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 to build (not currently
installed in this environment —
dotnet --versioncame back empty)
Project layout
src/WatchParty/ the plugin itself (C#, netstandard2.0)
Plugin.cs plugin registration + admin settings page
Configuration/ plugin settings + the dashboard config page HTML
Parties/ Party / PartyMember model + in-memory PartyManager
Sync/ the drift-correction background loop
Api/ REST endpoints + serving the control panel's static files
web/control-panel/ the user-facing page (plain HTML/JS/CSS, no build step)
docs/architecture.md full design doc
Building
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.:
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
- Design doc + scaffold
- Build against the real SDK, fix whatever the
TODO(verify)spots got wrong - Try it against a real Emby Server + two clients
- Live (WebSocket) updates in the control panel instead of polling
- Optional text chat, reusing the same realtime channel
- Per-party override of sync settings instead of only server-wide defaults
License
MIT — see LICENSE.