Files
haos-hacs-emby-media-player/README.md
T
alexei.dolgolyov 6ae0ed1787
Release / release (push) Successful in 2s
chore: release v0.2.0
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.
2026-05-26 13:16:36 +03:00

280 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 Server clients as media players with full playback control, real-time WebSocket updates, library browsing, repeat-mode control, and on-screen messaging.
## Features
### 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.
### Manual Installation
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** 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
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.
> 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, open **Configure** on the integration to adjust:
- **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 |
| Repeat Mode | Yes |
| Media Browser | Yes |
| Play Media | Yes |
| Enqueue / Play Next | Yes |
## Entity Attributes
Each media player entity exposes the following attributes:
| 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 a movie starts
```yaml
automation:
- alias: "Dim lights for movie"
trigger:
- platform: state
entity_id: media_player.emby_living_room_tv
to: "playing"
condition:
- condition: template
value_template: "{{ state_attr('media_player.emby_living_room_tv', 'item_type') == 'Movie' }}"
action:
- service: light.turn_on
target:
entity_id: light.living_room
data:
brightness_pct: 20
```
### Pause playback when the doorbell rings, then notify the screen
```yaml
automation:
- alias: "Pause Emby on doorbell"
trigger:
- platform: state
entity_id: binary_sensor.doorbell
to: "on"
action:
- 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
- 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
- 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
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.
## License
This project is licensed under the MIT License.