Add Yandex Music Connect (Ynison) plugin provider#3614
Merged
MarvinSchenkel merged 30 commits intomusic-assistant:devfrom Apr 28, 2026
Merged
Add Yandex Music Connect (Ynison) plugin provider#3614MarvinSchenkel merged 30 commits intomusic-assistant:devfrom
MarvinSchenkel merged 30 commits intomusic-assistant:devfrom
Conversation
Contributor
🔒 Dependency Security Report📦 Modified Dependencies
|
| Name | Skip Reason |
|---|---|
| torch | Dependency not found on PyPI and could not be audited: torch (2.11.0+cpu) |
| torchaudio | Dependency not found on PyPI and could not be audited: torchaudio (2.11.0+cpu) |
| ✅ No known vulnerabilities found |
Automated Security Checks
- ✅ Vulnerability Scan: Passed - No known vulnerabilities
- ✅ Trusted Sources: All packages have verified source repositories
- ✅ Typosquatting Check: No suspicious package names detected
- ✅ License Compatibility: All licenses are OSI-approved and compatible
- ✅ Supply Chain Risk: Passed - packages appear mature and maintained
Manual Review
Maintainer approval required:
- I have reviewed the changes above and approve these dependency updates
To approve: Comment /approve-dependencies or manually add the dependencies-reviewed label.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new yandex_ynison plugin provider that exposes Music Assistant players as Yandex Music Connect (Ynison) devices, including QR-based authentication, a WebSocket client for Ynison state sync, and PCM streaming via the existing yandex_music provider.
Changes:
- Introduce the Ynison WebSocket client (redirector → state service) with reconnect and state parsing/sending helpers.
- Add the plugin provider that maps Ynison state/control to Music Assistant player/source selection and streaming via ffmpeg conversion.
- Add QR authentication helpers and a unit test suite for client/provider behavior.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
music_assistant/providers/yandex_ynison/__init__.py |
Provider setup and config flow (QR auth actions, player selection options). |
music_assistant/providers/yandex_ynison/constants.py |
Centralized protocol/config constants for Ynison. |
music_assistant/providers/yandex_ynison/manifest.json |
Declares the plugin provider metadata and docs link. |
music_assistant/providers/yandex_ynison/icon.svg |
Provider icon asset. |
music_assistant/providers/yandex_ynison/yandex_auth.py |
Yandex Passport QR auth + token exchange helpers. |
music_assistant/providers/yandex_ynison/ynison_client.py |
Core Ynison WebSocket client implementation (connect, message loop, reconnect, send/state parsing). |
music_assistant/providers/yandex_ynison/provider.py |
PluginProvider implementation bridging Ynison state to MA playback/source and streaming. |
tests/providers/yandex_ynison/__init__.py |
Test package marker. |
tests/providers/yandex_ynison/test_ynison_client.py |
Unit tests for protocol header/state parsing/sending/disconnect/device-id generation. |
tests/providers/yandex_ynison/test_provider.py |
Unit tests for provider init, player selection, source selection behavior, provider matching, and Ynison state handling. |
Merged
3 tasks
MarvinSchenkel
approved these changes
Apr 28, 2026
Contributor
MarvinSchenkel
left a comment
There was a problem hiding this comment.
Thanks @trudenboy
Open
3 tasks
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
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_musicMusicProvider), and streams PCM to the selected MA player.Architecture
Authentication model
The plugin supports two top-level auth modes, picked via the Yandex Music source dropdown. Together they give three reachable populated states:
yandex_musicMusicProvider is configured) — read OAuth credentials live from a linkedyandex_musicinstance viaProviderConfig.get_value(). No secrets stored in the Ynison config; reactive refresh fromx_tokenon 401 is in-memory only (scheduled refresh stays withyandex_music).Login with QR codeaction opens a Passport QR popup (viaAuthenticationHelper); on scan-confirm both the music token and the long-livedx_tokenare stored in this plugin's config. Each instance can be bound to its own Yandex account without sharing tokens with ayandex_musicprovider — useful withmulti_instance: truefor one-account-per-player setups. ARemember sessiontoggle controlsx_tokenpersistence; with it enabled the plugin reactively refreshes on 401 in own mode, mirroring borrow behaviour.CONF_TOKEN. With no storedx_token, expiry surfaces a clearLoginFailedso the user knows to paste a new token.Upgrades from earlier standalone versions preserve own-mode if
CONF_TOKENwas set, so no silent switch of auth source.Key features
yandex_musicMusicProvider with FFmpeg PCM conversion (-rerealtime pacing) and byte-accurate progress syncversion.device_id-based — inspects the author of incomingplayer_queueandstatusversion blocks to suppress feedback loops from our own round-tripped updates (covers both queue and status-only echoes)version/timestamp_ms/progress_ms/duration_msfields are string-typed (integers trigger HTTP 500 + WS teardown); inbound state is normalized at ingestion so reconnect replays and queue edits stay safe by constructionRemember sessionon the plugin refreshes the music token from a storedx_tokenon 401 — no manual re-paste, no sharedyandex_musicinstance requiredSyncStateFromEOVfor queue replenishment, bounds-validated queue advancementin_use_bylifecycle — released on pause, re-acquired on resume vianeeds_reselectflagStreamMetadataChanged files
providers/yandex_ynison/__init__.pyym_instancedropdown, own-mode QR/clear actions, upgrade-path preservationproviders/yandex_ynison/provider.pyproviders/yandex_ynison/ynison_client.pyproviders/yandex_ynison/auth.pyya-passport-authwrapper:perform_qr_auth(QR popup → tokens) andrefresh_music_token(x_token → fresh music token)providers/yandex_ynison/streaming.pyproviders/yandex_ynison/constants.pyx_token/account_login/QR action keys),yandex_musicconfig-key constants, defaultsproviders/yandex_ynison/protocols.pyproviders/yandex_ynison/config_helpers.pylist_yandex_music_instances()— enumerates linked YM providers for the dropdownproviders/yandex_ynison/manifest.jsonya-passport-auth==1.3.0,depends_on: yandex_music)providers/yandex_ynison/icon.svgrequirements_all.txtya-passport-auth==1.3.0tests/.../test_provider.pytests/.../test_ynison_client.pytests/.../test_config_entries.pytests/.../test_auth.pytests/.../test_streaming.pyTest plan
pytest)yandex_musicinstancex_token,Logged in as <login>status is shown; second instance can be bound to a different Yandex account; reset-auth clears all three fieldsRelated PRs
Dependencies
ya-passport-auth==1.3.0— async Yandex Passport client. Used forrefresh_music_token(x_token)(borrow + own modes) and the QR login flow (PassportClient.start_qr_login+poll_qr_until_confirmed).yandex_musicMusicProvider (depends_onin 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 clearLoginFailedif the linked instance was removed.