Emby Server plugin: watch party feature (session sync via Emby's remote-control commands) + companion web control panel
Find a file
Nicolas db815df7d5 Fix plugin to build clean against real Emby 4.9.1.90 SDK
Installed .NET 8 SDK (per-user, winget needed admin elevation this
machine doesn't have) and restored the real MediaBrowser.Server.Core /
MediaBrowser.Common packages, then fixed everything the compiler and
a bit of reflection surfaced:

- PlaybackProgressEventArgs/PlaybackStopEventArgs are in
  MediaBrowser.Controller.Library, not ...Session
- IAuthorizationContext/AuthorizationInfo are in MediaBrowser.Controller.Net
- Item/user/session ids (SessionInfo.Id/UserId, BaseItemDto.Id) are plain
  string on this SDK version, not Guid - Party/PartyMember updated
  accordingly (Party.Id stays a Guid; it's minted by this plugin, not Emby)
- Reading the calling user needed an extra step:
  IAuthorizationContext.GetAuthorizationInfo(Request).UserId is a `long`
  (internal row id); .User.Id is the one matching SessionInfo.UserId,
  but it's a Guid so it's reformatted with .ToString("N")

docs/architecture.md's "Assumptions to verify" now reflects what was
actually confirmed vs. what's still only compile-checked (HTTP status
codes, content-type headers, the JS auth header format, the dashboard
config page) pending a run against a real server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 14:40:17 +02:00
.github/workflows Scaffold Emby Watch Party plugin 2026-09-13 14:02:43 +02:00
docs Fix plugin to build clean against real Emby 4.9.1.90 SDK 2026-09-13 14:40:17 +02:00
src/WatchParty Fix plugin to build clean against real Emby 4.9.1.90 SDK 2026-09-13 14:40:17 +02:00
web/control-panel Scaffold Emby Watch Party plugin 2026-09-13 14:02:43 +02:00
.gitignore Scaffold Emby Watch Party plugin 2026-09-13 14:02:43 +02:00
LICENSE Scaffold Emby Watch Party plugin 2026-09-13 14:02:43 +02:00
README.md Fix plugin to build clean against real Emby 4.9.1.90 SDK 2026-09-13 14:40:17 +02:00

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

  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.

The control panel is a companion page, not a video player — it never touches the actual video stream.

Status

Builds clean (0 errors, 0 warnings) against the real MediaBrowser.Server.Core / MediaBrowser.Common 4.9.1.90 assemblies from NuGet. Not yet installed or run against an actual Emby Server — a few things (auth header format, HTTP status codes, the dashboard settings page rendering) are only compile-checked so far, not runtime-verified. See docs/architecture.md 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 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 + 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.