Spotify на Яндекс Станции Лайт играет. Колонка появилась в списке устройств Spotify Connect на телефоне, музыка идёт из её динамика, а Алиса спокойно отвечает поверх песни и не замолкает. «Алиса, включи спотифай» тоже работает. Работает это на официальном клиенте Spotify — Soloist, который на эту колонку не рассчитан ни по библиотекам, ни по звуку. Чтобы он запустился, пришлось собрать ему маленький Debian в отдельной папке и обойти три препятствия, каждое из которых сначала выглядело как что-то другое.
Сразу о статусе. Автозапуск готов и проверен двумя перезагрузками: колонка сама возвращается в домашний Wi-Fi, Spotify поднимается без рук. Но не мгновенно — после включения проходит несколько минут, потому что первый вход в аккаунт обычно срывается и скрипт-супервизор повторяет его сам. Остаётся одно обязательство: раз в 90 дней менять сам клиент.
Зачем Spotify на Яндекс Станции, где уже есть Яндекс Музыка
Это вторая серия истории про одну колонку. В первой части мы получили root на Станции Лайт первого поколения и научили её отвечать головой нашего ИИ-агента Мии на фразу «Алиса, спроси нейросеть». Закончилось всё около часа ночи, и ноутбук, казалось, можно было закрывать.
Закрыть не получилось. Раз колонка теперь своя, захотелось, чтобы она играла не только Яндекс Музыку. Нужен был Spotify Connect: открываешь Spotify на телефоне, выбираешь колонку в списке устройств, и музыка идёт из неё, а телефон работает пультом. Spotify Connect Станция из коробки не поддерживает, ей и не положено.
Пациент тот же: Яндекс Станция Лайт, модель YNDX-00025, внутри процессор Cortex-A53, 244 МБ оперативной памяти и Linux на ядре 4.9. Ядро у неё 64-битное, а все программы 32-битные, системная библиотека glibc — версии 2.30. Эти цифры ещё не раз всплывут, потому что всё дальнейшее упиралось именно в них.
Первая попытка: librespot, который пролистывает треки
Сообщество давно решает эту задачу через librespot — открытую реализацию Spotify Connect. Для Станций Лайт и Мини есть готовый установщик, и мы начали с него.
Установщик сначала отказался работать: на нашей прошивке нет каталога /usr/local/bin, куда он кладёт свою команду. Каталог создали, и дальше всё прошло гладко. Колонка появилась в Spotify, приложение её выбирало, а потом начиналось странное: треки пролистывались один за другим, и ни один не звучал. В логе на каждую песню повторялась одна и та же строка: Unable to load key. Ключ расшифровки получить не удалось, трек пропущен.
До колонки, динамика и звука дело просто не доходило: без ключа расшифровки трек не играется. Причину нашли не у себя. Разработчик librespot 7 ноября 2026 года написал в issue #1649: воспроизведение сломано для аккаунтов, созданных после определённой даты, примерно в 2024–2025 годах. По его словам, проблема есть во всех версиях librespot и обходного пути нет, потому что официальные клиенты получают ключи по другой, защищённой схеме.
Похоже, наш аккаунт из тех самых. librespot сняли с колонки целиком, вместе с каталогом, который создавали под установщик.
Soloist: официальный клиент, который здесь не встаёт
У Spotify с августа 2026 года есть собственный ответ на эту задачу. Spotify Soloist — официальный «безголовый» клиент Spotify Connect для Linux: без экрана и интерфейса, только устройство в списке приложения. Для запуска нужен API-ключ, который выпускается на Premium-аккаунте. Сборки живут ограниченное время: наша сообщила при старте, что истекает через 88 дней. Раз в квартал программу придётся менять на свежую.
Есть и сборка под 32-битный ARM, то есть под наш процессор. Мы скачали её с официального сервера Spotify, и выяснилось, что напрямую на колонку она не встанет. Мешали две вещи.
Первая — системная библиотека. Soloist собран под glibc 2.38, а на колонке 2.30. Это как приложение, которому нужна свежая версия Android: на старой оно просто не откроется.
Вторая — звук. На Linux Soloist выводит звук только через звуковые серверы PulseAudio или PipeWire. На колонке нет ни того, ни другого, там голый ALSA — самый нижний уровень звука в Linux, через который говорит Алиса.
Обновить систему колонки нельзя, да и не нужно: прошивка Яндекса держит всё остальное, включая Алису и мост Мии. Поэтому решили поселить рядом с ней отдельный мини-мир.
Свой Debian в отдельной папке
Идея простая, хотя на 244 МБ памяти выглядит дерзко. Берём из Debian 13 (trixie) для 32-битного ARM свежую glibc 2.41, PulseAudio 17 и всё, что им нужно, и кладём в отдельную папку на колонке. Soloist запускаем не напрямую, а через загрузчик из этой папки и указываем ему путь к нашим библиотекам.
Можно было пойти коротким путём и прописать путь к новым библиотекам в переменной LD_LIBRARY_PATH для системных служб. Но тогда их подхватили бы и программы Яндекса, собранные под старую glibc, и колонка, скорее всего, перестала бы работать целиком. Поэтому системную библиотеку прошивки мы не заменяли: новые библиотеки лежат отдельно и нужны только Soloist и PulseAudio.
Собирали на ноутбуке. Скачали 129 пакетов Debian и сверили каждый с контрольной суммой из официального индекса. По спискам зависимостей отобрали ровно 38 библиотек, без локалей, документации и прочего балласта. Комплект вышел на 41 МБ при 57 свободных на разделе. Тесно, но влезло.
Под своим загрузчиком Soloist ответил версией 1.3.10, PulseAudio — версией 17.0. Первый шаг пройден. Дальше начались препятствия, которых мы не ждали.
Стена первая: звук, который не открывается
PulseAudio из Debian должен был сам выводить звук в ALSA колонки. Вместо этого он падал на первом же обращении к звуковой карте с ошибкой SNDRV_PCM_IOCTL_SYNC_PTR failed (-25).
Разгадка в возрасте ядра. Свежие 32-битные сборки Debian перешли на 64-битное время. Это защита от «проблемы 2038 года», когда 32-битный счётчик секунд переполнится. Наша звуковая библиотека из Debian попросила ядро о том же действии новым вариантом команды, с 64-битным временем, а ядро 4.9 такого варианта не знает и отвечает «не понимаю». Ядро обновить нельзя — оно часть прошивки.
Выход нашли в обход. PulseAudio больше не ходит в звуковую карту сам, а складывает готовый звук в именованный канал (FIFO), что-то вроде трубы между программами. С другого конца трубу читает родной проигрыватель колонки aplay со старой системной библиотекой, которая с ядром прекрасно ладит. Так оба источника звука, музыка и Алиса, попадают в один и тот же микшер dmix. Позже мы проверили, что Алису слышно поверх музыки, — но до этого было ещё далеко, и первая версия этой схемы закончилась тем, что звук завис у всех.
Стена вторая: колонка кричала не в ту сеть
Дальше нужен был ключ Soloist. Я выпустил его на сайте Spotify для разработчиков и положил в файл, откуда ключ уехал на колонку с правами только для root. Soloist запустился и отчитался, что объявил себя в сети. Телефон колонку не увидел.
Устройства Spotify Connect находят друг друга через mDNS: кто-то спрашивает «кто здесь умеет играть?», устройства отвечают. Проверка с ноутбука показала, что на один тип адресного запроса Soloist отвечает, а на обычный групповой вопрос в домашней сети ответа нет. Оказалось, у Станции есть служебный интерфейс Wi-Fi Direct p2p0 со служебным адресом вида 169.254.x.x. Первым в списке адресов Soloist видел именно его — похоже, из-за этого ответы и не попадали в домашнюю сеть.
Адрес с p2p0 сняли, Soloist перезапустили, и телефон сразу постучался к колонке. Это временная мера: после перезагрузки адрес вернётся. Постоянное решение ещё предстоит выбрать, потому что зачем этот интерфейс нужен самому Яндексу, мы пока не выяснили.
Стена третья: колонка видна, но подключиться нельзя
Колонка появилась в Spotify на телефоне. А потом ничего: телефон пытался подключиться и не мог. Встроенный веб-сервер Soloist, через который телефон передаёт сессию, принимал соединения в очередь и не обрабатывал ни одного. Главный поток программы при этом всё время был занят и жёг процессор, причём только в режиме ядра, как будто непрерывно просил систему о чём-то и не получал ответа.
Подсказку дал системный журнал: ядро на каждом витке жаловалось, что поток SoloistRunner M использует «устаревшую инструкцию барьера CP15». Мы разобрали машинный код по этому адресу и нашли цикл, который пытается атомарно поменять один байт. В процессорах ARM это делается парой инструкций: первая ставит на ячейку памяти невидимую отметку «я её читаю», вторая записывает новое значение, только если отметка ещё на месте. Между ними в коде Soloist стоит барьер памяти, записанный по-старому, в стиле 32-битных процессоров ARMv7.
В исходной настройке колонки ядро такой барьер не отдавало процессору, а перехватывало и выполняло само. Похоже, при этом перехвате отметка и сбрасывается: получается замкнутый круг, где программа ставит отметку, барьер её стирает, запись отказывается, программа начинает заново. Бесконечно.
Проверили это сменой режима: echo 2 > /proc/sys/abi/cp15_barrier. Строка говорит ядру больше не перехватывать старые барьеры, а дать процессору исполнить их самому — Cortex-A53 это умеет. После перезапуска Soloist главный поток наконец уснул в ожидании, как и положено, а веб-сервер колонки стал отвечать на запросы за 40–130 миллисекунд. Настройка действует до перезагрузки, поэтому в скрипте автозапуска она стоит одной из первых.
Оговорка важная: зависание ушло и ответы появились — это мы видели своими глазами. А вот механизм со сброшенной отметкой остаётся нашим предположением, и ровно так мы его и описали, когда отправляли находку в Spotify.
Найти такое по симптому «колонка видна, но не подключается» почти невозможно. Это тот самый случай, когда очевидные подозреваемые — сеть, ключ, Spotify — ни при чём.
После третьей стены в логе Soloist появилась строка, ради которой всё затевалось: телефон вошёл, ключ получен, играет «La clé des champs» группы NTO. Spotify-часть работала. Ключ расшифровки, которого librespot на этом аккаунте не дождался, официальный клиент получил без вопросов.
Из динамика при этом не было слышно ничего.
Как мы оставили колонку без голоса
Тут у истории наступает неприятная часть, но без неё рассказ был бы нечестным.
Первая схема звука была самой простой: aplay всё время читает трубу от PulseAudio, есть музыка или нет. Сначала его убило закрытие сеанса отладки: при запуске из командной строки процесс умирал вместе с ней. Потом оказалось, что звук не идёт уже ни у кого. Общий выход звуковой карты завис в состоянии «подготовлен, но не запущен», и вместе с музыкой замолчала Алиса. Вернуть звук без перезагрузки не получилось.
Перезагрузка вернула звук и тут же отняла домашний Wi-Fi. При загрузке Яндекс переписывает конфигурацию сети из своей базы, а домашней сети, которую мы добавили вручную, в этой базе не было. Домашняя сеть из списка пропала совсем, зато в нём осталась раздача с ноутбука, через которую колонка когда-то получала root. Без интернета Алиса так и говорила: «нет интернета». Нашли колонку, включив ту самую раздачу, а домашнюю сеть закрепили отдельным маленьким скриптом: он раз в минуту проверяет список сетей и, если домашней там нет, возвращает её. После перезагрузки на это уходит около полутора минут, всё это время Алиса честно говорит, что интернета нет.
Почему завис звук, мы, честно говоря, до конца не знаем. Первое объяснение — «наш aplay стал главным в микшере и умер, оставив его без хозяина» — не подтвердилось: по исходникам звуковой библиотеки такого режима на этом ядре нет. Рабочая гипотеза, к которой пришли вместе со вторым мнением Codex, такая: процесс умер посреди восстановления после сбоя, ровно между «подготовить» и «запустить», и общий выход так и остался подготовленным. Это гипотеза, не доказательство.
Раз причина не установлена, дальше мы шли от осторожности: посторонний процесс не должен держать общий звуковой выход дольше, чем нужно, и не должен умирать на полуслове.
Сторож, который пускает звук только на время музыки
Новая схема держится на маленьком скрипте-стороже. Он читает журнал Soloist. Как только там появляется «играет», сторож запускает aplay. Когда приходит «пауза» или телефон переключился на другое устройство, сторож ждёт пять секунд и вежливо останавливает проигрыватель сигналом, после которого тот сам закрывает звуковую карту. Никакого принудительного убийства процесса.
Проверяли по протоколу, с заранее записанными стоп-критериями: если замолчит Алиса или выход звука перестанет двигаться, сначала снимаем диагностику, потом спасаем колонку. Я слушал. Сначала секунда тишины через системный aplay: выход запустился и чисто закрылся. Потом тихая музыка и Алиса поверх неё — обе слышны. Пауза — проигрыватель остановлен, выход закрыт, Алиса говорит одна. Снова play — музыка вернулась. За всю проверку звук не завис ни разу.
По пути вылезла ещё одна ловушка. Soloist кэширует музыку, и за пять минут прослушивания кэш вырос до 15 МБ. На разделе, где он лежал, оставалось 13,8 МБ, а там же живут данные Яндекса, настройки Wi-Fi и мост Мии. Ещё немного, и колонка упёрлась бы в полный диск в самом неудобном месте. Кэш перенесли в оперативную память с жёстким лимитом 12 МБ и отдельно проверили, что будет, когда кончатся и они. Проверка заняла около десяти минут: кэш заполнился почти под завязку, после этого сменились два трека, и ни одной ошибки в журнале не появилось.
Сколько памяти Spotify занимает на Яндекс Станции Лайт
Замеры во время игры такие: Soloist занимает около 50 МБ памяти, PulseAudio — 3,5 МБ, aplay — 1,7 МБ. Системе при этом остаётся доступно 68–70 МБ из 244, а когда кэш в оперативной памяти заполнился — около 60 МБ. Порогом, ниже которого мы договорились всё сворачивать, было 40. Процессор Soloist загружает примерно на 4 %. Мост Мии всё это время отвечал нормально.
Для колонки, которая проектировалась под одну Алису, запас в короткой проверке оставался выше нашего порога. Как оно поведёт себя за несколько часов музыки, мы пока не знаем: долгого теста не было.
Автозапуск: колонка поднимает Spotify сама
Последний шаг — сделать так, чтобы после выключения из розетки всё возвращалось без ноутбука. Скрипт-супервизор по порядку дожидается сети, снимает адрес с p2p0, переключает режим барьеров, поднимает кэш в оперативной памяти, затем звук, Soloist и сторожа. Если клиент падает, супервизор его поднимает; если сборка истекла — не трогает, бесконечно перезапускать бессмысленно.
Проверили двумя перезагрузками. Колонка сама вернулась в домашний Wi-Fi, Spotify появился в списке устройств, мост Мии и блокировка обновлений не пострадали.
Одна честная деталь: первый вход в аккаунт Spotify после загрузки обычно не проходит. В первый раз причина была понятной — часы колонки ещё стояли на 1970 годе, а с таким временем не проверить сертификаты. Во второй раз сеть, часы и DNS были уже в порядке, а вход всё равно сорвался, и почему — мы не знаем. Супервизор ловит это сам и повторяет попытку, так что на второй перезагрузке Spotify был готов минуты через три-четыре после включения. Повтор мы потом ускорили — что из этого вышло, ниже, в разделе про установщик.
Голосом: «Алиса, включи спотифай»
Телефон-пульт — это хорошо, но колонка с Алисой, которую нельзя попросить голосом, выглядит недоделанной. Теперь можно. Три фразы: «Алиса, включи спотифай» продолжает то, что играло последним, «Алиса, пауза в спотифай» ставит паузу, «Алиса, следующий трек в спотифай» переключает песню. Без слова «спотифай» всё по-прежнему уходит Яндексу: «Алиса, пауза» остановит Яндекс Музыку, а не Spotify.
Устроено это на мосте из первой части. Правило в Quasar Bridge замечает в распознанной фразе «спотиф» и отдаёт её не Яндексу, а голосовой Мие — та коротко подтверждает вслух. Одновременно маленький наблюдатель на колонке видит в журнале моста, что запрос ушёл Мие, и даёт Soloist команду: играть, пауза или дальше. Журнал фраз живёт только в оперативной памяти колонки, а сам наблюдатель текст фраз никуда не записывает.
Почему так окольно, а не через инструменты агента напрямую: наш агент на сервере выполняет инструменты у себя и не возвращает вызов обратно на колонку. До Soloist он дотянуться не может, а наблюдатель на самой колонке — может.
Проверено голосом. Ограничение одно, но заметное: попросить конкретного исполнителя или песню нельзя. У Soloist нет поиска, для этого нужен отдельный Web API Spotify. Переживает ли голосовое управление перезагрузку, отдельно не проверяли; наблюдатель стартует вместе с Soloist, так что должно.
Громкость: музыка следует за Алисой
У Soloist своя громкость, по умолчанию 40 из 100, то есть музыка стартует на половине. А кнопки на колонке и «Алиса, громче» до неё не дотягиваются. Алиса хранит свой уровень по шкале от 0 до 20 в отдельном файле и применяет его только к своему плееру, общий регулятор звука при этом не трогает. Soloist просто не узнаёт, что громкость поменялась: голос Алисы становится тише или громче, а музыка играет как играла.
Поэтому в комплекте есть маленький скрипт синхронизации. Раз в секунду он читает уровень Алисы и передаёт его Soloist, пересчитывая шкалу: 15 из 20 у Алисы становятся 75 из 100 у Spotify. Беззвучный режим Алисы глушит и музыку. Soloist стартует сразу с громкостью Алисы, а не со своих 40. Регулятор в приложении Spotify тоже работает, но только до следующей смены громкости Алисы — кнопкой или голосом. Кому синхронизация не нужна, выключает её одной строкой в файле настроек.
Проверено тремя тестами, каждый из которых без этого скрипта падает, и на самой колонке: Soloist запустился на 75 при Алисе на 15, после перезагрузки служба поднялась сама, а в журнале колонки видно, как Алиса на 17 превращается в 85 у Spotify. Кнопки и голос я проверил сам — музыка меняется вместе с Алисой.
Установщик: чтобы это можно было повторить
Всё описанное выше делалось руками, команда за командой. Работало, но повторить по описанию было нельзя: второе мнение Codex прямо назвало такой рецепт невоспроизводимым и заодно нашло дефекты в скриптах. Поэтому ручную работу превратили в установщик.
Он из двух частей. Первая — сборщик на компьютере: одна команда на Python без сторонних зависимостей, работает на Windows, Linux и macOS, Docker не нужен. Он скачивает индекс Debian 13, сам считает зависимости, скачивает около 130 пакетов и сверяет каждый по контрольной сумме, отбирает 36 нужных библиотек и забирает Soloist с сервера Spotify. Комплект на 39,6 МБ собирается примерно за минуту. Если какой-то библиотеки не хватает, сборщик останавливается с ошибкой, а не собирает молча битый комплект. Самого Soloist в установщике нет: Spotify прямо запрещает распространять его архивы и бинарники, поэтому сборщик скачивает его у каждого пользователя сам.
Вторая часть ставит комплект на колонку по ADB, тоже одной командой. Места на колонке впритык — около 28 МБ свободно при комплекте на 40, — поэтому неизменённые файлы не копируются заново, а связываются жёсткими ссылками. Если после остановки старой версии что-то пошло не так, установщик возвращает всё как было. А если вернуть не вышло, так и пишет, вместо того чтобы рапортовать об успехе. На нашей колонке из 51 файла 39 совпали побайтно, скопировать пришлось 12 — всего 208 КБ. После перезагрузки Spotify вошёл в аккаунт с первой попытки, примерно через две минуты после включения. Пока это одна перезагрузка.
По дороге исправили ошибки в скриптах колонки, которые при ручной работе просто не всплыли. Если кэш в оперативной памяти не смонтировался, Soloist теперь не стартует: иначе минимум 100 МБ кэша ушли бы в общую оперативку колонки, где всего 244 МБ. Без PulseAudio он тоже не стартует. С p2p0 снимается только служебный адрес 169.254.x.x, а не любой. Режим барьеров CP15 работает по принципу «закрыто по умолчанию»: не удалось включить — не стартуем, чтобы не попасть в вечный цикл, а при остановке возвращается исходное значение. Фраза со словом «спотифай», но без понятной команды, больше не включает музыку. Строки вывода Soloist, где встречается ключ, в журнал не попадают. Имя колонки, интерфейсы и размер кэша вынесены в файл настроек.
Проверяли так, чтобы тестам можно было верить. Скрипты колонки прогнали 29 тестами под busybox — той же урезанной оболочкой, что стоит на колонке, — сборщик ещё 17 тестами. Потом каждое из 20 исправлений по очереди откатывали и смотрели, покраснеет ли его тест. Краснел каждый раз: значит, тесты ловят именно эти ошибки, а не просто зеленеют. Одно замечание Codex — про «зомби»-процессы aplay — не воспроизвелось, и его не стали записывать в исправленные. Заодно тесты поймали пять ошибок самого Claude, который писал скрипты, — например, наблюдатель голоса не останавливался вместе со службой.
А три вещи нашла только живая колонка, в тестах с заглушками их не было видно. adb под Windows отдаёт концы строк как \r\r\n, и разбор ответа ломался. adb на колонке молча отбрасывает команду длиннее примерно 4 КБ. И фоновый процесс, запущенный через adb, погибал: сеанс закрывался раньше, чем процесс успевал отделиться, — помогла пауза в две секунды.
Сам установщик лежит в открытом репозитории yandex-station-lite-spotify под лицензией MIT. В нём сборщик комплекта, установка по ADB с откатом, скрипты колонки вместе с синхронизацией громкости и голосовыми командами, тесты и README на русском с коротким абзацем на английском. Soloist и ключа там нет: сборщик скачивает клиент с сервера Spotify у каждого пользователя.
Из того же репозитория — схема того, что в итоге работает на колонке:
Рецепт с установщиком мы предложили и в вики сообщества hackalice.me — PR в репозитории yandex-station-extended ждёт решения мейнтейнеров. После новой установки проверили и звук на слух, и голосовые команды — всё работает. А вот на чистой колонке установка проверена только тестами: на нашей не хватило бы места на вторую полную копию.
Заодно: телеметрия Яндекса
Знакомый спросил простую вещь: а колонка что-нибудь шлёт в Яндекс? Проверили, ничего не меняя, — сделали 40 снимков сетевых соединений за 80 секунд. Колонка ходит на clck.yandex.net, куда уходят логи и продуктовые события, и на report.appmetrica.yandex.net — это сервис аналитики AppMetrica. Плюс постоянный канал самой Алисы, uniproxy.alice.yandex.net, который у нас держит мост. Spotify ходит только в Google Cloud. Это штатная телеметрия прошивки, root на неё никак не влияет.
Что именно уходит, на нашей колонке не видно: всё зашифровано. Но в вики сообщества есть подробный разбор телеметрии, снятый на Станции Миди. По нему в каждом отчёте AppMetrica — серийный номер устройства, модель, версия прошивки и полная строка версии ядра.
Закрыли её способом из той же вики. Точные имена серверов метрик направлены на саму колонку через файл /etc/hosts. Колонка заглядывает в него раньше, чем в свой DNS, поэтому программы Яндекса по этим адресам попадают сами в себя. Закрыто семь имён: clck.yandex.net, report.appmetrica.yandex.net, startup.mobile.yandex.net, startup.appmetrica.yandex.net и их варианты на yango.com. В отличие от скрипта из вики, строки прописаны и для IPv6 — у нас телеметрия шла как раз по нему. Системный раздел открывается на запись только на время правки, копия исходного файла сохранена, откат — одна команда. Канал Алисы, синхронизацию, обновление настроек, Spotify и мост не трогали.
До блокировки за 80 секунд набралось девять соединений с серверами телеметрии, после — ни одного за три минуты. Сами процессы телеметрии не упали и продолжают работать, просто отправить ничего не могут. Очередь неотправленного ограничена: около мегабайта на диске, остальное держится в памяти. Через десять минут после блокировки в памяти копилось 168 КБ, а процессы телеметрии так ни разу и не перезапустились. Алиса и Spotify свои соединения держат, и голосом это тоже проверено: Алиса отвечает, «спроси нейросеть» уходит Мие через мост, Spotify играет.
Одна оговорка. Записи голоса — отдельный канал, ими управляет настройка «Помогать Алисе стать лучше» в Яндекс ID, и блокировка через /etc/hosts их не касается.
Что ещё не готово
Поиск голосом. «Включи Земфиру в спотифай» не сработает: колонка умеет только продолжить, поставить на паузу и переключить трек.
Сборка Soloist истекает примерно 4 февраля 2027 года. Дальше каждые 90 дней — новая версия с официального сервера Spotify. Это единственное, что останется делать руками.
Долгая работа тоже под вопросом: самая длинная проверка заняла около десяти минут музыки. Что будет через три часа, мы не проверяли.
Честно про границы
- Это один эксперимент на одной колонке. Всё описанное проверено на нашей Станции Лайт 1 с усилителем
ntp8910a. В рецептах сообщества для той же модели встречается другой усилитель,tas5825m, то есть аппаратные ревизии различаются. Переносимость нашего решения мы не проверяли. - Нужен root. Вся история стоит на правах администратора из первой части, а это вмешательство в прошивку: колонка может перестать работать, и чем это обернётся для гарантии и восстановления, проверяйте отдельно.
- Готовый файл Soloist раздавать нельзя. Это запрет Spotify, поэтому архива «скачал и поставил» не будет. Клиент берётся только с официальной страницы Spotify для разработчиков, ключ — свой, на свой Premium-аккаунт.
- API-ключ нужен при каждом запуске, и Spotify прямо просит обращаться с ним как с паролем. В статье его, разумеется, нет. Но на колонке он виден в списке процессов: у Soloist 1.3.10 нет другого способа его передать. Посторонних пользователей на колонке нет, поэтому мы это приняли.
- Раз в квартал — обслуживание. Это не поставил и забыл, а подписка на маленькую работу каждые три месяца.
Грабли: коротко для своих
Установщик снимает большую часть ручной работы, но на чистой колонке он проверен только тестами, так что это всё ещё не инструкция «сделай так и заработает». Вот что в нашем эксперименте съело больше всего времени — начните с этих мест.
- Увидели
Unable to load keyи пролистывание треков в librespot — это известная проблема проекта, а не ваша установка. На нашем аккаунте она помешала воспроизведению полностью, обхода разработчик не предлагает. Проверьте librespot до того, как что-то ставить всерьёз. - Soloist требует glibc 2.38 и PulseAudio или PipeWire. На Станции Лайт есть только glibc 2.30 и ALSA, поэтому нужен свой набор библиотек в отдельной папке и запуск через свой загрузчик с
--library-path. Не прописывайте путь к ним системным службам: программы Яндекса собраны под старую библиотеку. - Звуковая библиотека из свежего Debian на ядре 4.9 не открыла звуковую карту:
SYNC_PTRотвечает ENOTTY. У нас сработал вывод из PulseAudio в FIFO, который проигрывает роднойaplayколонки. - Колонка видна, но телефон не подключается, а главный поток занимает процессор — загляните в
dmesg, нет ли там «CP15 Barrier». У нас зависание снялоecho 2 > /proc/sys/abi/cp15_barrier; настройка живёт до перезагрузки. - Телефон не видит колонку — посмотрите, нет ли IPv4-адреса на
p2p0. После того как мы его сняли, обнаружение заработало. - Не держите
aplayоткрытым постоянно и не убивайте его черезkill -9. Мы запускаем его на время воспроизведения и останавливаем через SIGINT. - Запускайте всё через
setsid nohup, иначе процессы умрут вместе с закрытой сессией отладки. - Кэш Soloist растёт быстро: за пять минут музыки 15 МБ. Не держите его на одном разделе с данными Яндекса; нам хватило tmpfs на 12 МБ.
- Не перезагружайте колонку, если домашняя сеть добавлена вручную и не закреплена: Яндекс при загрузке перепишет список сетей из своей базы.
- Если голосовые команды идут через агента на Hermes, помните: запросы с одинаковой первой фразой он склеивает в одну сессию с историей. Наш первый тестовый ответ «не могу включить Спотифай» прилип к фразе «включи спотифай» и повторялся, пока мы не удалили эту сессию.
- Кнопки колонки и «Алиса, громче» меняют только голос Алисы, а не Spotify. Уровень Алисы (0–20) лежит в файле
/data/quasar/data/last_vendor_volume; передавайте его Soloist командойsoloist ctl volume, пересчитав в шкалу 0–100. - Закрываете телеметрию через
/etc/hosts— прописывайте имена и для IPv6 (::1), не только для127.0.0.1. На нашей колонке телеметрия шла по IPv6. - Если ставите с Windows через
adb, учтите три вещи: концы строк в ответе приходят как\r\r\n, команда длиннее примерно 4 КБ молча теряется, а фоновый процесс может погибнуть вместе с закрытым сеансом — дайте ему пару секунд отделиться.
Что дальше
Обе находки на уровне самого Soloist — вечный цикл там, где ядро перехватывает старые барьеры, и ответы не в ту сеть при живом p2p0 — мы описали в официальном репозитории Spotify: issue #32 и issue #33. Механика первой и там названа предполагаемой, а не доказанной. Ответа от Spotify пока нет.
А колонка тем временем перестала быть экспериментом на одну ночь. Её можно выключить из розетки, включить обратно и через несколько минут сказать «Алиса, включи спотифай»: обычная домашняя колонка, которая умеет больше, чем ей положено — слушает Алису, отвечает головой Мии и играет Spotify.
Если вам близка такая самодеятельность с колонками и агентами, заходите в чат: расскажем, где грабли, и покажем, как это звучит вживую.





