watchparty/README.md
Nicolas 66af05f259 Scaffold Emby Watch Party plugin
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>
2026-09-13 14:02:43 +02:00

85 lines
3.4 KiB
Markdown

# 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. 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.
3. 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.
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 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](docs/architecture.md#assumptions-to-verify) 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](https://dotnet.microsoft.com/download) to build (not currently
installed in this environment — `dotnet --version` came 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
```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
- [ ] 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](LICENSE).