docs(plugins): add Yandex Music Connect (Ynison) plugin page#624
Open
trudenboy wants to merge 1 commit intomusic-assistant:betafrom
Open
docs(plugins): add Yandex Music Connect (Ynison) plugin page#624trudenboy wants to merge 1 commit intomusic-assistant:betafrom
trudenboy wants to merge 1 commit intomusic-assistant:betafrom
Conversation
Adds a documentation page for the Yandex Music Connect (Ynison) plugin, which exposes Music Assistant players as devices in the official Yandex Music app via the Ynison protocol (Yandex's equivalent of Spotify Connect). Page follows the style of the Yandex Music provider and Yandex Smart Home plugin pages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
✅ Deploy Preview for ohf-music-assistant ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
6 tasks
MarvinSchenkel
added a commit
to music-assistant/server
that referenced
this pull request
Apr 28, 2026
## Summary
Add new **Yandex Music Connect (Ynison)** plugin provider that makes
Music Assistant players appear as playback devices in the Yandex Music
app — similar to how Spotify Connect works.
When a user selects the MA device in the Yandex Music app, the plugin
receives track IDs via the Ynison WebSocket protocol, fetches audio from
Yandex Music CDN (via the linked `yandex_music` MusicProvider), and
streams PCM to the selected MA player.
## Architecture
```
Yandex Music app (phone/web/desktop)
-> Ynison WebSocket <-> YandexYnisonProvider
-> receives track_id from PlayerState
-> fetches audio via linked yandex_music MusicProvider
-> PCM audio -> PluginSource -> MA Player (Chromecast/DLNA/AirPlay/etc.)
<- play/pause/seek/next/prev -> update_playing_status back to Ynison
```
## Authentication model
The plugin supports two top-level auth modes, picked via the **Yandex
Music source** dropdown. Together they give three reachable populated
states:
- **Borrow mode** (default when a `yandex_music` MusicProvider is
configured) — read OAuth credentials live from a linked `yandex_music`
instance via `ProviderConfig.get_value()`. No secrets stored in the
Ynison config; reactive refresh from `x_token` on 401 is in-memory only
(scheduled refresh stays with `yandex_music`).
- **Own mode — QR login** — a per-instance `Login with QR code` action
opens a Passport QR popup (via `AuthenticationHelper`); on scan-confirm
both the music token and the long-lived `x_token` are stored in this
plugin's config. Each instance can be bound to its own Yandex account
without sharing tokens with a `yandex_music` provider — useful with
`multi_instance: true` for one-account-per-player setups. A `Remember
session` toggle controls `x_token` persistence; with it enabled the
plugin reactively refreshes on 401 in own mode, mirroring borrow
behaviour.
- **Own mode — manual paste** — escape hatch for headless setups: paste
a music token by hand into `CONF_TOKEN`. With no stored `x_token`,
expiry surfaces a clear `LoginFailed` so the user knows to paste a new
token.
Upgrades from earlier standalone versions preserve own-mode if
`CONF_TOKEN` was set, so no silent switch of auth source.
## Key features
- **Ynison WebSocket protocol**: two-step connection (redirector → state
service), device registration, bidirectional state sync
- **Reconnect resilience**: unbounded exponential backoff with ±20%
jitter (5s → 10s → 30s → 60s, saturating), session ownership tracking,
graceful disconnect handling
- **Audio streaming** via linked `yandex_music` MusicProvider with
FFmpeg PCM conversion (`-re` realtime pacing) and byte-accurate progress
sync
- **Playback control**: play / pause / next / prev / seek, synced
bidirectionally to Ynison state
- **Echo detection**: `version.device_id`-based — inspects the author of
incoming `player_queue` and `status` version blocks to suppress feedback
loops from our own round-tripped updates (covers both queue and
status-only echoes)
- **Ynison-safe wire format**: all outbound
`version`/`timestamp_ms`/`progress_ms`/`duration_ms` fields are
string-typed (integers trigger HTTP 500 + WS teardown); inbound state is
normalized at ingestion so reconnect replays and queue edits stay safe
by construction
- **Per-instance QR auth + reactive refresh** (own mode): own-mode
tokens come from a Passport QR scan or manual paste; with `Remember
session` on the plugin refreshes the music token from a stored `x_token`
on 401 — no manual re-paste, no shared `yandex_music` instance required
- **Radio queue management**: proactive prefetch of next radio batch at
~80% track progress, `SyncStateFromEOV` for queue replenishment,
bounds-validated queue advancement
- **Pause-resume handling**: polling-based pause wait (1s intervals, 30s
deadline) to correctly handle same-track resume without blocking on
track-change events
- **Plugin source ownership**: clean `in_use_by` lifecycle — released on
pause, re-acquired on resume via `needs_reselect` flag
- **Player selection**: auto (first available) or manual target player
- **Metadata sync**: title, cover art, duration, and elapsed time pushed
to MA frontend via `StreamMetadata`
## Changed files
| File | Lines | Description |
|------|-------|-------------|
| `providers/yandex_ynison/__init__.py` | 311 | Plugin setup, config
entries, `ym_instance` dropdown, own-mode QR/clear actions, upgrade-path
preservation |
| `providers/yandex_ynison/provider.py` | 1457 | Core plugin: state
machine, streaming, queue management, echo detection, borrow/own auth,
reactive 401 refresh |
| `providers/yandex_ynison/ynison_client.py` | 734 | Ynison WebSocket
client: two-step connect, state sync, unbounded reconnect with backoff,
timestamp normalization |
| `providers/yandex_ynison/auth.py` | 70 | `ya-passport-auth` wrapper:
`perform_qr_auth` (QR popup → tokens) and `refresh_music_token` (x_token
→ fresh music token) |
| `providers/yandex_ynison/streaming.py` | 47 | PCM format helpers,
pacing args |
| `providers/yandex_ynison/constants.py` | 72 | Protocol URLs, config
keys (incl. `x_token`/`account_login`/QR action keys), `yandex_music`
config-key constants, defaults |
| `providers/yandex_ynison/protocols.py` | 35 | Protocol types for
provider/client decoupling |
| `providers/yandex_ynison/config_helpers.py` | 20 |
`list_yandex_music_instances()` — enumerates linked YM providers for the
dropdown |
| `providers/yandex_ynison/manifest.json` | 12 | Plugin metadata
(`ya-passport-auth==1.3.0`, `depends_on: yandex_music`) |
| `providers/yandex_ynison/icon.svg` | 3 | Provider icon |
| `requirements_all.txt` | +1 | Added `ya-passport-auth==1.3.0` |
| `tests/.../test_provider.py` | 2176 | Provider unit tests (state
machine, streaming, queue, echo detection, borrow/own/QR auth, x_token
refresh) |
| `tests/.../test_ynison_client.py` | 1676 | WebSocket client tests
(connect, unbounded reconnect, state parsing, timestamp coercion) |
| `tests/.../test_config_entries.py` | 304 | Config-flow tests
(dropdown, upgrade preservation, stale-ID clamp, QR/clear action
dispatch and guards) |
| `tests/.../test_auth.py` | 162 | Auth wrapper tests (QR
success/timeout/error, token refresh, error propagation) |
| `tests/.../test_streaming.py` | 83 | Streaming helper tests (format
creation, pacing) |
## Test plan
- [x] 218 unit tests pass (`pytest`)
- [x] ruff lint and format clean
- [x] mypy type check clean
- [x] Manual testing on HAOS: device appears in Yandex Music app, audio
plays through MA player (DLNA), track changes, pause/resume, seek, and
radio queue advancement work correctly
- [x] Manual testing of upgrade path: existing standalone-token configs
preserve own-mode; fresh installs auto-select the sole `yandex_music`
instance
- [x] Manual testing of own-mode QR: QR popup renders, scan-confirm
populates token and `x_token`, `Logged in as <login>` status is shown;
second instance can be bound to a different Yandex account; reset-auth
clears all three fields
## Related PRs
- Documentation PR: music-assistant/music-assistant.io#624
## Dependencies
-
[`ya-passport-auth==1.3.0`](https://pypi.org/project/ya-passport-auth/1.3.0/)
— async Yandex Passport client. Used for `refresh_music_token(x_token)`
(borrow + own modes) and the QR login flow
(`PassportClient.start_qr_login` + `poll_qr_until_confirmed`).
- **Requires `yandex_music` MusicProvider** (`depends_on` in manifest) —
hard requirement for audio streaming. Borrow mode additionally reads its
OAuth credentials. Runtime detection via
`_check_yandex_provider_match()` handles the edge case where the
provider is unloaded while the plugin is running; borrow-mode token
reads surface a clear `LoginFailed` if the linked instance was removed.
> **Source**:
[trudenboy/ma-provider-yandex-ynison](https://github.com/trudenboy/ma-provider-yandex-ynison)
· branch
[`dev`](https://github.com/trudenboy/ma-provider-yandex-ynison/tree/dev)
· v1.8.0
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Marvin Schenkel <marvinschenkel@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new documentation page for the Yandex Music Connect (Ynison) plugin, which exposes Music Assistant players as devices in the official Yandex Music app via the Ynison protocol (Yandex's equivalent of Spotify Connect).
Changes
src/content/docs/plugins/yandex-ynison.mdastro.config.mjsunder PluginsThe page follows the style of the Yandex Music provider and Yandex Smart Home plugin pages (CAUTION / WARNING / NOTE callouts, features table, explicit settings list, known issues / notes) and documents:
Related PRs
Related links
Test plan
/plugins/yandex-ynison/