YandexMusic.Quasar 0.6.0

dotnet add package YandexMusic.Quasar --version 0.6.0
                    
NuGet\Install-Package YandexMusic.Quasar -Version 0.6.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="YandexMusic.Quasar" Version="0.6.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="YandexMusic.Quasar" Version="0.6.0" />
                    
Directory.Packages.props
<PackageReference Include="YandexMusic.Quasar" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add YandexMusic.Quasar --version 0.6.0
                    
#r "nuget: YandexMusic.Quasar, 0.6.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package YandexMusic.Quasar@0.6.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=YandexMusic.Quasar&version=0.6.0
                    
Install as a Cake Addin
#tool nuget:?package=YandexMusic.Quasar&version=0.6.0
                    
Install as a Cake Tool

YandexMusic.Quasar

Yandex smart speakers for the YandexMusic client: find them on the local network and drive them directly, without going through the cloud. Targets .NET 8, 9 and 10.

A speaker never joins the account's Ynison session, so this is the only way to reach one.

Find what is on the network

Discovery is mDNS/DNS-SD (_yandexio._tcp) and needs no account, no token and no internet connection — it asks the local network and reports what answers.

using YandexMusic.Quasar;

var scanner = new LocalDeviceScanner();
await foreach (var device in scanner.DiscoverAsync(TimeSpan.FromSeconds(3)))
{
    Console.WriteLine($"{device.Platform} {device.DeviceId} at {device.Endpoint}");
}

Finding nothing is a normal outcome, not an error: many corporate and guest networks block multicast outright.

Devices do not advertise the name their owner gave them, so a UI that wants to show "kitchen" has to get it from the account and match on DeviceId.

Drive one

Control needs the account, for two things the network cannot supply: a per-device token, and the certificate the speaker is supposed to present.

using YandexMusic;
using YandexMusic.Quasar;

await using var music = new YandexMusicClient();
music.Authentication.SignInWithToken("<oauth-token>");

using var quasar = music.CreateQuasarClient();
var speaker = (await quasar.GetDevicesAsync()).First(d => d.Platform == "yandexmini");

await using var control = await quasar.ConnectAsync(speaker);
_ = control.RunAsync();

var state = await control.WaitForStateAsync(TimeSpan.FromSeconds(10));
Console.WriteLine($"{speaker.Name}: {state.State?.PlayerState?.Title}");

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

GetDevicesAsync returns every Quasar device on the account, which is more than speakers — cameras and the phone apps signed in to it come back too. Filter on NetworkInfo and Platform.

The certificate is pinned, deliberately

A speaker presents a self-signed certificate that names localhost, so ordinary validation can never succeed and the usual shortcut is to trust anything. This package does not: it compares the certificate against the one the account publishes for that exact device, and refuses anything else.

Expiry is not checked, on purpose. Speakers are shipping certificates that expired years ago and still work; rejecting them would lock out the real device while proving nothing about any other.

Three things that will look like bugs

  • A command's reply carries the state from before the command was applied. Pause a speaker and its answer still says Playing; the truth arrives in the frames that follow. Confirming a command by reading its own answer concludes, every time, that nothing happened.
  • Not every command is answered at all, and SUCCESS is not proof that anything started — an unknown track id gets the same answer as a good one. The state stream is the only source of truth.
  • Times here are seconds, where YandexMusic.Ynison uses milliseconds for the same things.

The protocol is undocumented; all of the above was measured against real hardware rather than assumed. The findings are written up in the repository.

Documentation: https://jrfrigat.github.io/YandexMusic/

⚠️ Unofficial library, not affiliated with Yandex. It talks to undocumented endpoints. Use at your own risk and comply with the Yandex Music terms of use.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.6.0 101 8/23/2026