|
All checks were successful
Publier l'image Docker / publish (push) Successful in 28s
Mirrors the working mediaDrop pipeline (.forgejo/workflows/publish-docker.yml there) on the same instance: push to master -> latest + short-sha tags, push a vX.Y.Z tag -> X.Y.Z/X.Y/latest. REGISTRY_TOKEN secret already present on this repo. No test job yet - nothing to test. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| .github/workflows | ||
| client | ||
| docs | ||
| server | ||
| src/WatchParty | ||
| .gitignore | ||
| docker-compose.yml | ||
| LICENSE | ||
| README.md | ||
Watch Party for Emby
A standalone web app for watching the same title, in sync, with other users of the same Emby server. It reads your Emby catalog and streams your Emby media, but it's its own app with its own player — not an Emby plugin.
See docs/architecture.md for the full design, including why this replaced an earlier Emby-plugin attempt (still in src/WatchParty/ for reference — see below).
How it works
- Sign in with your Emby account.
- Search your Emby catalog for a title.
- Start a party (you become the host) or join one with a 6-character code.
- The host's play/pause/seek drives everyone else's player automatically, over a small backend that only ever coordinates timing — actual video always streams directly from your Emby server to each viewer's browser.
Status
Freshly scaffolded and smoke-tested (server starts, routes render, error handling works — see git history) with a stubbed Emby server. Not yet run against a real Emby server. The biggest open question is CORS: the browser calls Emby directly from a different origin, which needs Emby (or its reverse proxy) to answer that cross-origin requests are allowed — see docs/architecture.md.
Project layout
server/ Node.js backend: party/room coordination + WebSocket sync.
Never touches media bytes - only validates Emby tokens
(by asking Emby itself) and relays playback state.
src/index.js Express app + REST endpoints
src/wsHandler.js WebSocket protocol (see comments in the file)
src/partyManager.js in-memory room state
src/embyAuth.js token validation against your Emby server
client/ Static frontend (plain JS, ES modules, no build step).
Talks directly to Emby for catalog/images/streaming, and
to server/ only for party coordination.
js/embyApi.js Emby REST calls (auth, search, images, stream URLs)
js/party.js our own backend's REST + WebSocket client
js/views/ one file per screen (login, browse, item, player)
src/WatchParty/ The earlier Emby-plugin attempt. Builds fine and installs,
but Emby has no supported extension point for a player
button, and even menu integration required reverse-
engineering undocumented internals - see
docs/architecture.md for the full story. Kept for
reference; not the active direction.
docs/architecture.md full design doc for the standalone app
Running locally
cd server
npm install
EMBY_SERVER_URL=https://your-emby-server npm start
Then open http://localhost:3000.
Deploying
Build the Docker image from the repo root (it needs both server/ and
client/):
docker build -f server/Dockerfile -t watchparty .
docker run -d --name watchparty -p 3000:3000 -e EMBY_SERVER_URL=https://theater.media.kyuno.fr watchparty
Then put it behind your existing reverse proxy like everything else
(theater.media.kyuno.fr, git.dev.kyuno.fr, ...), e.g.
watchparty.kyuno.fr → http://<container>:3000.
Roadmap
- Design + scaffold the standalone app
- Smoke-test locally (routing, error handling) without a real Emby server
- Verify against the real Emby server (CORS is the main risk - see above)
- Try a full party end-to-end with two accounts
- TV show navigation (seasons/episodes) beyond flat search
- Tune transcoding target / support direct play when possible
No chat, no OIDC — deliberately out of scope (Emby-only auth was the explicit choice; see docs/architecture.md).
License
MIT — see LICENSE.