Skip to content

Add Yandex Music Connect (Ynison) plugin provider#3614

Open
trudenboy wants to merge 26 commits intomusic-assistant:devfrom
trudenboy:upstream/yandex_ynison
Open

Add Yandex Music Connect (Ynison) plugin provider#3614
trudenboy wants to merge 26 commits intomusic-assistant:devfrom
trudenboy:upstream/yandex_ynison

Conversation

@trudenboy
Copy link
Copy Markdown
Contributor

@trudenboy trudenboy commented Apr 8, 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

  • 218 unit tests pass (pytest)
  • ruff lint and format clean
  • mypy type check clean
  • 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
  • Manual testing of upgrade path: existing standalone-token configs preserve own-mode; fresh installs auto-select the sole yandex_music instance
  • 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

Dependencies

  • 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 · branch dev · v1.8.0

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

🔒 Dependency Security Report

📦 Modified Dependencies

music_assistant/providers/yandex_ynison/manifest.json

Added:


🔍 Vulnerability Scan Results

No known vulnerabilities found

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.

@trudenboy trudenboy changed the title feat(yandex_ynison): add yandex_ynison provider v1.0.0 feat: add Yandex Music Connect (Ynison) plugin provider Apr 8, 2026
@trudenboy trudenboy changed the title feat: add Yandex Music Connect (Ynison) plugin provider Add Yandex Music Connect (Ynison) plugin provider Apr 8, 2026
@trudenboy trudenboy marked this pull request as ready for review April 8, 2026 16:48
Copilot AI review requested due to automatic review settings April 8, 2026 16:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Comment thread music_assistant/providers/yandex_ynison/ynison_client.py
Comment thread music_assistant/providers/yandex_ynison/provider.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Comment thread music_assistant/providers/yandex_ynison/provider.py
Comment thread music_assistant/providers/yandex_ynison/ynison_client.py
Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Comment thread music_assistant/providers/yandex_ynison/provider.py
Copilot AI review requested due to automatic review settings April 9, 2026 12:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Comment thread music_assistant/providers/yandex_ynison/provider.py
Comment thread music_assistant/providers/yandex_ynison/provider.py
Copilot AI review requested due to automatic review settings April 9, 2026 14:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Comment thread music_assistant/providers/yandex_ynison/provider.py Outdated
Comment thread music_assistant/providers/yandex_ynison/provider.py
Copilot AI review requested due to automatic review settings April 9, 2026 14:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Comment thread music_assistant/providers/yandex_ynison/provider.py
Comment thread music_assistant/providers/yandex_ynison/provider.py Outdated
Copilot AI review requested due to automatic review settings April 9, 2026 15:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.

Comment thread music_assistant/providers/yandex_ynison/provider.py
Copilot AI review requested due to automatic review settings April 9, 2026 15:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Comment thread music_assistant/providers/yandex_ynison/provider.py Outdated
Comment thread music_assistant/providers/yandex_ynison/provider.py Outdated
Copilot AI review requested due to automatic review settings April 9, 2026 16:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.

Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Comment thread music_assistant/providers/yandex_ynison/provider.py Outdated
Comment thread music_assistant/providers/yandex_ynison/provider.py Outdated
Copilot AI review requested due to automatic review settings April 9, 2026 19:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

@MarvinSchenkel MarvinSchenkel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refactor this PR to use the central auth like we discussed in your other PR. Will have an in depth look after that.

@trudenboy
Copy link
Copy Markdown
Contributor Author

Hi @MarvinSchenkel — thanks for the pointer. The refactor landed as v1.6.0 of the plugin (trudenboy/ma-provider-yandex-ynison#34) and was synced to this PR branch after your review. Short summary of what changed:

  • No more duplicated auth flow. QR login, x_token validation, and auto-refresh are gone from yandex_ynison. auth.py is now a 22-line wrapper over ya-passport-auth (refresh_music_token only).
  • Credentials are borrowed from the linked yandex_music provider via a new CONF_YM_INSTANCE source selector. Ynison reads token/x_token from the selected YM provider's config at runtime and reactively refreshes in-memory on 401 — it doesn't persist or manage any of its own.
  • Own-token mode remains as a minimal escape hatch: a single manual token field, no refresh.
  • ya-passport-auth bumped to 1.3.0.

PR title and body have been refreshed to match the current state. Ready for re-review when you get a chance.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.

Comment thread requirements_all.txt
Comment thread tests/providers/yandex_ynison/test_config_entries.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 1 comment.

Comment thread music_assistant/providers/yandex_ynison/provider.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.

Comment thread music_assistant/providers/yandex_ynison/constants.py Outdated
Comment thread music_assistant/providers/yandex_ynison/constants.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.

Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Comment thread music_assistant/providers/yandex_ynison/ynison_client.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Comment thread music_assistant/providers/yandex_ynison/provider.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.

Comment thread music_assistant/providers/yandex_ynison/provider.py Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants