Яндекс Музыка для Android, немного о недочётах и странностях сервиса

Я хотел бы рассмотреть приложение Яндекс Музыка для Android (и немного сам сервис) и указать на недочёты/неудобства, которые мне попались.
Пользуюсь я сервисом пару месяцев всего, но считаю что свои 150 рублей Ямузыка оправдывает с лихвой. Довольно большой каталог, местами правда обрезанный (например у Arcade Fire всего 2 альбома в наличии, а всё что ранее 2010 — отсутствует), но сейчас не об этом.
1. Тёмная тема (веб/приложение)
У меня Motorola с amoled-экраном (чёрный батарею не ест), да и вообще, приложение в цветовой гамме белый-жёлтый — не самый лучший вариант, днём всё хорошо, но вот вечером-ночью можно использовать экран телефона как фонарик если запустить Ямузыку.
2. Оффлайн режим, и вообще, библиотека и немного о рекомендациях
Именному поэтому я и купил подписку, возможность скачивать треки в кэш и слушать когда нет нормального интернет соединения (а в Крыму его нигде и никогда не было и нет). В меню нету отдельного пункта под эти самые сохранённые треки, самое удобное что можно сделать, это создать плейлист, накидать в него музыки и затем сохранить в один клик к себе. Нельзя сохранить целый альбом (сохранятся только те треки, которые отмечены сердечком («мне нравится»). Если я жму на «мне нравится» у альбома — на треки это никак не действует, они таким значком не помечаются и выкачать весь альбом себе сразу я всё ещё не могу. Проще говоря, куда-то уходя я просто захожу в «мне понравившиеся треки», и по одному тыкаю на какие-нибудь из них, это неудобно, или же иду в мои альбомы, захожу в какой-то из них, понимаю, чтобы выкачать весь альбом, мне всё равно надо отметить каждый-каждый трек и лишь затем нажать на «скачать всё». Затем, я например, жму «перемешать всё», и тут, аллилуйя, приложение играет только то, что скачано, но продолжает почти после каждого трека (ведь выкачиваю я с пробелами в общем списке) сообщает, что я в оффлайн режиме и это не комильфо. Ну и обложки кэшируются через раз.


Рекомендации — они хороши, но не в случае с зарубежной музыкой (pandora/spotify и xbox музыка понимали меня лучше, мб из-за более крупного каталога как минимум у пандоры и сервиса Microsoft), зато с русскоязычными исполнителями всё отлично, 3 месяца назад я почти ничего не слушал из подобных, но Ямузыка это поменяла.
3. Скробблинг (last.fm) и Яндекс Диск
До определённого момента я думал, что в приложении нет скробблинга, скачал simple last fm scrobbler и ещё парочку приложений с таким функционалом, но ни одно из них не поймало яндекс музыку. После, написал в техподдержку где мне сказали, что сервис независимо от моего хотения скробблит музыку, если в настройках самого сервиса в веб-версии эта функция включена (и если я не в оффлайн режиме). Я ничего не имею против, но об этом можно где-то указать было бы. При этом остаётся непонятным момент про оффлайн режим и настройку wi-fi/мобильный интернет, я могу выключить использование мобильного интернета, это ясно — но не ясно, работает ли при этом скробблинг?
В-общем, было бы гораздо круче если бы кто-нибудь из Яндекса прикрутил Ямузыку к Simple Lastfm Scrobbler, т.к его исходный код открыт и им пользуется куча народу, пропиаритесь чуток заодно 😀
Про Яндекс Диск тоже непонятно, в Википедии есть упоминание, что мол с 29 ноября прошлого года можно заливать свои треки в Диск и слушать их из Ямузыки, где они будут отображаться? Почему об этом нигде не указано? (Оказалось, это маленький пункт настроек, хотя Google с их Музыкой использовали это чуть ли не как основную фишку сервиса долгое время).
На этом всё, надеюсь, кто-то из Яндекса прочитает моё нытье, и (на что я даже не надеюсь), передаст это куда-нибудь)
Как скачать музыку на Android

Если слушать музыку с телефона онлайн нет возможности, скачайте предварительно на Андроид любимые треки и наслаждайтесь ими в поездке или в любых других условиях. Обо всех удобных и простых способах загрузки музыки на ваше устройство мы поговорим в этой статье.
Если вы желаете слушать на телефоне музыку в офлайн режиме, вам потребуется скачать треки в память устройства. На гаджетах с ОС Андроид вы можете сделать это несколькими способами, как из Интернета, так и с компьютера, если на нем есть любимые композиции.
Содержание Показать
Скачивание музыки из Интернета
Скачать музыку из Интернета вы можете с помощью специальных приложений или напрямую, через браузер, установленный на мобильном устройстве.
Приложения для загрузки музыки
Для загрузки музыки в телефон существует ряд приложений (Zaicev.net, RYT и т.д.), доступных для скачивания в магазине для Android. Найти их вы сможете, набрав в поисковой строке Play Market фразу «Скачать музыку». Рассмотрим их принцип работы на примере Zaycev.net:
Шаг 1. Скачайте приложение «Zaycev.Net» из Play Market.

Шаг 2. Запустите приложение. На главной странице вы увидите наиболее часто скачиваемые треки.

Шаг 3. Найдите музыку, которую желаете скачать. Вы можете воспользоваться строкой поиска, а также поискать треки среди новых или по жанрам.

Шаг 4. Выбрав песню, нажмите на нее для прослушивания. Если это действительно желаемая композиция, нажмите на кнопку в виде стрелки вниз для загрузки.

После завершения загрузки в панели уведомлений появится соответствующее оповещение. Скачанная песня по умолчанию находится в папке «Музыка» («Music») на телефоне, но вы можете выбрать другую в настройках приложения.
Похожим образом работают и другие мобильные приложения для загрузки музыки. Они удобны, но имеют существенный недостаток: в них можно найти только те композиции, которые есть в их базах. Если же ваш любимый трек в них отсутствует, то загрузить его не удастся. В таком случае стоит прибегнуть к следующему способу.
Скачивание музыки через браузер
Этот способ удобен тем, что не требует установки дополнительного ПО, а также позволяет скачать практически любую композицию.
Шаг 1. Откройте установленный на телефоне браузер и введите в поисковую строку фразу: ««название песни» скачать».

Шаг 2. На экране появится сайты, с которых можно скачать выбранный трек. Выберите подходящий и перейдите на него.

Шаг 3. Следуйте инструкции по скачиванию композиции на веб-ресурсе. Обычно нужно найти название трека на странице и напротив него нажать на кнопку «Скачать». После завершения композиция появится в папке «Загрузки».

Обратите внимание, что формат загружаемого файла должен быть музыкальным – mp3, wav и т.д. Если же вы заметите, что на телефон будет скачан файл с расширением .exe или иным, не имеющим отношения к музыке, не стоит его загружать. Возможно, под его видом скрывается вирус или вредоносное ПО.
При скачивании музыки через браузер используйте только проверенные ресурсы. Это Zaycev.net, mp3party.net, myzuka.org и аналогичные. Не посещайте неизвестные и подозрительные сайты, т.к. на них существует риск скачать вредоносное ПО или заразить устройство вирусами.
Скачивание музыки с ПК
Этот способ подходит, если у вас на компьютере есть большое количество музыки и вы желаете переместить ее в свой телефон. Он удобен, т.к. вы можете скопировать в гаджет сразу множество композиций. Скачивание аналогичного количества песен через приложения или через браузер займет гораздо больше времени.
Для перемещения музыкальных композиций в память устройства можно использовать USB-кабель или же воспользоваться облачным хранилищем.
Через USB-кабель
Чтобы скинуть музыку на телефон через кабель, выполните следующие действия:
Шаг 1. Соедините кабелем USB от мобильного устройства разъемы на корпусе телефона и компьютера. На экране смартфона должно появиться окно с выбором действий. Если этого не происходит, откройте панель уведомлений и нажмите на окно с надписью: «Зарядка устройства по USB».

Шаг 2. Выберите «Медиа-устройство (MTP)» или «Передача файлов».

Шаг 3. С помощью файлового менеджера или через «Мой компьютер» найдите в памяти ПК музыку, выберите необходимые треки и скопируйте их.

Шаг 4. Перейдите на телефоне в папку с музыкой и вставьте скопированные песни. Дождитесь завершения процесса.

Теперь вы можете отключить смартфон от компьютера и приступить к прослушиванию треков.
Через облачное хранилище
Облачные хранилища позволяют вам не только хранить файлы в Интернете, но и перемещать их между устройствами, если авторизоваться в облаке на каждом из них. С их помощью вы можете переместить музыку с компьютера на телефон, не используя для этого кабель. Облачное пространство предлагают большинство популярных поисковиков – Яндекс, Google, Mail и т.д. Выбирайте тот, в котором у вас есть электронная почта – это позволит вам не тратить время на создание нового почтового ящика. Инструкция ниже представлена на примере хранилища от Яндекс:
Шаг 1. Перейдите по ссылке и нажмите «Войти» в правой верхней части экрана.

Шаг 2. Авторизуйтесь, указав телефон или почту и пароль.

Шаг 3. Выберите папку «Музыка».

Шаг 4. Откройте «Мой компьютер», найдите каталог с песнями, выберите необходимые и перетащите их мышью в папку «Музыка» в хранилище.

Шаг 5. Дождитесь окончания загрузки.

Шаг 6. Откройте Play Market и скачайте на телефон приложение «Яндекс.Диск».

Шаг 7. Авторизуйтесь в приложении под теми же логином и паролем, что и на ПК.

Шаг 8. Перейдите в папку «Музыка».

Шаг 9. Нажмите на одну из песен пальцем и некоторое время подержите, чтобы выделить ее. Выделите и остальные треки.

Шаг 10. Нажмите на кнопку с тремя точками справа вверху и выберите «Скачать».

Шаг 11. Выберите папку в памяти телефона, куда должны быть загружены песни. Обычно это «Music»или «Музыка». Нажмите «Сохранить здесь».

Дождитесь завершения загрузки. Теперь файлы из облака скачаны на ваш телефон.
Скачивание через Bluetooth с другого телефона или ПК
Этот способ пригодится вам, если вы услышали песню у друга на телефоне и желаете скачать ее себе. Чтобы не тратить время на поиск, вы можете попросить его передать ее вам по Bluetooth. Для этого:
Шаг 1. Включите Bluetooth на обоих устройствах.

Шаг 2. На телефоне-источнике выберите трек и выделите его нажатием.

Шаг 3. В верхней части экрана нажмите «Поделиться» и в списке возможных способов передачи файла выберите «Bluetooth».

Шаг 4. Начнется поиск устройств. Выберите смартфон получателя файла.

Шаг 5. Кликните «Принять» на телефоне, получающем трек. Начнется скачивание файла.

Когда операция завершится, на обоих устройствах появится соответствующее уведомление.
Аналогичным образом, через Bluetooth, вы можете скачать на телефон файл с ноутбука или компьютера, если у последнего есть соответствующий адаптер.
Платный способ: Яндекс.Музыка, Deezer, Spotify
Если вы пользуетесь такими приложениями, как Яндекс.Музыка, Deezer, Spotify, МТС Music или аналогичными, либо слушаете музыку через ВК, то знаете, что скачиваются они полностью бесплатно, однако в них есть платная подписка. Одна из возможностей, которую она предлагает – это прослушивание музыки в офлайн-режиме без подключения к Интернету, подразумевающее скачивание необходимых треков в память телефона. Вот как это работает на примере Яндекс.Музыки:
Шаг 1. Запустите приложение.
Шаг 2. Чтобы скачать целый плейлист (собственный или сформированный сервисом), выберите его и нажмите на кнопку «Скачать».

Шаг 3. Чтобы загрузить отдельный трек, напротив его названия нажмите на кнопку с тремя точками и нажмите «Скачать» в открывшемся окне с доступными действиями.

Шаг 4. После скачивания в нижней части экрана нажмите на кнопку «Коллекция». В открывшемся окне выберите «Скачанные треки».

Теперь у вас есть доступ ко всем загруженным песням. Слушать их вы можете в случае отсутствия Интернета через интерфейс Яндекс.Музыки. Однако у этого способ есть недостаток: файлы хранятся в зашифрованном виде, скачать их в память телефона для прослушивания через другое приложение не удастся.
Вместо итогов
Скачать музыку на телефон можно шестью способами. Загрузка с компьютера через облако или кабель подойдет вам, если у вас на ПК большое количество музыки и вы желаете переместить ее в телефон для прослушивания. Скачивание через специальные приложения или непосредственно из Интернета через браузер актуальны для тех, кто желает быстро и просто скачать на смартфон одну-две любимые песни. Загрузка музыки через Bluetooth пригодится для перемещения файлов с ноутбука или ПК на телефон, а также в случаях, если вы хотите скачать музыку с телефона другого человека. Если вы слушаете любимые песни через такие приложения, как Яндекс.Музыка, Deezer и т.д., то при наличии платной подписки вы можете скачивать треки и слушать их офлайн, но только через интерфейс самого приложения.
Интегрируем Яндекс Музыку в Visual Studio Code
Представьте, что вы можете слушать свои любимые песни на Яндекс.Музыке, прямо из своего любимого редактора кода, не переключаясь между приложениями. Это уже не мечта, а реальность! В этой статье мы рассмотрим, как интегрировать Яндекс.Музыку в Visual Studio Code и наслаждаться любимой музыкой прямо во время работы.
- Обзор расширения
- API Яндекс Музыки
- Авторизация
- Плейлисты
- Персональные плейлисты
- Плейлист “Мне нравится”
- Плейлисты пользователей
- Создание очереди
- Получение текущего проигрываемого трека
- Основные компоненты
- TreeView
- Диалог подтверждения
- Хранение паролей и настроек
- Предыстория
- Под капотом Microsoft Live Share Audio
- Архитектура Electron
- Воспроизведение трека
- Загрузка Electron в рантайме
Обзор расширения
Перед тем перейти к описанию реализации давайте краем глаза взглянем на само расширение и его возможности.

Я думаю, легко заметить, что левая панель по большому счёту просто повторяет реализацию главной страницы Яндекс Музыки. Здесь вам:
- и персональные плейлисты
- и ваши любимые песни и подкасты
- и рекомендации
- и поиск
Подборки пока отсутствуют, но со временем и они должны появиться (если не хватает ещё чего-то — дайте знать ).

Конечно же, расширение — лишь урезанная версия Я.Музыки, поэтому вы можете быстро перейти к нужному треку, альбому или плейлисту с помощью кнопки “Открыть в браузере”.
Не буду углубляться в детали, это всё-таки разбор реализации, а не демо. Если интересно поближе посмотреть на расширение — можете просто установить его.
Как авторизоваться в расширении
Есть два способа авторизоваться в расширении:

- По токену
- По логину и паролю
Почему так? Яндекс постепенно уходит от авторизации по логину и паролю, ведь способ не очень безопасный, и всё меньше и меньше пользователей могут использовать данный способ. Если вы уверены, что ввели корректные данные, но всё равно видите данную ошибку, то вам стоит использовать второй вариант — вход с помощью токена.

Существует 3 способа получить токен:
- С помощью расширения
- Для Google Chrome
- Для Firefox
Оба браузерных расширения используют последний способ и просто перехватывают токен во время редиректа, поэтому вам нужно уже быть авторизованным в Яндекс.Музыке. Исходники всех способов собраны здесь в репозитории (спасибо Илье, что всё это дело собрал вместе).
Самый простой способ — расширение для Хрома, установите его и нажмите на кнопку “Скопировать токен”.

Теперь самое время взглянуть под капот. Реализация расширения будет состоять из 3-х частей:
- Работа с API Яндекс Музыки
- Разработка VS Code расширения, отображающее треки и плейлисты
- Воспроизведение треков с помощью Electron
API Яндекс Музыки
Я думаю будет логично начать рассказ с базовой вещи, без которой это расширение не увидело бы свет — с API. Подробностей уже не помню, но мне кажется дело было так:
- Погуглил, есть ли у Я.Музыки официальное API
- Официального API нет, нашёл неофициальное API
- К сожалению, библиотека заброшена, к тому же в ней отсутствуют нужные мне методы
- Натыкаюсь на статью “Как я библиотеку для сервиса «Яндекс.Музыка» писал” и на библиотеку на питоне (Илья, если ты читаешь статью — Спасибо тебе, я не забыл про тебя!).
- Начинаю самостоятельно писать клиент Яндекс.Музыки внутри расширения. Использую также как указано в статье HTTP Analyzer и виндовое приложение Яндекс Музыки.
- Вручную пишу OpenAPI схему
- Генерирую JavaScript-клиент yandex-music-client на основе OpenAPI схемы
Работа над генерацией клиента всё ещё продолжается, и когда появится первая более-менее стабильная версия — я напишу отдельную статью.
Теперь рассмотрим самые популярные методы.
Авторизация
Первое, что необходимо сделать для использования большинства методов API — авторизация. Вы не сможете получить персональные плейлисты или же ваши любимые треки, если у вас нет токена.
Если для вашего аккаунта всё ещё работает вход по логину и паролю — используйте метод getToken как показано ниже, иначе — скопируйте токен с помощью Google Chrome Extension.
import < getToken >from 'yandex-music-client/token'; import < YandexMusicClient >from 'yandex-music-client/YandexMusicClient' // Получение токена работает не для всех пользователей // Универсальный способ получения токена через Google Chrome Extension: // https://chrome.google.com/webstore/detail/yandex-music-token/lcbjeookjibfhjjopieifgjnhlegmkib const token = await getToken('your email', 'your password'); const client = new YandexMusicClient(< BASE: "https://api.music.yandex.net:443", HEADERS: < 'Authorization': `OAuth $`, >, >);Плейлисты
Персональные плейлисты
Большинство плейлистов, которые вы видите на главной странице, можно получить с помощью метода client.landing.getLandingBlocks (GET /landing3 )
Есть разные типы лендинг блоков:
- Например, чтобы получить плейлисты “плейлист дня”, “дежавю”, “премьера” и т.д. необходимо запросить блок типа personalplaylists — client.landing.getLandingBlocks(«personalplaylists»)
- Плейлист с новинками — нужно запрашивать блок new-releases
- Чарт Я.Музыки — chart
- Новые плейлисты — new-playlists
- Подкасты — podcasts
- Интересно сейчас — promotions
Можно получить сразу несколько блоков, указав их через запятую:
client.landing.getLandingBlocks( "personalplaylists,promotions,new-releases,new-playlists,podcasts" )Именно такой запрос отправляет официальное приложение Яндекс.Музыки.

Плейлист “Мне нравится”
Все понравившиеся треки нужно получать в 2 захода:
- Получить идентификаторы понравившихся треков — (GET /users//likes/tracks )
- Получение треков по идентификаторам — (POST /tracks ). Идентификаторы должны выглядеть как строка “:”.
Код будет выглядеть вот так:
const result = await client.tracks.getLikedTracksIds(userId); const ids = result.result.library.tracks.map(track => `$:$`); const tracks = await client.tracks.getTracks(< "track-ids": ids >);Почему нужно делать 2 запроса? Возможно за всё время использования вы налайкали несколько тысяч треков и загружать их все одним махом будет достаточно жирно. Правильнее будет делать пагинацию и загружать все треки постепенно.
Стоит упомянуть ещё несколько методов:
- Лайкнуть трек — client.tracks.likeTracks (POST /users//likes/tracks/add-multiple )
- Убрать лайк — client.tracks.removeLikedTracks (POST /users//likes/tracks/remove )
- Список треков с дизлайками — client.tracks.getDislikedTracksIds (GET /users//likes/tracks/remove )
Плейлисты пользователей
Тут ничего интересного — просто перечислю существующие методы работы с плейлистами:
- Создать плейлист — client.playlists.createPlaylist (POST /users//playlists/create )
- Переименовать плейлист — client.playlists.renamePlaylist (POST /users//playlists//name )
- Удалить плейлист — client.playlists.deletePlaylist (POST /users//playlists//delete )
- Добавить/удалить треки из плейлиста — client.playlists.changePlaylistTracks (POST /users//playlists//change-relative )
- Получить все плейлисты пользователя — client.playlists.getPlayLists (GET /users//playlists/list )
- Получить плейлист по полю kind (такой идентификатор, уникальный внутри плейлистов пользователя, у других пользователей будут такие же айдишки) — client.playlists.getPlaylistById(userId, playlistKind) (GET /users//playlists/ )
- Получить список плейлистов по kind , позволяет получить треки вместе с плейлистами, если передать rich-tracks как true — client.playlists.getUserPlaylistsByIds (GET /users//playlists )
- Получить плейлист по kind — client.playlists.getPlaylistById (GET /users//playlists/ )
Радио
Методы работы с радио:
- Получить информации о станции — client.rotor.getStationInfo (GET /rotor/station//info )
- Получить треки для станции — client.rotor.getStationTracks (GET /rotor/station//tracks )
- Получить списка радиостанций — client.rotor.getStationsList (GET /rotor/stations/list )
- Получить рекомендации станций для текущего пользователя — client.rotor.getRotorStationsDashboard (GET /rotor/stations/dashboard )
- Отправить фидбэк о событиях станции. Необходимо отправлять, когда включается радио и начинается/заканчивается/или пользователь пропускает трек — (GET /rotor/station//feedback )
Если до этого, я просто перечислял запросы, то с радио всё сложнее. Тут мы остановимся поподробнее. Если мы включим HTTP Analyzer, и запустим радио в официальном виндовом приложении Я.Музыки (например “Моя волна” — user:anyourwave ) мы получим вот такую портянку запросов.

Всё выглядит гораздо проще, если нарисовать диаграмму. Стрелочки используются, чтобы показать как связаны между собой запросы, и как одни запросы используют в качестве параметров ответы других запросов.

Если вдруг вы собираетесь создавать свой клиент для радио, то можно реализовать проигрывание без отправки фидбека, что упростит логику. Но мы тут уже обсуждали и пришли к выводу, что фидбек необходим для системы рекомендаций и чтобы избежать повтора треков в персональных плейлистах.
В расширении пока реализовано только одно радио — Моя волна (исходники тут).

Очереди
Один из самых частых вопросов в чате по Яндекс.Музыке — как получить трек, который играет в данный момент. Мы уже шутили, что нужно интегрировать чат GPT, чтобы он отвечал на данный вопрос, но к сожалению он начал придумывать несуществующие методы. Так вот — получать текущий трек нужно именно на основе очередей.
Создание очереди
Очереди создаются при любом воспроизведении плейлиста, альбома или радио. Например, вот так происходит воспроизведение альбома.

- Получаем альбом с треками GET /albums//with-tracks
- Создание очереди POST /queue , куда мы передаём все треки из плейлиста
- Выставляем номер текущего трека — POST /queues//update-position?currentIndex=0
Именно благодаря этому мы можем продолжить слушать трек на любом другом устройстве. Например, я включил альбом в официальном виндовом приложении

и теперь могу продолжить слушать трек из браузера или со своего мобильного.

Получение текущего проигрываемого трека
Чтобы получить текущий проигрываемый трек, достаточно нескольких шагов:
- Получить список очередей — client.queues.getQueues() (GET /queues)
- Получить id последней воспроизводимой очереди — первая в массиве полученном на прошлом шаге.
- Запросить эту очередь — client.queues.getQueueById() (GET /queues/)
- Получить текущий трек в очереди — client.tracks.getTracks() (GET /tracks/)
Код целиком будет выглядеть вот так:
const < YandexMusicClient >= require('yandex-music-client'); const client = new YandexMusicClient(< BASE: "https://api.music.yandex.net:443", HEADERS: < 'Authorization': `OAuth `, >, >); client.queues .getQueues('os=unknown; os_version=unknown; manufacturer=unknown; model=unknown; clid=; device_id=unknown; uuid=unknown') .then(async () => < // Последняя проигрываемая очередь всегда в начале списка const currentQueue = await client.queues.getQueueById(result.queues[0].id); const = currentQueue.result; const currentTrackId = tracks[currentIndex ?? 0]; const currentTrack = (await client.tracks.getTracks(:$`]>)).result[0]; const supplement = await client.tracks.getTrackSupplement(currentTrack.id); console.log(JSON.stringify(supplement.result.lyrics.fullLyrics, null, 2)); >)Хоть для радио и создаётся очередь — получить текущий трек не получится. В этой очереди нет треков, так как треки для радио генерируются динамически. Поэтому если вы продолжите слушать радио на другом устройстве, воспроизведение начнётся совсем с другого трека.
Скачивание трека
Никому не было бы интересно API, если бы не могли скачивать музыку, ведь это самое главное.
Если вы используете библиотеку yandex-music-client, то для скачивания трека достаточно знать его id и использовать метод getTrackUrl. Но под капотом скачивание происходит вот так:

Swagger и CORS
Совсем забыл упомянуть очень важную вещь, вы не сможете просто взять и написать веб приложение с помощью моего API. Дело в том, что Яндекс запрещает выполнение кросс доменных запросов.
В своём проекте с OpenAPI схемой я обхожу это ограничение с помощью proxy-сервера на NodeJS, но в этом случае некоторые запросы могут не работать из-за того, что proxy-server не находится в России.

Если вы собираетесь писать своё приложение, в котором будет присутствовать бэкенд — то вы просто можете просто использовать yandex-music-client на бэке и, таким образом, не будет никаких проблем с крос-доменными запросами (но помните, что некоторые методы не доступны вне СНГ). Если вы пишите консольное приложение, телеграмм бота или мобильное приложение — то никаких проблем не будет, ведь CORS существует лишь в браузере.
Разработка VS Code расширения
Теперь, когда у нас есть API для Яндекс Музыки, мы можем всё это дело интегрировать в VS Code. Я не буду описывать всё очень подробно, поэтому, если вам интересна базовая структура расширений VS Code, можете почитать о ней здесь.
Но есть одна из главных вещей, которую необходимо понимать. VS Code — обычное NodeJS приложение, поэтому вы можете использовать совершенно любые библиотеки, которые вы привыкли использовать, будь то axios для выполнения запросов или MobX для управления состоянием.
Основные компоненты
Ниже описаны основные компоненты, которые необходимы для разработки расширения.

Создание большинства компонентов начинается с добавления так называемых contribution points. Все они описываются в package.json в поле contributes.

Именно здесь необходимо определять:
- Команды — что-то вроде обработчиков событий (contributes/commands)
- Настройки вашего расширения (contributes/configuration)
- Боковые панели и их содержимое (contributes/viewsContainers, contributes/views)
- Горячие клавиши (contributes/keybindings)
- Экшены для узлов дерева и контекстное меню (contributes/menus)
Чтобы было более понятно как работать с компонентами, давайте рассмотрим пару примеров.
TreeView
Большая часть расширения представляет собой деревья с плейлистами, альбомами и треками. Прежде чем создать TreeView, необходимо определить соответствующий contribution point в package.json.

Здесь мы определяем 4 дерева, которые будут использоваться в расширении:
Далее для каждого дерева нужно определить data provider, который будет решать какие узлы необходимо отобразить в дереве. Для простоты возьмём дерево, отображающее Чарт.
// Провайдер для Чарта Я.Музыки export class ChartTree implements vscode.TreeDataProvider < constructor(private store: Store) < >getChildren(): vscode.ProviderResult< // Каждый трек чарта рендерится как отдельный узел в дереве return this.store.getChart().then((items) => < return items.map((item) =>new ChartTreeItem(this.store, item, CHART_TRACKS_PLAYLIST_ID)); >); > > const api = new YandexMusicApi(); const store = new Store(api); // Создание провайдера const chartProvider = new ChartTree(store); // Создание дерева, объявленного во вью "yandex-music-chart" с провайдером chartProvider vscode.window.createTreeView("yandex-music-chart", < treeDataProvider: chartProvider >); Код немного упрощён, полную версию можно посмотреть тут и тут.
Диалог подтверждения
В VS Code есть альтернатива привычных нам alert/confirm, которые существуют в браузере (и которыми мы обычно не пользуемся) — window.showInformationMessage. Первым аргументом вы указываете сообщение, а затем передаёте сколько угодно кнопок.
export async function showPrompt(title: string): Promise

Хранение паролей и настроек
VS Code предоставляет 2 возможности хранения данных, обе схожи с localStorage:
- WorkspaceConfiguration
- и SecretStorage
Так как нам необходимо хранить пароли, то первый вариант нам не подходит. Все настройки хранятся в общем файле settings.json и доступны для любого расширения. Это именно те настройки VS Code, которые вы изменяете, чтобы настроить размер шрифта или темы.

Мы же собираемся хранить токен авторизации, поэтому важно использовать именно второй вариант — SecretStorage. Хранится SecretStorage в контексте нашего расширения, который передаётся в метод activate, выполняющийся при запуске расширения. API такой же простой, как и API localStorage в браузере.

Очень просто и понятно оба способа хранения настроек описаны в статье SecretStorage VSCode extension API. В ней же описывается тот же подход с реализацией класс-синглтона для настроек, который я использую в расширении.
Воспроизведение музыки
Предыстория
Мы разобрались с получением и отображением треков и находимся на финишной прямой, теперь осталось самое главное — воспроизвести их. Кажется, что всё довольно просто — VS Code работает на электроне, значит мы легко сможем воспроизвести музыку, так же как и в браузере. Всё так, да немного не так, немного погуглив, я наткнулся на гитхаб ишью.

В этом ишью есть две новости:
- плохая — нельзя просто взять и воспроизвести музыку
- хорошая — можно использовать любой nodejs пакет, в том числе для проигрывания музыки.
После долгих поисков подходящего npm-пакета я нахожу play-sound. Но после недолгого использования я сразу же понимаю, что использовать этот пакет просто невозможно:
- он не умеет ничего кроме воспроизведения музыки, а значит перемотка, регулировка звука и всё остальное — ложится на ваши плечи
- К тому же нельзя узнать закончился ли трек, чтобы включить следующий
Далее, я нахожу mplayer — обёртку для MPlayer, которая поддерживает все данные функции. Кажется, что всё гораздо лучше — но нет, через некоторое время использования я понимаю, что работает он ужасно:
- Следующий трек воспроизводится с задержкой (библиотека не умеет в потоковое скачивание, поэтому трек необходимо полностью скачать, из-за чего происходит задержка)
- Перемотка работает очень плохо, всё постоянно заедает
- Из мелочей — у библиотеки нет тайпингов, их приходится писать руками
Тут я понимаю, что расширение vscode для командной разработки поддерживает голосовые звонки, а значит поддерживает воспроизведение аудио внутри vscode. Очевидно, я решил заглянуть под капот этого расширения.
Под капотом Microsoft Live Share Audio
Все расширения в vscode находятся в /Users//.vscode/extensions и представляют собой обычное JavaScript приложение, где есть package.json и набор js файлов, которые можно изучать и даже дебажить. Интересующее нас расширение находится в папке ms-vsliveshare.vsliveshare-audio-0.1.93

Как дебажить сторонние VS Code расширения
На самом деле — всё очень просто. Открываете папку с нужным расширением в Vs Code, затем нажимаете F5 и выбираете “VS Code Extension Development” — готово.


Немного подебажив исходники, несложно заметить, что расширение под капотом использует electron для совершения звонков с помощью Skype API. Для этого достаточно открыть файл ExternalAppCallingService — в котором одноимённый класс отвечает за запуск электрона.

- ./out/calling/externalApp/dist — путь к электрон приложению, с помощью которого будут осуществляться голосовые звонки
- При запуске электрона необходимо удалить переменные, которые устанавливает VS Code, чтобы запускаться в качестве NodeJS процесса. Нам не нужно, чтобы электрон запускался как NodeJS процесс, поэтому эти переменные нужно удалить, подробнее можно посмотреть вот в этом ишью.
- Непосредственный запуск электрона.
Этот код показывает, как правильно запускать electron в качестве дочернего процесса vscode — это то, что нам нужно. Получается, чтобы воспроизвести музыку, нам нужно запустить электрон из электрона (VS Code тот же электрон).

Также если покопаться, можно заметить, что электрон скачивается в рантайме только один раз при первом запуске расширения, но к этому мы ещё вернемся.
Архитектура Electron
Теперь мы умеем запускать электрон — круто, теперь нам необходимо научиться воспроизводить треки, а для этого нужно понимать его архитектуру.
Процесс электрона состоит из 2-х частей:

- main — главная часть, в которой есть доступ к нативному API
- renderer — часть в которой рендерится web-страница
Взаимодействуют эти части с помощью межпроцессовых каналов коммуникации (inter process communication (IPC) channels) — ipcMain и ipcRenderer. По названиям очевидно, что:
- Внутри main-процесса нужно использовать ipcMain
- А внутри renderer-процесса — ipcRenderer (либо напрямую — небезопасно, либо через contextBridge — безопасно)
Оба канала могут как отправлять, так и получать сообщения.
Подробнее об архитектуре Electron можно почитать здесь, а о IPC-каналах здесь.
Воспроизведение трека
Для воспроизведения будем использоваться обычное Audio-API, поэтому здесь всё просто. Самая интересная часть — передача трека, который мы хотим воспроизвести, от VS Code в Renderer-процесс электрона. Передавать мы будем пейлоад следующего типа:
export interface IPlayPayload
Чтобы понять как это реализовать — давайте взглянем на диаграмму, сейчас нас интересуют лишь зелёные стрелки, начало процесса в VS Code extension ⇒ Store.

Всё ещё сложнее, когда нужно воспроизвести следующий, трек, когда предыдущий завершился. В этом случае — нужно преодолеть целый круг:
- От Audio до Store, чтобы оповестить Store, что трек завершился
- От Store до Audio, чтобы воспроизвести следующий трек
При передаче данных от VS Code extension до Electron Process — необходимо их сериализовать в JSON, потому что между процессами мы не можем передавать JavaScript объекты.
play(trackinfo?: IPlayPayload) < this.childProcess?.send(JSON.stringify(< command: "play", payload: trackinfo >)); >Загрузка Electron в рантайме
Кажется можно уже радоваться, всё прекрасно работает, треки крутятся, а звёзды на гитхабе мутятся (нет!), но начали появляться ишью на гитхабе для мака и линукса.
Изначально, я просто добавил electron, как зависимость к проекту и всё работало хорошо. Как оказалось, нужная версия электрона скачивается при установке npm пакетов, а я работал на винде и соответственно, расширение работало только на винде.
Снова покопавшись в Live Share Audio, я обнаружил, что расширение cкачивает нужную версию электрона в рантайме с собственных серверов.



Мне не хотелось хостить электрон для всевозможных версий, как это сделано в Live Share Audio, из-за чего приостановил работу над расширением.
Мне не хотелось хостить электрон для всевозможных версий, как это сделано в Live Share Audio, из-за чего приостановил работу над расширением.
Через некоторое время я понял, что если electron устанавливает необходимые бинарники в рантайме, то код скачивания должен быть где-то в их репозитории. Немного покопавшись, я нашёл пакет electron/get — именно он используется под капотом, когда вы устанавливаете электрон в зависимости. Также я нашёл почти готовый скрипт для установки нужной версии электрона в рантайме.
Итог
На этом всё. Спасибо, если смогли дочитать до самого конца, я думаю таких не много, статья получилась достаточно длинной. Если у вас есть какие-либо вопросы или предложения — обязательно пишите в личку или в комментариях. Буду признателен, если сможете поддержать проект любым способом:
- Идеями в комментариях к статье или в ишью на гитхабе
- Звёздочками на гитхабе
- Отзывами в магазине расширений
- Подпиской на мой телеграмм канал, где я рассказываю о программировании
«Яндекс.Музыка»: зачем они так сделали?
В начале года я уже писал о том, как меня неприятно поразил сервис «СберЗвук». А в серии статей «Импортозамещение поневоле» перебирал вообще все аудиостриминговые сервисы. Поиск замены для ушедшего из России Spotify лично для меня завершился переходом на «Яндекс.Музыку» — во многом по причине того, что у них было совместное предложение с «МегаФоном», подразумевавшее, что можно оформить «льготную» подписку. Ага, льготную в кавычках, по той причине, что мне не попадалось других предложений, кроме как льготным образом начать пользоваться этим сервисом. Полную цену с первого месяца вы начнете платить ровно в одном случае: если ваш аккаунт уже был когда-то привязан к данному сервису «Яндекса». Но ничто не помешает вам создать новый и получить все то же льготное предложение. Никакой проверки устройств, личностей и прочего у «Яндекса» нет, так что можно все время участвовать в каких-то льготных акциях, которые предлагаются свежеподключившимся. И это приводит к первому вопросу: что помешало сделать нормальную систему аккаунтов?
Аккаунты
Нет, меня как пользователя не заботит, что в руководстве «Яндекса» никто не подумал о том, что рост базы пользователей — это вещь в себе. Пользователю, в общем-то, все равно, что компания хвастается миллионами пользователей, тогда как на самом деле у одного человека может быть хоть десяток аккаунтов. Но не считать это проблемой на уровне оценки собственной доли на рынке — это странно. Более того, не совсем понятно, в чем смысл бесконечного предоставления пользователям возможности создавать новые подключения к сервису при одновременном вводе искусственных ограничений по числу устройств, на которых можно запустить ваш сервис. Это какая-то откровенная ерунда.

Конечно, с переходом подписки на «Яндекс+» количество устройств выросло до 10, так что актуальность вопроса резко снизилась. Но все же — где логика? Если компания опасается того, что кто-то будет экономить деньги, пользуясь одним аккаунтом на десяток разных человек, то почему ее не заботит, что один человек может сделать десяток аккаунтов, чтобы получить льготный период? Как показывает мировой опыт, единственный способ помешать людям делиться своим аккаунтом с друзьями и родственниками — это сделать сервис настолько доступным по цене, чтобы такие махинации просто были лишены смысла. Но вот запретить на одном устройстве подключать один сервис с разных аккаунтов или ввести какую-то другую проверку уникальности достаточно просто.
Кстати, из возможности регистрации множества аккаунтов в «Яндекс.Музыке» следует и еще один плохо продуманный элемент. В момент, когда у вас закончился оплаченный период, приложение просто показывает экран с предложением попробовать сервис. Этот экран ничем не отличается от того, который появится, если вас разлогинит или же вы выберете аккаунт, где сервис не подключен. Дальше вы сами должны вспомнить, какой аккаунт вы используете для «Яндекс.Музыки», то есть на каком вы платите за него. И это снова возвращает нас к вопросу: зачем нужно было делать так с оплатой?
Оплата
Я ничего не буду говорить о том, дорого или дешево обходится «Яндекс.Музыка», цены на рынке у всех стриминговых сервисов примерно одинаковые, так что тут есть три варианта: вы не пользуетесь стриминговым сервисом и пиратите, вы не пользуетесь стриминговым сервисом и покупаете контент где-то еще или вы пользуетесь стриминговым сервисом. Поэтому давайте просто посмотрим, как реализована оплата у «Яндекса». На первый взгляд все вроде бы неплохо: цена в рынке, способов вносить плату много. Но выше я уже написал, что происходит, когда оплаченный период закончился, а у вас нет автоматического продления или на счете, к которому он привязан, нет средств.

Полагаю, что я далеко не единственный человек в мире, который не доверяет сервисам с автоматическим списанием средств. Я стараюсь либо вообще отключить подобную опцию, либо привязать ее к счету, на котором не хранится никаких денег, он лишь пополняется по мере необходимости. Неприятный опыт ошибочных списаний и списаний за сервис, которым я фактически перестал пользоваться, подсказывает, что так спокойнее и лучше для бюджета. Но в случае с «Яндексом» это ведет к тому, что я постоянно вижу предложение начать пользоваться сервисом. Пока приложение не было принудительно переведено на систему «Плюс мульти», выяснить, откуда и как списывается плата, вообще не получалось. Сейчас узнать о том, что там с вашей оплатой и как списываются средства, можно, но лишь в случае, если сервис активен. Если средства закончились… увы, только обязательно пополнив счет прежним способом. Если он вам почему-то недоступен — создавайте новый аккаунт, и вперед.