Skip to content

Latest commit

 

History

88 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

YandexMusic

YandexMusic for .NET

🌐 English · Русский

CI NuGet License: MIT .NET

Unofficial asynchronous library for the Yandex Music API. Runs on .NET 8, .NET 9 and .NET 10.

⚠️ Unofficial project, not affiliated with Yandex. Use at your own risk and comply with the service's terms of use.

Features

  • ✅ Fully asynchronous API with CancellationToken support on every call
  • Full catalogue coverage — tracks (metadata, direct download/stream link, lyrics, full-info, similar, trailer), search (+ autocomplete), albums, artists, playlists, genres, labels, clips, credits, disclaimers, concerts, meta-tag pages
  • Personalised endpoints — account & settings, library likes/dislikes (read & write), playlist editing, radio (rotor) stations, landing & feed, cross-device queues, pins, pre-saves, listening history
  • Ynison real-time — subscribe to the account's playback state across all devices and remote-control it (pause, tracks, volume) over the same websocket protocol the official clients use
  • Smart speakers — find them on the local network over mDNS and drive them directly, with their TLS certificate pinned; a speaker never joins the account's session, so this is the only way to reach one
  • Multiple sign-in flows — OAuth token, the official OAuth device-code flow, and best-effort cookie, QR or login + password; all over a serializable session you can persist and restore
  • System.Text.Json source generation — allocation-conscious and trim/AOT-friendly (IsAotCompatible)
  • ✅ Typed exceptions, first-class dependency-injection integration, full XML documentation
  • ✅ Clean, extensible design: add an endpoint group and you have a new domain

Sample: terminal music player

samples/YandexMusicTerminal is a full interactive TUI built on the library — search, browse your albums and playlists, and a live "now playing" view with an animated equalizer, a real-time progress bar and keyboard volume/transport controls.

Install — one command, no .NET needed (the builds are self-contained). It installs into your user profile, needs no administrator rights, and puts ymt on your PATH:

irm https://raw.githubusercontent.com/jrfrigat/YandexMusic/main/scripts/install.ps1 | iex
curl -fsSL https://raw.githubusercontent.com/jrfrigat/YandexMusic/main/scripts/install.sh | sh

Then run it from anywhere:

ymt

Re-running the same command updates in place, but you rarely have to: the player checks GitHub for a newer release at startup and every half hour after that, says so on the main menu when one exists, and installs it on u. "About" (i) shows the current version and checks on demand. Set YM_PLAYER_NO_UPDATE_CHECK=1 to turn the automatic check off; the manual one still works. To pin a version or change the location, see scripts/.

Or grab the archives by hand from the Releases page (ymt-<version>-win-x64.zip, ymt-<version>-linux-x64.tar.gz), or run it from source:

dotnet run --project samples/YandexMusicTerminal
  • Sign in with an OAuth token, the device-code flow, a QR code, or login + password; the session is cached so the next run starts already signed in.
  • Playback uses NAudio on Windows; everywhere else (and as a fallback) it runs a silent simulation that drives the same UI. The audio backend is a single IAudioPlayer seam, so swapping in a cross-platform backend changes one line.
  • Remote control — the screen lists both the account's Ynison devices and the speakers answering on this network, numbered in one row. Pick one with 1-9 and the transport keys drive it; 0 hands them back to the session, r rescans.
  • Per-track actions (now-playing view) — l like · x dislike (and skip) · t lyrics · i an endless radio of similar tracks · r send the track to a speaker, which then fetches and plays it itself. Playback starts and skips are reported back to the API, so "My Wave" keeps learning from what you play.
  • Search — tabs for tracks, artists, albums and playlists, paging via a "more" row, and drill-in to a picked artist's, album's or playlist's tracks.
  • Main menu is cursor-driven with a hotkey bar along the bottom — single-key shortcuts jump straight to a section (s search · a albums · l playlists · p open player · r remote · g request log · q quit).
  • Controls (now-playing view): space play/pause · ←/→ prev/next · ↑/↓ volume · s stop · q back — plus l/x/t/i for like, dislike, lyrics and similar (see above).

See the sample's README for the architecture.

Installation

# Core client
dotnet add package YandexMusic

# Optional: real-time state and remote control
dotnet add package YandexMusic.Ynison

# Optional: smart speakers on the local network
dotnet add package YandexMusic.Quasar

# Optional: dependency-injection integration
dotnet add package YandexMusic.DependencyInjection
Package Purpose
YandexMusic The YandexMusicClient, models, authentication and endpoint groups.
YandexMusic.Ynison CreateYnisonClient() — the account's live playback state and the remote.
YandexMusic.Quasar Finds Yandex speakers on the local network and drives them directly.
YandexMusic.DependencyInjection AddYandexMusic() — a scoped client over an IHttpClientFactory pool.

The core package is standalone and depends on nothing but the BCL — most consumers want the REST API and nothing else, so the websocket-based remote and the speaker support live in their own packages rather than in everyone's dependency tree.

Quick start

using YandexMusic;

await using var client = new YandexMusicClient();

// Authorize with an OAuth token (never hardcode it — use an environment variable or a secure store)
client.Authentication.SignInWithToken(Environment.GetEnvironmentVariable("YANDEX_MUSIC_TOKEN")!);

// Track metadata and a direct media link
var track = await client.Tracks.GetAsync("4");
Console.WriteLine(track?.Title);
var link = await client.Tracks.GetDirectLinkAsync("4");

// Search and autocomplete
var results = await client.Search.SearchAsync("Queen");
var hints = await client.Search.SuggestAsync("que");

// Albums, artists, playlists (all catalogue ids are strings)
var album = await client.Albums.GetWithTracksAsync("3");
var artist = await client.Artists.GetBriefInfoAsync("79215");
var playlist = await client.Playlists.GetAsync("yamusic-daily", "1000");

// Account and library
var status = await client.Account.GetStatusAsync();
var uid = status!.Account.Uid.ToString();
var liked = await client.Library.GetLikedTracksAsync(uid);
await client.Library.AddLikedTracksAsync(uid, ["4"]);

// Discovery: radio, landing, charts
var dashboard = await client.Radio.GetStationsDashboardAsync();
var chart = await client.Landing.GetChartAsync("russia");
var newReleases = await client.Landing.GetNewReleasesAsync();

Sign in with the OAuth device-code flow

No password handling — show the user a short code, then poll until they confirm it:

await using var client = new YandexMusicClient();
var token = await client.Authentication.SignInWithDeviceFlowAsync(code =>
    Console.WriteLine($"Open {code.VerificationUrl} and enter code {code.UserCode}"));
// The client is now authenticated; persist token.AccessToken if you want to reuse it.

Control playback in real time (Ynison)

Ynison is what synchronizes the web player, the phone apps and smart speakers. The client subscribes to the account's playback state and can control any device of the session. It ships separately, in YandexMusic.Ynison:

using YandexMusic.Ynison;

await using var ynison = client.CreateYnisonClient();
var run = Task.Run(() => ynison.RunAsync());

var state = await ynison.WaitForStateAsync(TimeSpan.FromSeconds(10));
Console.WriteLine(state.Devices.Count + " device(s) in the session");
ynison.StateReceived += (_, s) => Console.WriteLine(s.PlayerState?.PlayerQueue?.PlayableList[
    Math.Max(0, s.PlayerState.PlayerQueue.CurrentPlayableIndex)]?.Title);

await ynison.SetPausedAsync(paused: false);   // remote control
await ynison.NextTrackAsync();

Drive a speaker on the local network (Quasar)

A smart speaker never joins the account's Ynison session, so the only way to reach one is to talk to it directly. YandexMusic.Quasar finds them over mDNS and connects to each speaker itself:

using YandexMusic.Quasar;

// Discovery alone needs no account, no token and no internet connection.
var scanner = new LocalDeviceScanner();
await foreach (var found in scanner.DiscoverAsync(TimeSpan.FromSeconds(3)))
{
    Console.WriteLine($"{found.Platform} at {found.Endpoint}");
}

// Driving one does: the account supplies its name, its certificate and a per-device token.
using var quasar = client.CreateQuasarClient();
var speaker = (await quasar.GetDevicesAsync()).First(d => d.Platform == "yandexmini");

await using var control = await quasar.ConnectAsync(speaker);
_ = control.RunAsync();
await control.WaitForStateAsync(TimeSpan.FromSeconds(10));

await control.PlayTrackAsync("38633712");   // the speaker fetches and plays it itself
await control.SetVolumeAsync(0.4);

The connection pins the speaker's TLS certificate against the one the account publishes for it — the certificate is self-signed and names localhost, so ordinary validation could never succeed and "trust anything" would be the only alternative.

Every method accepts a CancellationToken:

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var track = await client.Tracks.GetAsync("4", cts.Token);

Authentication & session persistence

Getting an OAuth token

The simplest way to obtain a token is Yandex's OAuth implicit flow. Open this URL in a browser, sign in, and confirm access:

https://oauth.yandex.ru/authorize?response_type=token&client_id=23cabbbdc6cd418abb4b39c32c41195d

You'll be redirected to a music.yandex.ru URL with the token in the fragment (after the #):

https://music.yandex.ru/#access_token=y0__xExampleFAKEtokenDoNotUse000000000000000000&token_type=bearer&expires_in=24752795&cid=ab1cd23efghij4klmn5opqrs6

Copy the value of access_token (here y0__xExampleFAKEtokenDoNotUse000000000000000000) — that is your token. Keep it secret; pass it via the YANDEX_MUSIC_TOKEN environment variable (or paste it into the sample player's OAuth token sign-in). The token_type, expires_in and cid parts are not needed.

Sign in & persist a session

Sign in with an OAuth token, then export the session to resume it later:

client.Authentication.SignInWithToken("<oauth-token>");

var snapshot = client.Authentication.Session.Export();      // serializable record
var json = System.Text.Json.JsonSerializer.Serialize(snapshot);
// ... store json securely ...
client.Authentication.Session.Import(
    System.Text.Json.JsonSerializer.Deserialize<YandexMusic.Authentication.AuthSnapshot>(json)!);

Dependency injection

services.AddYandexMusic(options =>
{
    options.Timeout = TimeSpan.FromSeconds(30);
    options.DeviceId = "my-app";
});

// IYandexMusicClient is registered as scoped, isolated per scope.

Documentation

Full guides and API reference: https://jrfrigat.github.io/YandexMusic/

Repository layout

.
├── src/
│   ├── YandexMusic/                     # core library (client, models, endpoints, auth, JSON)
│   ├── YandexMusic.Ynison/              # real-time state and remote control (websocket)
│   ├── YandexMusic.Quasar/              # speakers on the local network (mDNS + websocket)
│   └── YandexMusic.DependencyInjection/ # AddYandexMusic() integration
├── tests/
│   └── YandexMusic.Tests/               # unit + (token-gated) integration tests (xUnit)
├── samples/
│   └── YandexMusicTerminal/              # interactive terminal music player (TUI demo)
├── scripts/                             # one-command installers for the player (ps1 + sh)
├── docs/                                # documentation site (DocFX)
└── .github/workflows/                   # CI, release (NuGet), docs publishing

Build and test

dotnet restore
dotnet build -c Release
dotnet test  -c Release

The .NET SDK 10 is required (it builds the net8.0/net9.0/net10.0 targets). Integration tests hit the real API and are skipped automatically unless YANDEX_MUSIC_TOKEN is set:

YANDEX_MUSIC_TOKEN=<your-token> dotnet test -c Release

License

MIT © FrigaT

About

Unofficial async .NET client for the Yandex Music API - full catalogue & personal endpoints, Ynison real-time remote, and direct local-network control of Yandex smart speakers. Source-gen JSON, AOT-ready, .NET 8/9/10. Ships a terminal player.

Topics

Resources

Contributing

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages