chore: release v0.2.0
Release / release (push) Successful in 2s

Production-readiness pass: security hardening, performance improvements,
new services (send_message, set_repeat, refresh_library), diagnostics,
reauth flow, image proxy, per-instance device IDs, exponential WS
reconnect backoff, ID validation, stale device cleanup, and supporting
integration plumbing. Three rounds of independent code review applied.

See RELEASE_NOTES.md for the full changelog.
This commit is contained in:
2026-05-26 13:16:36 +03:00
parent 56c1125ef2
commit 6ae0ed1787
18 changed files with 2170 additions and 645 deletions
+197 -73
View File
@@ -1,96 +1,190 @@
# Emby Media Player
[![hacs_badge](https://img.shields.io/badge/HACS-Custom-orange.svg)](https://github.com/hacs/integration)
[![version](https://img.shields.io/badge/version-0.2.0-blue.svg)](RELEASE_NOTES.md)
[![Home Assistant](https://img.shields.io/badge/Home%20Assistant-2024.10%2B-blue.svg)](https://www.home-assistant.io/)
A Home Assistant custom integration that exposes Emby media server clients as media players with full playback control, media metadata, and library browsing capabilities.
A Home Assistant custom integration that exposes Emby Server clients as media players with full playback control, real-time WebSocket updates, library browsing, repeat-mode control, and on-screen messaging.
## Features
- **Media Player Control**: Play, pause, stop, seek, volume control, mute, next/previous track
- **Real-time Updates**: WebSocket connection for instant state synchronization with polling fallback
- **Media Metadata**: Display currently playing media information including:
- Title, artist, album (for music)
- Series name, season, episode (for TV shows)
- Thumbnail/artwork
- Duration and playback position
- **Media Browser**: Browse your Emby library directly from Home Assistant
- Navigate through Movies, TV Shows, Music libraries
- Play any media directly from the browser
- **Dynamic Session Discovery**: Automatically discovers and creates media player entities for active Emby clients
### Playback & metadata
- **Full media-player control**: play, pause, stop, seek, volume, mute, next/previous track, repeat mode.
- **Real-time updates over WebSocket** with a slow REST poll as a safety net — `PlaybackStart`, `PlaybackProgress`, and `PlaybackStopped` events update the entity in place.
- **Now-playing metadata**: title, artist, album, series / season / episode, artwork, duration, position, play method (DirectPlay / DirectStream / Transcode).
- **Per-client device class** inferred from the Emby client (AndroidTV / Kodi / Roku → TV, music clients → speaker, others → generic).
- **Enqueue semantics** mapped to Emby commands: HA's `play` / `replace``PlayNow`, `next``PlayNext`, `add``PlayLast`.
### Library
- **Browse the Emby library** from Home Assistant's media browser — Movies, TV Shows, Music, Playlists, user views.
- **Server-side image proxy** — artwork is fetched with the API key in an HTTP header and never leaks into URLs in the browser.
### Security & reliability
- **API key never appears in URLs** (no query-string leakage to proxy logs or browser history).
- **Per-instance device IDs** derived from the Home Assistant UUID — multiple HA installs no longer collide on the same Emby server.
- **Self-signed HTTPS** support via a `verify_ssl` toggle.
- **Reauth flow** prompts for a fresh API key when the server rejects the current one.
- **Exponential backoff with jitter** for WebSocket reconnects; auth failures stop the retry loop.
- **ID validation** on all session / item / user identifiers (defense in depth against path traversal in REST paths).
- **Stale device cleanup** removes media-player devices for sessions that disappear for over 30 minutes (with a 10-minute grace period after startup).
### Integration plumbing
- **Diagnostics** — Settings → Integrations → "..." → Download diagnostics for a redacted JSON dump (API key and session IDs are hashed/redacted).
- **Hub device** linked to per-session devices via `via_device` — easier to clean up.
- **Zeroconf + SSDP discovery hints** so Emby servers can be found by HA.
- **Three services**: `send_message`, `set_repeat`, `refresh_library`.
## Installation
### HACS (Recommended)
1. Open HACS in Home Assistant
2. Click on "Integrations"
3. Click the three dots menu and select "Custom repositories"
4. Add this repository URL and select "Integration" as the category
5. Click "Install"
6. Restart Home Assistant
1. Open HACS in Home Assistant.
2. Click on **Integrations**.
3. Click the three-dots menu and select **Custom repositories**.
4. Add this repository URL and select **Integration** as the category.
5. Click **Install**.
6. Restart Home Assistant.
### Manual Installation
1. Download the `custom_components/emby_player` folder
2. Copy it to your Home Assistant `custom_components` directory
3. Restart Home Assistant
1. Download the `custom_components/emby_player` folder.
2. Copy it to your Home Assistant `custom_components` directory.
3. Restart Home Assistant.
## Configuration
1. Go to **Settings** > **Devices & Services**
2. Click **Add Integration**
3. Search for "Emby Media Player"
4. Enter your Emby server details:
- **Host**: Your Emby server hostname or IP address
- **Port**: Emby server port (default: 8096)
- **API Key**: Your Emby API key (found in Dashboard > Extended > API Keys)
- **Use SSL**: Enable if your server uses HTTPS
5. Select the Emby user account to use
6. Click **Submit**
1. Go to **SettingsDevices & Services**.
2. Click **Add Integration** and search for **Emby Media Player**.
3. Enter your Emby server details:
- **Host** — Emby server hostname or IP address.
- **Port** — default `8096` (HTTP) or `8920` (HTTPS).
- **API Key** — created in Emby Dashboard → Extended → API Keys.
- **Use SSL** — enable if your server uses HTTPS.
- **Verify SSL certificate** — disable only when using a self-signed certificate that HA's CA bundle doesn't trust.
4. Select the Emby user account to use for browsing & playback.
5. Click **Submit**.
### Getting an API Key
### Getting an API key
1. Open your Emby Server Dashboard
2. Navigate to **Extended** > **API Keys**
3. Click **New API Key** (+ button)
4. Give it a name (e.g., "Home Assistant")
5. Copy the generated key
1. Open your Emby Server Dashboard.
2. Navigate to **ExtendedAPI Keys**.
3. Click **New API Key** (+ button).
4. Give it a name (e.g., `Home Assistant`).
5. Copy the generated key.
> Admin keys list all users automatically. Non-admin keys fall back to the
> public users endpoint — the integration handles both.
### Reauthentication
If you regenerate the API key on the Emby server, Home Assistant will flag
the integration as needing attention and walk you through entering the new
key — no need to remove and re-add the integration.
## Options
After configuration, you can adjust the following options:
After configuration, open **Configure** on the integration to adjust:
- **Scan Interval**: Polling interval in seconds (5-60, default: 10). Used as a fallback when WebSocket connection is unavailable.
- **Scan Interval** (560 s, default `10`). Used as the polling cadence while
the WebSocket is unavailable. When the WebSocket is connected, the
integration drops to a 5-minute REST safety-net poll automatically.
## Supported Features
| Feature | Support |
|---------|---------|
| Play/Pause | Yes |
| Stop | Yes |
| Volume Control | Yes |
| Volume Mute | Yes |
| Seek | Yes |
| Next Track | Yes |
| Previous Track | Yes |
| Media Browser | Yes |
| Play Media | Yes |
| Feature | Support |
| ------------------- | ------- |
| Play / Pause | Yes |
| Stop | Yes |
| Volume Control | Yes |
| Volume Mute | Yes |
| Seek | Yes |
| Next Track | Yes |
| Previous Track | Yes |
| Repeat Mode | Yes |
| Media Browser | Yes |
| Play Media | Yes |
| Enqueue / Play Next | Yes |
## Entity Attributes
Each media player entity exposes the following attributes:
- `session_id`: Emby session identifier
- `device_id`: Device identifier
- `device_name`: Name of the playback device
- `client_name`: Emby client application name
- `user_name`: Emby user name
- `item_id`: Currently playing item ID
- `item_type`: Type of media (Movie, Episode, Audio, etc.)
| Attribute | Description |
| -------------- | -------------------------------------------------------------------------- |
| `session_id` | Emby session identifier |
| `device_id` | Device identifier |
| `device_name` | Name of the playback device |
| `client_name` | Emby client application name |
| `user_name` | Emby user currently signed in on the client (when available) |
| `item_id` | Currently playing item ID (only while playing) |
| `item_type` | Type of media (`Movie`, `Episode`, `Audio`, …) |
| `play_method` | `DirectPlay`, `DirectStream`, or `Transcode` (only while playing) |
## Services
### `emby_player.send_message`
Display a banner notification on an Emby client. Great for doorbells, alarms,
laundry timers, etc.
| Field | Required | Description |
| ------------ | -------- | -------------------------------------------- |
| `entity_id` | Yes | One or more Emby media-player entities. |
| `message` | Yes | Text to display. |
| `header` | No | Optional header / title. |
| `timeout_ms` | No | How long to show the message (10060000 ms). |
```yaml
service: emby_player.send_message
target:
entity_id: media_player.emby_living_room_tv
data:
header: "Doorbell"
message: "Someone's at the front door"
timeout_ms: 5000
```
### `emby_player.set_repeat`
Set the repeat mode on the current playback.
| Field | Required | Description |
| ------------- | -------- | -------------------------------------------------------- |
| `entity_id` | Yes | One or more Emby media-player entities. |
| `repeat_mode` | Yes | One of `RepeatNone`, `RepeatOne`, or `RepeatAll`. |
```yaml
service: emby_player.set_repeat
target:
entity_id: media_player.emby_living_room_tv
data:
repeat_mode: RepeatAll
```
> The standard HA media-player repeat control is also wired up — `media_player.repeat_set` will work without using this service.
### `emby_player.refresh_library`
Trigger a server-side library scan. If `entity_id` is omitted, all configured
Emby servers are refreshed.
```yaml
service: emby_player.refresh_library
```
## Diagnostics
Open **Settings → Integrations → Emby Media Player → "..." → Download diagnostics** to get a redacted JSON dump containing the entry, the current sessions, server id, and WebSocket connection status. Useful when filing bug reports.
The dump redacts the API key and replaces real session / device / user IDs with stable hashes so it's safe to share.
## Automation Examples
### Dim lights when playing a movie
### Dim lights when a movie starts
```yaml
automation:
@@ -110,7 +204,7 @@ automation:
brightness_pct: 20
```
### Pause playback when doorbell rings
### Pause playback when the doorbell rings, then notify the screen
```yaml
automation:
@@ -123,32 +217,62 @@ automation:
- service: media_player.media_pause
target:
entity_id: media_player.emby_living_room_tv
- service: emby_player.send_message
target:
entity_id: media_player.emby_living_room_tv
data:
header: "Doorbell"
message: "Someone is at the door"
timeout_ms: 8000
```
### Toggle shuffle/repeat from a script
```yaml
script:
emby_repeat_all:
sequence:
- service: media_player.repeat_set
target:
entity_id: media_player.emby_living_room_tv
data:
repeat: all
```
## Troubleshooting
### Connection Issues
### Connection issues
- Verify the Emby server is accessible from Home Assistant
- Check that the API key is valid and has appropriate permissions
- Ensure the port is correct (default is 8096)
- Verify the Emby server is reachable from the Home Assistant host (try `ping` / `curl http://<host>:8096/emby/System/Info` from a terminal on the HA box).
- Check that the API key is valid and not revoked in Emby Dashboard → Extended → API Keys.
- For HTTPS with a self-signed certificate, toggle **Verify SSL certificate** off in the integration config.
- If reauth keeps failing, regenerate the API key on the server and try again.
### No Media Players Appearing
### No media players appearing
- Media player entities are only created for **active sessions** that support remote control
- Start playback on an Emby client and wait for the entity to appear
- Check the Home Assistant logs for any error messages
- Media-player entities are only created for **active sessions that support remote control**. Start playback on an Emby client first.
- Browser-based Emby Web sessions usually do not support remote control and won't appear as entities.
- Check **Settings → System → Logs** in Home Assistant for messages from `custom_components.emby_player`.
### WebSocket Connection Failed
### WebSocket connection failed
If WebSocket connection fails, the integration will fall back to polling. Check:
- Firewall rules allow WebSocket connections
- Reverse proxy is configured to support WebSocket
- Server logs in Home Assistant for specific errors
If the WebSocket can't connect, the integration falls back to REST polling at the configured **Scan Interval**. To restore real-time updates:
- Allow WebSocket traffic to TCP `8096` / `8920` from the HA host.
- If you run Emby behind a reverse proxy, make sure `Upgrade` / `Connection` headers are forwarded for `/embywebsocket`.
- For HTTPS proxies (Caddy / Traefik / nginx), confirm the WebSocket path is included in the proxy config.
### Stale devices in the registry
Devices for sessions that haven't been seen for 30 minutes are removed automatically (after a 10-minute startup grace). You can also manually delete a device from **Settings → Devices & Services → Emby Media Player → Device → Delete**.
## Versioning
See [RELEASE_NOTES.md](RELEASE_NOTES.md) for the full changelog.
## Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Contributions are welcome. Please open an issue or submit a pull request.
## License