537 lines
14 KiB
Markdown
537 lines
14 KiB
Markdown
# ⚡ Быстрый старт - YandexMusic
|
||
|
||
5-минутное введение в использование YandexMusic для начинающих.
|
||
|
||
## 📋 Содержание
|
||
|
||
- [Установка](#установка)
|
||
- [Ваш первый запрос](#ваш-первый-запрос)
|
||
- [Авторизация](#авторизация)
|
||
- [Основные операции](#основные-операции)
|
||
- [WebSocket (Ynison)](#websocket-ynison)
|
||
- [Обработка ошибок](#обработка-ошибок)
|
||
- [Дальнейшее обучение](#дальнейшее-обучение)
|
||
|
||
## 📦 Установка
|
||
|
||
### 1. Требования
|
||
|
||
- .NET 10 SDK
|
||
- C# 12 совместимый компилятор
|
||
|
||
### 2. Создание проекта
|
||
|
||
```bash
|
||
# Создаём консольное приложение
|
||
dotnet new console -n MyMusicApp
|
||
cd MyMusicApp
|
||
|
||
# Добавляем ссылку на YandexMusic (если опубликовано в NuGet)
|
||
dotnet add package YandexMusic
|
||
|
||
# ИЛИ добавляем ссылку на проект локально
|
||
dotnet add reference ../YandexMusic/YandexMusic.csproj
|
||
```
|
||
|
||
### 3. Восстановление зависимостей
|
||
|
||
```bash
|
||
dotnet restore
|
||
```
|
||
|
||
## ✨ Ваш первый запрос
|
||
|
||
### Простой поиск (без авторизации)
|
||
|
||
```csharp
|
||
using YandexMusic;
|
||
using YandexMusic.API;
|
||
|
||
// Создаём клиент
|
||
var client = new YandexMusicClient();
|
||
|
||
// Ищем музыку
|
||
var results = await client.Api.Search.SearchAsync("Ленинград");
|
||
|
||
// Выводим первые результаты
|
||
if (results?.Tracks?.Results != null)
|
||
{
|
||
foreach (var track in results.Tracks.Results.Take(5))
|
||
{
|
||
Console.WriteLine($"🎵 {track.Title} - {string.Join(", ", track.Artists?.Select(a => a.Title) ?? [])}");
|
||
}
|
||
}
|
||
```
|
||
|
||
### Получение информации о треке
|
||
|
||
```csharp
|
||
var track = await client.Api.Track.GetTrackAsync("trackId");
|
||
|
||
if (track != null)
|
||
{
|
||
Console.WriteLine($"Трек: {track.Title}");
|
||
Console.WriteLine($"Исполнитель: {track.Artists?.FirstOrDefault()?.Title}");
|
||
Console.WriteLine($"Альбом: {track.Album?.Title}");
|
||
Console.WriteLine($"Длительность: {track.DurationMs / 1000} сек");
|
||
}
|
||
```
|
||
|
||
## 🔐 Авторизация
|
||
|
||
### Способ 1: Через логин и пароль
|
||
|
||
```csharp
|
||
var client = new YandexMusicClient();
|
||
|
||
try
|
||
{
|
||
// Авторизуемся
|
||
await client.AuthorizeAsync("your-email@gmail.com", "your-password");
|
||
|
||
Console.WriteLine($"✅ Авторизирован: {client.Account.User?.DisplayName}");
|
||
Console.WriteLine($"💰 Подписка: {client.Account.Plus?.HasPlus}");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"❌ Ошибка: {ex.Message}");
|
||
}
|
||
```
|
||
|
||
### Способ 2: Через токен
|
||
|
||
```csharp
|
||
var client = new YandexMusicClient();
|
||
|
||
// Если у вас уже есть токен
|
||
await client.AuthorizeByTokenAsync("your-oauth-token");
|
||
|
||
Console.WriteLine($"✅ Авторизирован через токен");
|
||
```
|
||
|
||
## 📚 Основные операции
|
||
|
||
### 1. Поиск
|
||
|
||
```csharp
|
||
// Поиск треков
|
||
var search = await client.Api.Search.SearchAsync("Beatles");
|
||
var tracks = search?.Tracks?.Results ?? [];
|
||
foreach (var t in tracks.Take(10))
|
||
{
|
||
Console.WriteLine($" {t.Title}");
|
||
}
|
||
|
||
// Поиск альбомов
|
||
var albumSearch = await client.Api.Search.SearchAsync("Abbey Road", type: "album");
|
||
|
||
// Поиск исполнителей
|
||
var artistSearch = await client.Api.Search.SearchAsync("John Lennon", type: "artist");
|
||
```
|
||
|
||
### 2. Альбомы
|
||
|
||
```csharp
|
||
// Получение альбома
|
||
var album = await client.Api.Album.GetAlbumAsync("albumId");
|
||
Console.WriteLine($"Альбом: {album?.Title} ({album?.Year})");
|
||
Console.WriteLine($"Жанр: {album?.Genre}");
|
||
|
||
// Список треков в альбоме
|
||
foreach (var track in album?.Tracks ?? [])
|
||
{
|
||
Console.WriteLine($" {track.Position}. {track.Title}");
|
||
}
|
||
|
||
// Получение нескольких альбомов
|
||
var albums = await client.Api.Album.GetAlbumsAsync(["albumId1", "albumId2"]);
|
||
```
|
||
|
||
### 3. Исполнители
|
||
|
||
```csharp
|
||
// Получение исполнителя
|
||
var artist = await client.Api.Artist.GetArtistAsync("artistId");
|
||
Console.WriteLine($"Исполнитель: {artist?.Title}");
|
||
Console.WriteLine($"Жанр: {artist?.Genre}");
|
||
|
||
// Фото исполнителя
|
||
if (artist?.Cover?.Pic != null)
|
||
{
|
||
Console.WriteLine($"Фото: {artist.Cover.Pic}");
|
||
}
|
||
|
||
// Информация об исполнителе
|
||
Console.WriteLine($"Альбомов: {artist?.Albums?.Count}");
|
||
Console.WriteLine($"Треков: {artist?.Tracks?.Count}");
|
||
```
|
||
|
||
### 4. Плейлисты
|
||
|
||
```csharp
|
||
// Получение плейлиста
|
||
var playlist = await client.Api.Playlist.GetPlaylistAsync("playlistId");
|
||
Console.WriteLine($"Плейлист: {playlist?.Title}");
|
||
Console.WriteLine($"Описание: {playlist?.Description}");
|
||
Console.WriteLine($"Треков: {playlist?.Tracks?.Count}");
|
||
|
||
// Список треков
|
||
foreach (var track in playlist?.Tracks ?? [])
|
||
{
|
||
Console.WriteLine($" {track.Title}");
|
||
}
|
||
|
||
// Получение информации о плейлисте через UUID
|
||
var playlistByUuid = await client.Api.Playlist.GetPlaylistByUuidAsync("uuid");
|
||
```
|
||
|
||
### 5. Треки
|
||
|
||
```csharp
|
||
// Получение одного трека
|
||
var track = await client.Api.Track.GetTrackAsync("trackId");
|
||
|
||
// Получение нескольких треков
|
||
var tracks = await client.Api.Track.GetTracksAsync(["id1", "id2", "id3"]);
|
||
|
||
// Дополнительная информация о треке
|
||
var supplement = await client.Api.Track.GetTrackSupplementAsync("trackId");
|
||
|
||
// Похожие треки
|
||
var similar = await client.Api.Track.GetTrackSimilarAsync("trackId");
|
||
```
|
||
|
||
### 6. Радио
|
||
|
||
```csharp
|
||
// Получение станций
|
||
var stations = await client.Api.Radio.GetStationsAsync();
|
||
|
||
foreach (var station in stations?.Stations ?? [])
|
||
{
|
||
Console.WriteLine($"📻 {station.Title}");
|
||
}
|
||
|
||
// Треки станции
|
||
var stationTracks = await client.Api.Radio.GetStationTracksAsync("stationId");
|
||
foreach (var track in stationTracks?.Sequence ?? [])
|
||
{
|
||
Console.WriteLine($" {track.Track?.Title}");
|
||
}
|
||
```
|
||
|
||
### 7. Библиотека (Лайки)
|
||
|
||
```csharp
|
||
// Получение лайков
|
||
var library = await client.Api.Library.GetLibraryAsync();
|
||
|
||
Console.WriteLine($"Лайки: {library?.Library?.Count}");
|
||
|
||
// Добавление трека в лайки
|
||
await client.Api.Library.LibraryAddAsync("trackId");
|
||
|
||
// Удаление из лайков
|
||
await client.Api.Library.LibraryRemoveAsync("trackId");
|
||
```
|
||
|
||
### 8. Главная страница (Landing)
|
||
|
||
```csharp
|
||
// Получение рекомендаций
|
||
var landing = await client.Api.Landing.GetLandingAsync("home");
|
||
|
||
foreach (var block in landing?.Blocks ?? [])
|
||
{
|
||
Console.WriteLine($"Блок: {block.Title}");
|
||
|
||
foreach (var entity in block.Entities ?? [])
|
||
{
|
||
Console.WriteLine($" {entity.Title}");
|
||
}
|
||
}
|
||
```
|
||
|
||
## 🌐 WebSocket (Ynison)
|
||
|
||
### Подключение к Ynison
|
||
|
||
```csharp
|
||
var client = new YandexMusicClient();
|
||
|
||
// Авторизуемся
|
||
await client.AuthorizeAsync("email@gmail.com", "password");
|
||
|
||
// Получаем плеер
|
||
var player = client.Ynison;
|
||
|
||
if (player != null)
|
||
{
|
||
// Подключаемся
|
||
await player.ConnectAsync();
|
||
Console.WriteLine("✅ Подключены к Ynison");
|
||
|
||
// Используем плеер...
|
||
|
||
// Отключаемся
|
||
await player.DisconnectAsync();
|
||
}
|
||
```
|
||
|
||
## ⚠️ Обработка ошибок
|
||
|
||
### Базовая обработка
|
||
|
||
```csharp
|
||
try
|
||
{
|
||
var track = await client.Api.Track.GetTrackAsync("trackId");
|
||
if (track == null)
|
||
{
|
||
Console.WriteLine("Трек не найден");
|
||
}
|
||
}
|
||
catch (HttpRequestException ex)
|
||
{
|
||
Console.WriteLine($"Ошибка сети: {ex.Message}");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"Неожиданная ошибка: {ex.Message}");
|
||
}
|
||
```
|
||
|
||
### Проверка авторизации
|
||
|
||
```csharp
|
||
if (!client.IsAuthorized)
|
||
{
|
||
Console.WriteLine("❌ Требуется авторизация");
|
||
return;
|
||
}
|
||
|
||
// Выполняем авторизованные операции
|
||
var account = await client.Api.User.GetAccountAsync();
|
||
```
|
||
|
||
### Валидация входных параметров
|
||
|
||
```csharp
|
||
public async Task GetTrackInfo(string trackId)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(trackId))
|
||
{
|
||
Console.WriteLine("❌ ID трека не может быть пустым");
|
||
return;
|
||
}
|
||
|
||
var track = await client.Api.Track.GetTrackAsync(trackId);
|
||
if (track == null)
|
||
{
|
||
Console.WriteLine($"❌ Трек с ID {trackId} не найден");
|
||
return;
|
||
}
|
||
|
||
Console.WriteLine($"✅ {track.Title}");
|
||
}
|
||
```
|
||
|
||
## 🔍 Полные примеры
|
||
|
||
### Пример 1: Поиск и загрузка информации
|
||
|
||
```csharp
|
||
using YandexMusic;
|
||
|
||
// Создание клиента
|
||
var client = new YandexMusicClient();
|
||
|
||
// Поиск
|
||
Console.Write("Введите исполнителя: ");
|
||
string query = Console.ReadLine() ?? "Beatles";
|
||
|
||
var search = await client.Api.Search.SearchAsync(query);
|
||
var artists = search?.Artists?.Results ?? [];
|
||
|
||
if (artists.Count == 0)
|
||
{
|
||
Console.WriteLine("Исполнители не найдены");
|
||
return;
|
||
}
|
||
|
||
// Выбор первого результата
|
||
var artist = artists.First();
|
||
Console.WriteLine($"Найден: {artist.Title}");
|
||
|
||
// Получение полной информации
|
||
var fullArtist = await client.Api.Artist.GetArtistAsync(artist.Id);
|
||
Console.WriteLine($"Жанр: {fullArtist?.Genre}");
|
||
Console.WriteLine($"Альбомов: {fullArtist?.Albums?.Count}");
|
||
|
||
// Список треков
|
||
Console.WriteLine("\nПопулярные треки:");
|
||
foreach (var track in fullArtist?.Tracks?.Take(5) ?? [])
|
||
{
|
||
Console.WriteLine($" 🎵 {track.Title}");
|
||
}
|
||
```
|
||
|
||
### Пример 2: Работа с плейлистом
|
||
|
||
```csharp
|
||
using YandexMusic;
|
||
|
||
var client = new YandexMusicClient();
|
||
|
||
// ID плейлиста Яндекса
|
||
string playlistId = "1130499373";
|
||
|
||
// Получение плейлиста
|
||
var playlist = await client.Api.Playlist.GetPlaylistAsync(playlistId);
|
||
|
||
Console.WriteLine($"📋 {playlist?.Title}");
|
||
Console.WriteLine($"Описание: {playlist?.Description}");
|
||
Console.WriteLine($"Треков: {playlist?.Tracks?.Count}");
|
||
|
||
// Вывод треков с номерами
|
||
Console.WriteLine("\nТреки:");
|
||
int i = 1;
|
||
foreach (var track in playlist?.Tracks ?? [])
|
||
{
|
||
var artists = string.Join(", ", track.Artists?.Select(a => a.Title) ?? []);
|
||
Console.WriteLine($"{i}. {track.Title} - {artists}");
|
||
i++;
|
||
}
|
||
|
||
// Общая длительность
|
||
var totalSeconds = (playlist?.Tracks ?? []).Sum(t => t.DurationMs ?? 0) / 1000;
|
||
var hours = totalSeconds / 3600;
|
||
var minutes = (totalSeconds % 3600) / 60;
|
||
Console.WriteLine($"\nОбщая длительность: {hours}:{minutes:D2}");
|
||
```
|
||
|
||
### Пример 3: Авторизация и библиотека
|
||
|
||
```csharp
|
||
using YandexMusic;
|
||
|
||
var client = new YandexMusicClient();
|
||
|
||
Console.Write("Email: ");
|
||
string email = Console.ReadLine() ?? "";
|
||
|
||
Console.Write("Password: ");
|
||
string password = Console.ReadLine() ?? "";
|
||
|
||
try
|
||
{
|
||
await client.AuthorizeAsync(email, password);
|
||
Console.WriteLine($"✅ Добро пожаловать, {client.Account.User?.DisplayName}!");
|
||
|
||
if (client.IsAuthorized)
|
||
{
|
||
// Получение лайков
|
||
var library = await client.Api.Library.GetLibraryAsync();
|
||
Console.WriteLine($"\n❤️ Ваши лайки: {library?.Library?.Count} треков");
|
||
|
||
// Список лайков
|
||
if (library?.Library?.Count > 0)
|
||
{
|
||
Console.WriteLine("\nПервые 5 лайков:");
|
||
var trackIds = library.Library.Select(l => l.TrackId).Take(5);
|
||
var tracks = await client.Api.Track.GetTracksAsync(trackIds);
|
||
|
||
foreach (var track in tracks)
|
||
{
|
||
Console.WriteLine($" ❤️ {track?.Title}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"❌ Ошибка: {ex.Message}");
|
||
}
|
||
```
|
||
|
||
## 📖 Дальнейшее обучение
|
||
|
||
### Документация
|
||
|
||
- **[README.md](README.md)** - Полное описание проекта
|
||
- **[ARCHITECTURE.md](ARCHITECTURE.md)** - Архитектура и паттерны
|
||
- **[YandexMusic.API/README.md](YandexMusic.API/README.md)** - Низкоуровневый API
|
||
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Как внести вклад
|
||
|
||
### Полезные ресурсы
|
||
|
||
- [.NET 10 Documentation](https://learn.microsoft.com/dotnet/)
|
||
- [C# 12 Features](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12)
|
||
- [System.Text.Json Guide](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json)
|
||
|
||
### Где найти ID
|
||
|
||
**Трека:** `https://music.yandex.ru/album/123456/track/789012`
|
||
- Album ID: `123456`
|
||
- Track ID: `789012`
|
||
|
||
**Плейлиста:** `https://music.yandex.ru/playlist/1130499373`
|
||
- Playlist ID: `1130499373`
|
||
|
||
**Исполнителя:** `https://music.yandex.ru/artist/123456`
|
||
- Artist ID: `123456`
|
||
|
||
## ⚡ Советы и трюки
|
||
|
||
### 1. Работа с async/await
|
||
|
||
```csharp
|
||
// Получение нескольких ресурсов параллельно
|
||
var (albums, artists, tracks) = await (
|
||
client.Api.Album.GetAlbumsAsync(ids),
|
||
client.Api.Artist.GetArtistsAsync(ids),
|
||
client.Api.Track.GetTracksAsync(ids)
|
||
).AsAsync();
|
||
```
|
||
|
||
### 2. Обработка больших списков
|
||
|
||
```csharp
|
||
// Пагинация для больших результатов
|
||
var allPlaylists = new List<YPlaylist>();
|
||
int page = 0;
|
||
|
||
while (true)
|
||
{
|
||
var playlists = await client.Api.Playlist.GetPlaylistsAsync(page: page);
|
||
if (playlists?.Playlists?.Count == 0) break;
|
||
|
||
allPlaylists.AddRange(playlists.Playlists ?? []);
|
||
page++;
|
||
}
|
||
```
|
||
|
||
### 3. Кеширование результатов
|
||
|
||
```csharp
|
||
private readonly Dictionary<string, YTrack?> _trackCache = new();
|
||
|
||
public async Task<YTrack?> GetTrackAsync(string id)
|
||
{
|
||
if (_trackCache.TryGetValue(id, out var cached))
|
||
return cached;
|
||
|
||
var track = await client.Api.Track.GetTrackAsync(id);
|
||
_trackCache[id] = track;
|
||
return track;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
**Следующий шаг:** Прочитайте [ARCHITECTURE.md](ARCHITECTURE.md) для понимания внутреннего устройства.
|
||
|
||
**Нужна помощь?** Посмотрите [README.md](README.md) или создайте issue.
|
||
|
||
Удачи в разработке! 🚀
|