Spotify Connect (Станция 2)¶
Станция 2 как устройство Spotify Connect: колонку видно в приложении Spotify, громкость общая с Алисой, а на «Алиса, поставь …» музыка включается из Spotify вместо Яндекс Музыки.
Проверено на: Станция 2 (yandexmidi), прошивка 0.369.1.50.* от 21.10.2026,
librespot 0.8.0, подписка Spotify Premium. Ставится поверх
AirPlay 2 одним набором: тот же каталог
/data/local/opt/ap2, распорядитель звука и автозапуск.
Что понадобится¶
- набор из рецепта AirPlay и SSH по ключу;
- Spotify Premium — с бесплатным аккаунтом librespot не работает;
- доступ к серверам Spotify из домашней сети — если провайдер его режет, см. ниже.
Сборка и установка¶
cd contrib/station2-media/build
docker run --rm --platform linux/arm64 -v "$PWD:/work" -v "$PWD/out:/out" \
alpine:3.24 sh /work/spotify-build.sh
docker run --rm --platform linux/arm64 -v "$PWD:/work" -v "$PWD/out:/out" \
alpine:3.24 sh /work/voice-build.sh
cd .. && ./install.sh <IP колонки> --ssh-only
spotify-build.sh собирает librespot с alsa-backend, with-avahi и
rustls-tls-webpki-roots. Объявление идёт через тот же Avahi, что у AirPlay, — второго mDNS
рядом с maind нет, а TLS не зависит от OpenSSL и сертификатов колонки.
Вход¶
Поиск колонки в локальной сети с телефона срабатывает не всегда, надёжнее один раз войти по
OAuth. Дальше librespot берёт сохранённый вход из spotify-cache и виден в Spotify как
устройство аккаунта из любой сети:
Скрипт поднимает на колонке librespot --enable-oauth --oauth-port 5588, пробрасывает этот
порт на компьютер по SSH (-L 5588:127.0.0.1:5588) и открывает страницу входа Spotify в
браузере. После «Принимаю» ответ уходит через туннель на колонку.
Как устроено¶
- Звук.
librespotс--backend subprocessзапускаетspotify-sink.shна старте воспроизведения и убивает на паузе. Приёмник освобождает устройство от медиа-демона Алисы и запускаетaplayс буфером 0,5 с; на паузе распорядитель сразу возвращает звук Алисе. - Громкость.
--mixer alsa --alsa-mixer-control Master: ползунок Spotify двигает регулятор Алисы. Кривая —--volume-ctrl log --volume-range 25. - Стартовая громкость. Без
--initial-volumelibrespotставит 50% или сохранённое значение и этим переставляет громкость Алисы.ap2.shпереводит текущее значениеMasterв проценты кривой Spotify и передаёт его явно, а сохранённое значение удаляет.
Значение volume-range ниже 25 ломает регулировку громкости
На регуляторе со шкалой в дБ librespot считает такой диапазон «узким аппаратным» и молча
переходит на линейную шкалу от минимума регулятора. Нужно 25 или больше.
Провайдер режет Spotify¶
Признак — в логе could not initialize spirc: Service unavailable { client error (Connect) }.
Вход с телефона при этом проходит: собственный протокол Spotify на порту 4070 не трогают, а
HTTPS к *.spotify.com рвётся сразу после TLS ClientHello. Проверка с колонки:
/data/local/opt/ap2/bin/curl -sS -o /dev/null -w "%{http_code}\n" \
--cacert /data/local/opt/ap2/lib/ca-certificates.crt https://apresolve.spotify.com/
librespot ходит только через HTTP-прокси без шифрования, поэтому прокси на внешнем сервере
не поможет: DPI видит имя Spotify и внутри такого туннеля. Рабочий вариант — обход на роутере.
В стандартных правилах XKeen (Mihomo) группа Spotify уже есть (spotify@domain). Колонку
нужно добавить в ту же политику доступа Keenetic, через которую XKeen проксирует остальные
устройства, а у группы Spotify должен быть рабочий узел.
Голосом: «Алиса, поставь …»¶
Алиса отдаёт распознанный текст фразы в локальный канал 127.0.0.1:9875. alice-text берёт
из него только финальный текст и смену состояния, voice-spotify.sh разбирает фразу, а
spotify-api.sh ищет и включает через Spotify Web API:
| Фраза | Что делает |
|---|---|
| «Алиса, поставь / включи X» | исполнитель, если первый найденный трек — его, иначе трек |
| «Алиса, поставь песню / альбом / плейлист X» | трек, альбом или плейлист |
| «Алиса, поставь музыку» | любимые треки |
| «Алиса, пауза / продолжи / дальше / назад» | управляет Spotify, если он играл в последний час |
Голосом проверена только часть команд
«Поставь» с именем исполнителя, «пауза» и «тише» во время музыки. Альбом, плейлист, «поставь музыку», «дальше» и «назад» работают по коду, голосом не проверялись.
- Умный дом, таймеры, будильники и громкость остаются Алисе.
- Алиса отвечает как обычно и успевает на секунду-две включить своё — Spotify её перебивает. От фразы до звука около 7 с.
- Падежное окончание мешает поиску, поэтому при пустом результате запрос повторяется без него («маркула» → «маркул»).
- В лог
voice.logпопадают только музыкальные команды, остальная речь никуда не пишется.
Ключ Web API — своё приложение на developer.spotify.com
(Web API, Redirect URI <http://127.0.0.1:5589/callback>) и вход по PKCE без секрета:
Ключи лежат в etc/spotify-webapi.json на колонке с правами 600. Web API
(api.spotify.com) провайдер режет так же, и он идёт через тот же обход.
Приглушение, пока Алиса слушает¶
Свою музыку Алиса на время слушания приглушает, а AirPlay и Spotify — нет, и команда тонет в
музыке. alice-text печатает смену состояния: @state 1 — слушает, 3 — распознала,
0 — свободна; номера совпадают с onAliceStateChanged в maind.log. На время слушания
voice-spotify.sh опускает отдельный регулятор AP2 Duck до 25% (около −22 дБ). Громкость
Алисы он не трогает, а если «свободна» не придёт, громкость вернётся через 15 с.
Короткие команды без обращения («громче», «пауза») колонка слышит, но включены они только для
собственного плеера Алисы (Phrase … is disabled in commandPhrasesConfig). Для Spotify и
AirPlay нужно говорить «Алиса, …».
Откат¶
Установщик кладёт свои файлы в /data/local/opt/ap2 и прописывает два автозапуска.
Чтобы вернуть колонку как было, с root по SSH:
rm -f /etc/init.d/S97ap2 /etc/init.d/S96otaguard
rm -rf /data/local/opt/ap2
sh /data/opt/yandex-noupdate.sh restore
reboot
Последняя команда возвращает штатные обновления: установщик отключает их
скриптом из шага 2 и кладёт оригиналы в /data/opt/backup.