A small standalone Windows tray agent that hides the Emby client to the system tray when playback pauses or stops on this machine, and restores it when playback resumes or starts. It lives entirely outside the Emby client install, so client updates never touch it.
It is a lightweight, API-driven replacement for external helpers: no DLNA renderer, no mpv, just the Emby REST API and Win32 window control.
- Real system-tray icon with a status dot (green when the Emby window is on screen, gray when hidden to tray).
- Pause on the playback screen hides Emby to the tray; resume shows and focuses it.
- Playback start shows Emby; stop/end hides it. Every behavior is an independent toggle.
- "Start minimized" tucks the client into the tray each time it launches.
- Manual control: left-click the tray icon to toggle, or use
--show/--hide/--togglefrom a shortcut, hotkey, or Stream Deck. - Optional watchdog to keep the Emby client running (relaunch if it exits).
- LAN server discovery, connection test, and a session picker in Settings.
- Per-event command/file hooks (run something on start/resume/pause/stop).
- API key encrypted at rest with Windows DPAPI (scoped to your Windows user).
- Custom fade notifications instead of Windows toasts (no focus stealing).
- Config and log sit next to the exe, so everything travels with it.
- Windows 10 or 11 (x64)
- .NET 8 SDK (https://dotnet.microsoft.com/download/dotnet/8.0) - only needed to build
From the project folder in a terminal:
dotnet publish -c Release
The output is a single self-contained exe (no .NET runtime needed on the target):
bin\Release\net8.0-windows\win-x64\publish\EmbyTray.exe
Copy that one EmbyTray.exe anywhere you like. For a quick dev run without publishing, use dotnet run.
See BUILD.md for full build, setup, autostart, and troubleshooting details.
- Start
EmbyTray.exe. A green Emby tray icon appears. - Get an API key: Emby Dashboard > Advanced > API Keys > New API Key.
- Right-click the tray icon > Settings. Enter your Emby server URL and the API key ("Find servers" and "Test connection" help here). Leave the device name blank to use this PC's hostname; if several Emby clients exist on the network, use "Detect my session" or set the device name to disambiguate.
- Save. The tray menu status line should change to "Connected to ...".
Settings are stored in config.json next to the exe (falling back to %AppData%\EmbyTray if that folder is read-only). The API key is encrypted with DPAPI and is not portable across users or machines - just re-enter it if you move the config.
Settings are managed through the Settings dialog; config.json is written automatically. A sanitized config.example.json is included for reference. config.json itself is gitignored because it holds your server URL, encrypted API key, and device name.
Playback state is read by polling the Emby REST endpoint GET /Sessions (which reports PlayState.IsPaused and the now-playing item). Emby has no WebSocket "Sessions" push - that is a Jellyfin feature - so REST polling is the documented, supported approach. The agent filters to this machine's session (by local network address, then client name, then device name), then controls the Emby window with Win32 (enumerate windows, hide to tray / restore / foreground), with a WinEvent hook for instant re-hiding during the client's slow boot.
GNU General Public License v3.0. See LICENSE.