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>
43 lines
1.8 KiB
HTML
43 lines
1.8 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Watch Party</title>
|
|
<link rel="stylesheet" href="app.css" />
|
|
</head>
|
|
<body>
|
|
<main class="wrap">
|
|
<h1>Watch Party</h1>
|
|
|
|
<section id="loginPanel" class="panel">
|
|
<h2>Sign in</h2>
|
|
<p class="hint">Uses your normal Emby account. Nothing leaves this browser except requests to your own server.</p>
|
|
<label>Server URL <input id="serverUrl" placeholder="http://192.168.1.10:8096" /></label>
|
|
<label>Username <input id="username" autocomplete="username" /></label>
|
|
<label>Password <input id="password" type="password" autocomplete="current-password" /></label>
|
|
<button id="loginBtn">Sign in</button>
|
|
<p id="loginError" class="error"></p>
|
|
</section>
|
|
|
|
<section id="lobbyPanel" class="panel hidden">
|
|
<h2>Start or join a party</h2>
|
|
<p class="hint">Start playing the title in your normal Emby app first, then come back here.</p>
|
|
<button id="createBtn">Start a party from what I'm watching</button>
|
|
<div class="or">or</div>
|
|
<label>Join code <input id="joinCode" maxlength="6" style="text-transform:uppercase" /></label>
|
|
<button id="joinBtn">Join</button>
|
|
<p id="lobbyError" class="error"></p>
|
|
</section>
|
|
|
|
<section id="partyPanel" class="panel hidden">
|
|
<h2>Party <span id="partyCode" class="code"></span></h2>
|
|
<p class="hint">Share the code above. Everyone keeps using their own Emby app - this page just keeps you in sync.</p>
|
|
<ul id="memberList" class="members"></ul>
|
|
<button id="resyncBtn">Resync me now</button>
|
|
<button id="leaveBtn" class="secondary">Leave party</button>
|
|
</section>
|
|
</main>
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html>
|