Spotify Connect для Яндекс Станций: музыка, голосовое управление и TUI в одном бинарнике на Rust. Воспроизведение и подключение к Spotify обеспечивает librespot.
Caution
Использование дополнения PlayPlay — на ваш страх и риск. Возможна блокировка аккаунта Spotify. Есть сообщения о блокировках у пользователей, использовавших PlayPlay. Точная причина блокировок пока не установлена; безопасность аккаунта с этим дополнением не гарантируется.
В root-терминале самой колонки (SSH или adb shell) вставьте строку целиком,
вместе со скобками, и нажмите Enter:
(set -e; d=$(mktemp -d /tmp/spotiya.XXXXXX); trap 'rm -rf "$d"' EXIT; cd "$d"; echo 'Downloading Spotiya...'; get() { LD_LIBRARY_PATH=/system/vendor/quasar/libs /system/vendor/quasar/maind --gst-launch "souphttpsrc location=https://github.com/klockky/spotiya/releases/latest/download/$1 ssl-strict=true ssl-ca-file=/etc/ssl/certs/ca-certificates.crt iradio-mode=false timeout=15 retries=1 ! filesink location=$1" >log 2>&1 && grep -Fq 'EOS: end of stream' log && ! grep -Fq 'ERROR from ' log && [ -s "$1" ]; }; get INSTALL_SHA256SUMS && get install.sh || { echo 'Installer download failed.' >&2; exit 1; }; [ "$(wc -l <INSTALL_SHA256SUMS)" -eq 1 ] && grep -Eqx '[0-9a-f]{64} install\.sh' INSTALL_SHA256SUMS && sha256sum -c INSTALL_SHA256SUMS || { echo 'Installer checksum mismatch.' >&2; exit 1; }; sh install.sh)Команда открывает интерактивное меню: установка или обновление до последнего
стабильного релиза GitHub,
проверка совместимости без установки и полное удаление. Выберите пункт цифрой
и нажмите Enter; Enter без выбора или конец ввода отменяет действие.
При установке и обновлении вход в аккаунт, настройки, профили и дополнения
сохраняются. При первой установке добавляются команда spotiya и автозапуск;
при обновлении сохраняется состояние
службы. Во время загрузки команда выводит сообщение — дождитесь результата.
После установки откройте интерфейс:
spotiya tuiPlayPlay, AirPlay и YouTube можно установить через spotiya addons. Нужны root-доступ и
Spotify Premium. Быстрый способ проверен на Мини 2; для прошивок без подходящего
maind --gst-launch доступна установка через ПК.
Проект поддерживает первую Мини (YNDX-0004, yandexmini) с glibc 2.23
и Мини 2 с glibc 2.30. Обе используют Buildroot и 32-битный ARM
userspace. Имя в Spotify берётся из hostname колонки. Для других моделей нужны
совместимая сборка, ALSA и проверка локального протокола Алисы; поддержка всех
моделей не заявляется.
- Spotify Connect, вход через приложение или короткий код на
spotify.com/pair. - Голосовой поиск треков и исполнителей, пауза, продолжение и смена трека.
- Общая громкость Spotify и колонки через ALSA Master.
- Плавное приглушение Spotify на время обращения к Алисе и её ответа.
- TUI с поиском, текущим треком, прогрессом и управлением воспроизведением.
- Кнопки, жесты, подсветка, громкость и музыкальный спектр на дисплее Мини 2.
- Автозапуск, восстановление процесса после сбоя и сохранение входа.
- Остановка серии неудачных загрузок с явным повтором из TUI.
- Профили устройства: ALSA, локальный IPC Алисы, кнопки, кольцо и дисплей.
- Диагностика с отчётом без токенов и обновление из GitHub Releases с откатом.
- Дополнения: AirPlay 2, PlayPlay и YouTube (каст из приложений и ссылки из TUI).
Нужны Spotify Premium и уже работающий root-доступ к колонке. Получение root, прошивка и первоначальная активация станции в проект не входят.
Для установки или обновления прямо на колонке используйте быструю команду в начале README. Если Spotiya уже установлена, достаточно:
spotiya updateКоманда использует последний стабильный релиз из GitHub Releases. Если версия уже актуальна, переустановка и перезапуск приёмника не выполняются.
В root-терминале колонки выполните:
spotiya uninstallВведите uninstall для подтверждения. Приёмник и дополнения остановятся;
будут удалены автозапуск, команда spotiya, все дополнения, сохранённый вход,
настройки, профили, бэкапы и журналы Spotiya. Штатная Алиса и её данные сохраняются.
Если остановить процессы не удалось, файлы установки не удаляются.
Для автоматизации: spotiya uninstall --yes (без запроса подтверждения).
Полное удаление также доступно в меню быстрой настройки. Для старых версий без
команды удаления установщик скачает текущий пакет и запустит из него удаление,
не устанавливая его поверх старого.
Скачанный install.sh без аргументов открывает меню. Для запуска без меню:
sh install.sh --install, sh install.sh --check или
sh install.sh --uninstall --yes.
Готовые ARMv7-сборки доступны в GitHub Releases и артефактах Actions.
На ПК распакуй архив и передай каталог на колонку:
sha256sum -c SHA256SUMS
tar -xzf spotiya-armv7-linux-gnueabihf.tar.gz
adb -s SPEAKER_IP:5555 push spotiya /tmp/
adb -s SPEAKER_IP:5555 shell sh /tmp/spotiya/scripts/install.shУстановщик запускается от root на колонке. Он проверяет бинарник, профиль и свободное место, сохраняет предыдущие бинарник,
скрипты и встроенные профили в backups/, устанавливает автозапуск и команду
spotiya. Если корневая файловая система была read-only, после установки она
возвращается в read-only. При ошибке установки или запуска восстанавливается
предыдущая версия. Данные входа и пользовательские профили сохраняются.
При первой установке служба запускается; при обновлении сохраняется её состояние:
работающий приёмник перезапускается, остановленный остаётся остановленным.
Исполняемый файл и скрипты находятся в /data/opt/spotify-connect, состояние —
в receiver-state/, журнал — в /tmp/spotify-connect.log.
Начиная с 0.9.3 готовый декодер устанавливается из GitHub Releases: откройте
spotiya addons, выберите PlayPlay и нажмите Enter. Либо выполните:
spotiya addon install playplayAPK и ручное копирование файлов для установки не нужны. После проверки SHA-256,
манифеста и протокола декодер попадает в playplay/bin/playplay-decoder.
В TUI появится Ready (on demand). Приёмник подхватывает дополнение без перезапуска;
если предыдущая загрузка трека завершилась ошибкой, повторите воспроизведение.
Ранее вручную установленный playplay-decoder рядом с spotiya также поддерживается.
Обычный AES-путь используется первым; PlayPlay запрашивается только при явном
отказе AP. При успешном обычном ключе, сетевой ошибке или таймауте дополнительный
процесс не запускается. Параметры декодера запрашиваются при первом отказе и
сохраняются в памяти между сеансами Spotify. В журнале появляются
AP audio key refused; trying PlayPlay, PlayPlay decoder configured on demand
и PlayPlay decoder ready.
Материал ключей и ответы сервера в журнал не выводятся.
Декодер работает отдельным процессом для каждого загружаемого трека. Чтение и перемотка передаются через локальный бинарный канал с ограничением размера и таймаутами. При освобождении трека или ошибке процесс завершается. Ошибка получения ключа для музыкального трека останавливает загрузку до аудиодекодера; зашифрованный поток больше не разбирается как незашифрованный MP3.
Экспериментальный playplay-decoder содержит выделенные фрагменты Spotify APK
и запускает их через Unicorn. Он распространяется отдельным дополнением
spotiya-playplay-armv7.tar.gz; основной бинарник Spotiya их не содержит.
Описание сборки и происхождения пакета.
Без дополнения приёмник использует обычные аудиоключи.
Резервный путь проверен запросом ключа проблемного аккаунта и побайтным сравнением
расшифрованного образца без запуска воспроизведения. На Мини 2 также подтверждён
слышимый звук с проблемного аккаунта; в журнале проверено использование PlayPlay.
Это не проверка всех треков или всех аккаунтов. На Мини 1 этот путь пока не проверялся.
spotiya profiles показывает встроенные и пользовательские профили, spotiya profile — выбранную
конфигурацию и обнаруженные возможности. Эти команды доступны без запуска
приёмника; профиль работающего приёмника также виден в TUI.
mini1— первая Мини: штатная ALSA, общая громкостьMasterи Quasar IPC. Допустим также выбор по имениyandexmini.mini2— проверенный профиль Мини 2 с Quasar IPC и драйвером её кнопок, шестисегментного RGB-кольца и четырёхразрядного дисплея.generic— Spotify Connect через ALSA без штатного IPC и физического управления.auto— используетreceiver-state/profile.json, если файл существует; иначе используетcommon.deviceTypeиз системногоquasar.cfgи device tree.yandexminiвыбираетmini1,yandexmini_2—mini2; неизвестные модели получаютgeneric.
У первой Мини отдельный драйвер датчика жестов и подсветки пока не включён.
Кнопка микрофона и штатные жесты остаются у Алисы; изменение общего Master
подхватывается приёмником. Экрана у этой модели нет. Фирменная ALSA-библиотека
реализует виртуальный default, поэтому профиль не подменяет его прямым hw.
Кнопки, кольцо и дисплей проверяются независимо. Для кольца и дисплея должны
существовать все нужные sysfs-каналы; для кнопок Мини 2 проверяется имя input-устройства.
Отсутствующая возможность отключается. Голосовое управление в общем профиле
показывается как unavailable; команды паузы штатному плееру не отправляются.
В TUI нажми d, выбери профиль стрелками или j/k и подтверди Enter.
Из терминала: spotiya profile select mini1, spotiya profile select mini2, spotiya profile select generic
или spotiya profile select auto. Выбор сохраняется при обновлениях и перезагрузках.
Работающий приёмник перезапускается; воспроизведение при этом прекращается.
Остановленный приёмник остаётся остановленным. При неудачном запуске возвращается
предыдущий выбор и выполняется попытка восстановить приёмник.
Для другой колонки положи JSON в /data/opt/spotify-connect/profiles/:
он появится в меню. Его можно выбрать по id или командой
spotiya profile select /путь/к/профилю.json. Выбранный файл сохраняется
как копия в receiver-state/profile-selection.json, поэтому удаление исходника
не ломает запуск. После редактирования исходного JSON выбери его повторно.
Встроенные варианты имеют приоритет над одноимёнными пользовательскими id.
Для прежней настройки через receiver-state/profile.json выбери auto.
Параметр бинарника --profile ID_OR_JSON переопределяет сохранённый выбор только
для текущего запуска. Новый профиль описывает ALSA, Quasar IPC и поддерживаемый
драйвер; для другой схемы кнопок или дисплея может потребоваться новый драйвер.
Ошибки JSON и неизвестные поля останавливают запуск; скрытого перехода к другому
профилю при ошибке нет.
Пример собственного аудиопрофиля; значения ALSA выбираются на целевой колонке:
{
"version": 1,
"id": "my-station",
"name": "My Station",
"audio": {
"device": "plughw:0,0",
"format": "S16",
"mixer_device": "hw:0",
"mixer_control": "PCM",
"mixer_index": 0,
"mixer_channel": "mono"
},
"voice": null,
"controls": null
}Если станция использует совместимый Quasar IPC, поле voice задаётся как
{"protocol":"quasar","address":"127.0.0.1:9875"} с её локальным адресом.
В профиле Мини 2 вынесены input_device, input_name, коды трёх кнопок,
ring_prefix и display_prefix. Неиспользуемый путь можно заменить на null;
визуализация работает и без input-устройства. Драйвер mini2 предполагает
совместимые жесты, отдельное input-устройство кнопок и ту же геометрию светодиодов.
Для другого протокола экрана, подсветки или голосового IPC потребуется новый
драйвер. Профили сами по себе не добавляют поддержку Android Audio HAL или
совместимость ARM-сборки с любым userspace.
Для ручного запуска можно выбрать встроенный профиль или файл без изменения сохранённой конфигурации:
/data/opt/spotify-connect/spotiya --profile generic --profile-info
/data/opt/spotify-connect/run.sh --profile /absolute/path/profile.jsonВыбор передаётся дочернему процессу при автоматическом перезапуске. Встроенные профили находятся внутри бинарника; JSON-файлы в пакете служат готовыми образцами. Имя в списке Spotify по-прежнему берётся из hostname.
Внутри adb shell:
spotiya # TUI
spotiya login # вход по коду
spotiya play "No Surprises"
spotiya pause
spotiya resume
spotiya retry # повтор после серии ошибок
spotiya next
spotiya previous
spotiya volume 25
spotiya voice off
spotiya voice on
spotiya spectrum on
spotiya spectrum off
spotiya release # освободить сеанс для штатной музыки
spotiya status
spotiya profile
spotiya profiles
spotiya profile select auto
spotiya restartКоманды start, stop и version тоже доступны. OK означает постановку
команды в очередь; поиск и загрузка трека выполняются асинхронно.
Для управления с ПК используй bin/spotiya: нужны Python 3 и adb.
python3 bin/spotiya --device SPEAKER_IP:5555 tui
python3 bin/spotiya --device SPEAKER_IP:5555 loginУстройство можно задать через SPOTIYA_DEVICE или в
~/.config/spotiya/config.json:
{"device": "SPEAKER_IP:5555"}Если устройство не задано, выбирается единственное подключённое через adb. При нескольких подключениях нужно указать устройство явно.
| Клавиша | Действие |
|---|---|
Space |
Пауза / продолжение |
n / p |
Следующий / предыдущий трек |
+ / - |
Громкость |
/ |
Поиск |
l |
Вход по короткому коду |
v |
Голосовое управление вкл/выкл |
e |
Визуализация спектра вкл/выкл |
r |
Повтор после серии ошибок, когда закончится пауза |
x |
Освободить сеанс для Алисы |
q |
Закрыть TUI, оставив музыку |
Вход по коду ждёт подтверждения до десяти минут. До подтверждения и проверки нового входа текущий аккаунт продолжает работать. Токены не выводятся в TUI, статус или журнал приложения.
Примеры: «Алиса, включи Radiohead», «включи песню No Surprises», «останови музыку», «Алиса, хватит», «продолжи музыку», «продолжай», «следующий трек».
Приёмник получает окончательный текст распознавания из локального IPC Алисы
на 127.0.0.1:9875, отменяет штатный музыкальный ответ и передаёт запрос
существующему сеансу librespot. Собственное распознавание микрофона не используется.
Пока играет Spotify, штатный музыкальный плеер периодически ставится на паузу,
чтобы дорожки не накладывались. Голосовые фразы в журнал не записываются.
Быстрые команды без слова «Алиса» приходят из штатного CommandSpotterCapability:
«хватит», «стоп», «пауза», «играй», «продолжай» (также «продолжи»), «дальше», «назад»
и «следующий» управляют воспроизведением. «Громче» и «тише» меняют громкость
штатными средствами; Spotiya подхватывает общий Master без второго шага громкости.
Доступность конкретной фразы зависит от прошивки и штатной модели распознавания.
Spotiya назначает действия уже распознанным фразам; добавление слова в её обработчик
само по себе не учит штатную модель распознавать новую быструю фразу.
В приложении «Дом с Алисой» должны быть включены быстрые команды для музыки
(Настройки → Ассистент → Быстрые команды).
При активации Алисы Spotify плавно приглушается до 20% амплитуды за 80 мс.
Приглушение сохраняется во время распознавания, ожидания и озвучивания ответа;
после возврата Алисы в ожидание звук восстанавливается за 300 мс. Это обработка
только PCM Spotify. Выбранная громкость музыки сохраняется отдельно от временных
значений Master, которые штатная система выставляет для речи. Они не передаются
обратно в Spotify; через 750 мс после завершения диалога Master возвращается
к выбранному уровню. Изменения ползунком или кнопками во время диалога также
сохраняются. Для распознанных команд «громче», «тише», «громкость…» и других
команд управления звуком принимается новый уровень, выставленный Алисой.
В TUI появляется Alice: ducked. При разрыве локального соединения
приглушение снимается; если завершающее событие потерялось, оно снимается через
60 секунд после последнего события активности. Команда voice off отключает
перехват музыкальных фраз, сохраняя приглушение для обычных вопросов Алисе.
На Мини 2 центральная кнопка управляет паузой; +/− меняют громкость;
жесты Алиса → +/− переключают треки. Есть короткие эффекты кольца и вывод
громкости 0–100 на дисплей. Профиль включается только при наличии sysfs-интерфейса
Мини 2. Кнопка отключения микрофона не перехватывается.
На Мини 2 клавиша e в TUI или команда spotiya spectrum on включает четыре
столбца спектра: басы слева, высокие частоты справа (100, 400, 1600 и 6400 Гц).
Они обновляются 20 раз в секунду по звуку Spotify. Это визуализация;
эквализация и сами аудиоданные не меняются.
Изменение громкости на две секунды показывает проценты поверх спектра.
На паузе, при отключении визуализации и завершении Spotify возвращаются часы.
Штатные анимации имеют приоритет. Настройка сохраняется после перезапуска;
при первой установке визуализация выключена. Для других моделей TUI показывает
unavailable, пока для их дисплея не добавлен профиль. При выключенной
визуализации анализ звука не выполняется.
Разбор музыкальных фраз экспериментальный. Необычные имена устройств умного дома могут быть приняты за музыкальный запрос. Альбомы и плейлисты пока обрабатываются как текстовый поиск. После перезапуска «включи музыку» запускает последний трек сначала; очередь и позиция не сохраняются.
spotiya doctor
spotiya doctor report # новый JSON-файл в /tmp
spotiya doctor report /tmp/my-report.jsondoctor проверяет процесс и наблюдение за ним, актуальность статуса, сохранённый
профиль, ALSA-микшер, громкость и mute, Quasar IPC, свободное место и RAM,
наличие сохранённого входа, DNS и HTTPS для Spotify, входа и обновлений.
Команда не запускает приёмник, не меняет громкость и не открывает PCM-устройство.
Проверка HTTPS не запускает воспроизведение и не требует входа в Spotify.
FAIL даёт ненулевой код завершения; WARN указывает, например, на остановленную
службу или отсутствие сохранённого входа.
Для отчёта из последних 64 КиБ каждого журнала берутся только счётчики категорий:
ключ аудио, сеть, декодер, аудиоустройство, авторизация и другие предупреждения.
Историческая ошибка в журнале не означает, что она продолжается сейчас.
Исходные строки логов, токены, содержимое credentials, имя аккаунта, hostname,
названия треков и пути пользовательских профилей в JSON не копируются.
Файл создаётся с правами 0600; существующий файл не перезаписывается.
Отчёт можно приложить к issue после копирования с колонки.
С ПК доступны те же проверки; путь отчёта относится к колонке:
python3 bin/spotiya --device SPEAKER_IP:5555 doctor reportspotiya update check # проверить последний стабильный релиз
spotiya update # установить более новую версию
spotiya update v0.8.0 # выбрать опубликованный стабильный релизКоманда скачивает ARMv7-архив и SHA256SUMS из GitHub Releases по HTTPS,
проверяет SHA-256, структуру архива и соответствие версии бинарника тегу.
Черновики и предварительные релизы не устанавливаются. Равная или более старая
версия пропускается. Артефакты Actions не считаются опубликованным релизом;
если релизов ещё нет, update check сообщает об этом без изменения устройства.
Контрольная сумма сверяется с файлом из того же релиза; отдельной подписи релиза нет.
Обновление использует тот же установщик с проверкой профиля и места, что и
ручная установка. При ошибке копирования или неготовности работающего приёмника
восстанавливаются предыдущие бинарник, скрипты и встроенные профили, затем
выполняется попытка запуска старой версии. Готовность проверяется локально;
отсутствие Интернета само по себе не вызывает откат. Обновление прерывает текущую
музыку и не возобновляет её автоматически. Остановленная служба остаётся остановленной.
Хранятся до двух последних новых копий backups/managed-*; старые ручные и
созданные прежними установщиками копии автоматически не удаляются.
Для установки архива, уже переданного на колонку, в том числе из Actions:
spotiya update file /tmp/spotiya-armv7-linux-gnueabihf.tar.gz /tmp/SHA256SUMSЛокальный вариант тоже проверяет сумму и выполняет установку с откатом;
он допускает повторную установку и возврат к более старой совместимой версии.
Формат SHA256SUMS должен содержать имя spotiya-armv7-linux-gnueabihf.tar.gz.
С ПК команды доступны через python3 bin/spotiya --device SPEAKER_IP:5555 update …;
пути локального варианта относятся к файлам на колонке.
Загрузка трека отображается как LOADING: кнопки и спектр переходят под
управление Spotify после события воспроизведения. При Unavailable для текущего
трека захват снимается, прогресс останавливается, а TUI показывает UNAVAILABLE.
Ошибка предзагрузки следующего трека не сбрасывает текущий.
После трёх последовательных неудачных загрузок spotiya закрывает сеанс Spotify,
чтобы остановить автоматические пропуски. TUI показывает RETRY REQUIRED,
причину последней серии ошибок и отсчёт 15 секунд. Затем клавиша r или
spotiya retry подключает приёмник заново и повторяет последний неудачный трек.
По окончании отсчёта автоматического повтора нет. Вход по новому коду также
сбрасывает блокировку. Ошибки предзагрузки и повторы одного события не считаются;
успешная загрузка для воспроизведения или паузы сбрасывает счётчик.
Причина определяется по предупреждениям и ошибкам librespot: ключ аудио, загрузка по сети, декодирование или аудиоустройство. Это диагностическая подсказка; отказ выдачи ключа сам по себе не доказывает несовместимость аккаунта.
Предупреждения и ошибки librespot, включая загрузку аудио, декодер и ALSA,
попадают в /tmp/spotify-connect.log по умолчанию. Для подробной диагностики
плеера запусти приёмник в терминале:
spotiya stop
RUST_LOG=warn,librespot_playback=debug /data/opt/spotify-connect/run.shПосле диагностики останови его через Ctrl+C и выполни spotiya start.
spotiya start запускает режим наблюдения --supervise того же бинарника.
Он перезапускает приёмник после выхода с паузами 2, 4, 8, 16, 32 и максимум
60 секунд. После минуты стабильной работы задержка снова начинается с двух
секунд. Отсутствие сети не отменяет последующие попытки запуска.
spotiya stop останавливает и наблюдение, и приёмник; после ручной остановки
служба сама не запускается. Повторный start не создаёт второй экземпляр.
После сбоя самого наблюдения следующий start останавливает оставшийся
дочерний процесс и запускает службу заново. run.sh без --supervise
по-прежнему подходит для диагностики в переднем плане.
Журнал наблюдения — /tmp/spotify-connect-supervisor.log. Журнал приёмника
сохраняется между перезапусками; перед очередным запуском файл от 256 КиБ
перемещается в /tmp/spotify-connect.log.1. Новые скрипты устанавливаются
вместе с бинарником через scripts/install.sh.
Приёмник использует однопоточный асинхронный runtime и до двух вспомогательных
потоков для блокирующих операций. Они освобождаются после двух секунд простоя;
их стеки ограничены 512 КиБ. Внутренний runtime плеера librespot использует
один рабочий поток; это значение можно переопределить переменной
TOKIO_WORKER_THREADS перед запуском. ALSA-микшер открывается один раз и обновляется
по событиям, а буферы статуса и локального IPC используются повторно.
При ошибке микшера дескриптор открывается заново при следующем обращении.
glibc использует одну арену выделения памяти; каждые 30 секунд без
воспроизведения свободные страницы возвращаются системе через malloc_trim.
Приглушение изменяет существующий PCM-буфер без дополнительной копии.
Битрейт, предзагрузка следующего трека и качество декодирования сохранены.
RSS включает страницы бинарника и библиотек, разделяемые между процессами;
для сравнения расхода полезно учитывать также PSS и Private Dirty из
/proc/PID/smaps. Расход во время воспроизведения зависит от трека и очереди.
В сравнении 0.5.0 и 0.6.0 на Мини 2 с подключённым Spotify без воспроизведения число потоков приёмника уменьшилось с 8 до 5, виртуальное адресное пространство — с 24,2 до примерно 14,2 МиБ. RSS остался примерно 6,6–6,8 МиБ: сокращение зарезервированного адресного пространства не означает такую же экономию ОЗУ. Пиковый расход при воспроизведении в этом сравнении не измерялся.
Доработки Login5 и Zeroconf, а также экспериментальный резервный путь PlayPlay
находятся в форке librespot.
Cargo загружает его по точному коммиту из Cargo.toml; Cargo.lock фиксирует
зависимости. Все внутренние крейты librespot берутся из одной ревизии форка.
Описание изменений и проверки: SPOTIYA.md.
На Linux с x86_64 нужны Rust/rustup, Git, C-компилятор, make, pkg-config, curl, bzip2 и xz.
Для локальных Rust-тестов нужны заголовки ALSA (libasound2-dev в Debian/Ubuntu).
cargo fmt --all -- --check
cargo clippy --locked --all-targets -- -D warnings
cargo test --locked
make -C controls/mini2 check
scripts/bootstrap-arm.sh
scripts/build-arm.sh
scripts/package.shARM-сборка использует Linaro GCC 6.5 / glibc 2.23 и ALSA 1.1.8.
scripts/build-arm.sh проверяет, что бинарник не требует более новой glibc. Загрузки
проверяются по SHA-256; Rust и зависимости зафиксированы в rust-toolchain.toml
и Cargo.lock. На колонке используются её системные libasound.so.2 и glibc;
ALSA из сборочного sysroot в пакет не включается.
По умолчанию собирается ARMv7 hard-float с настройкой CPU Cortex-A53.
Пути можно переопределить через SPOTIYA_CACHE, SPOTIYA_TOOLCHAIN,
SPOTIYA_ALSA_SYSROOT; CPU — через SPOTIYA_TARGET_CPU. Это не гарантирует
совместимость с другой моделью или Android/bionic.
CI проверяет core/audio/discovery форка на закреплённой ревизии и выполняет Rust fmt/clippy/tests, C-тесты с ASan/UBSan, ShellCheck, проверку Python launcher, ARM-сборку и создание установочного архива.
MIT. Librespot распространяется под MIT; системная ALSA — под LGPL.
Начиная с 0.9.0 Spotiya может управлять дополнительным приёмником AirPlay 2
на основе Shairport Sync. Он использует системное имя колонки и объявляет модель
AudioAccessory5,1 для иконки HomePod mini в меню AirPlay. Набор возможностей
AirPlay остаётся прежним. Иконка зависит от отправителя и его кеша. В TUI клавиша
a открывает отдельный экран дополнений. Из терминала — spotiya addons.
В нём Enter скачивает отсутствующее дополнение из GitHub Releases. Для AirPlay
установка также включает службы; Enter у установленного AirPlay включает или
выключает их. PlayPlay работает по необходимости и не имеет отдельной службы.
Отдельные команды — spotiya airplay on и
spotiya airplay off. Настройка сохраняется после перезагрузки.
AirPlay устанавливается отдельным пакетом spotiya-airplay2-armv7.tar.gz.
Экран показывает список дополнений, их состояние и ход загрузки. Стрелки или
j/k выбирают пункт, Esc/q возвращают к плееру, c отменяет установку.
Можно вернуться к плееру, пока идёт загрузка; выход из TUI отменяет её.
У установленного дополнения u скачивает пакет текущей версии заново и заменяет
старый, если он отличается. Новый PlayPlay подхватывается сразу; после обновления
AirPlay перезапустите приёмник (spotiya restart). Двойное нажатие x удаляет дополнение; AirPlay сначала
нужно выключить. Из терминала: spotiya addon install ID также обновляет,
spotiya addon remove ID удаляет.
Каталог дополнений задаётся в src/addons.rs, интерфейс работает со всем списком.
Пакет берётся из релиза той же версии, что запущенная Spotiya. Перед установкой
проверяются SHA-256 архива, манифест и отдельные бинарники. Установка не перезапускает
Spotify и не копирует файлы AirPlay в основной бинарник. При выключенном AirPlay
его четыре службы остановлены. Для прямой установки: spotiya addon install airplay.
Без опубликованного релиза с AirPlay экран покажет причину и позволит повторить попытку.
Базовый пакет Spotiya сохраняет прежний размер и работает без него. Внутри AirPlay-пакета находятся Shairport Sync, NQPTP, Avahi и приватный D-Bus; системный D-Bus и его настройки не меняются. Avahi не публикует обратные адресные записи, чтобы не конфликтовать со штатным mDNS станции. Все процессы запускаются и останавливаются вместе с приёмником Spotiya. При сбое одного из них стек перезапускается с задержкой. Обновление основной Spotiya сохраняет AirPlay-пакет.
Сборка на Linux:
scripts/bootstrap-arm.sh
scripts/build-airplay.shНужны инструменты сборки C/C++, Python 3, CMake, Autoconf, Automake, Libtool,
gettext, pkg-config, flex, bison, xxd, patch и host-программа plistutil.
Исходники зависимостей закреплены в airplay/sources.json с SHA256;
ревизии Shairport Sync и NQPTP закреплены в airplay/fetch.py.
Собранный пакет ставится той же командой, что и пакет из релиза; версия Spotiya на станции должна совпадать с версией пакета:
adb -s DEVICE push dist/spotiya-airplay2-armv7.tar.gz dist/AIRPLAY_SHA256SUMS /tmp/
adb -s DEVICE shell spotiya addon file airplay /tmp/spotiya-airplay2-armv7.tar.gz /tmp/AIRPLAY_SHA256SUMS
adb -s DEVICE shell spotiya airplay onВыберите системное имя станции в меню AirPlay на iPhone, iPad или Mac в той же
локальной сети. При начале AirPlay Spotify освобождает аудиовыход. При запуске
Spotify AirPlay-сессия завершается, а приёмник снова становится доступен.
Громкость AirPlay меняет общий уровень колонки. release/x и пауза в TUI
завершают AirPlay-сессию; продолжение и смена трека управляются на отправителе.
Спектр на дисплее пока обрабатывает только Spotify.
Лог дополнительных служб: /tmp/spotiya-airplay.log. В spotiya status есть
поля airplay_available, airplay_enabled, airplay_running, airplay_active
и airplay_error. Отдельная ошибка AirPlay не останавливает Spotify Connect.
Основной пакет собран для ARMv7 hard-float с glibc 2.23 и системной ALSA; он подходит для первой Мини и Мини 2. Опциональные AirPlay-компоненты необходимо отдельно проверять на конкретной станции.
Дополнение youtube принимает каст из приложений YouTube и YouTube Music (колонка
видна в меню трансляции под своим системным именем) и играет ссылки: их можно вставить в обычный поиск TUI (/) или в отдельную строку
y, из терминала — spotiya youtube ССЫЛКА или spotiya play ССЫЛКА. Ссылка
YouTube в поиске никогда не уходит в Spotify. Понимаются
youtu.be/…, watch?v=…, /shorts/… и голый идентификатор видео. Звучит только
аудиодорожка.
Установка и включение — через экран дополнений или командами
spotiya addon install youtube и spotiya youtube on/off. Пакет
spotiya-youtube-armv7.tar.gz занимает около 1,5 МБ; пока дополнение выключено,
его процесс не запущен.
Аккаунт YouTube на колонке не нужен и не используется: выбирает видео телефон, а
звук колонка получает как анонимный мобильный веб-клиент, то есть так же, как
разлогиненный браузер. Чтобы YouTube не обрывал поток на первой минуте, колонка сама
получает PO-токен: проверка BotGuard и расшифровка ссылок из плеера YouTube
выполняются во встроенном QuickJS. Подготовленный плеер кешируется в
receiver-state/youtube/cache и пересобирается только при смене его версии.
Видео, для которых нужен вход (приватные, для участников, с возрастным
ограничением), так не воспроизводятся.
Колонку YouTube делит со Spotify и Алисой так же, как AirPlay: с первым звуком
трека Spotify останавливается, а Алиса ставится на паузу; запуск Spotify, наоборот,
останавливает YouTube. Пауза, продолжение и смена трека работают с кнопок колонки,
из TUI (пробел, n, p) и голосом; громкость кнопками и с телефона меняет общий
ALSA Master. TUI показывает состояние YOUTUBE и название ролика, спектр работает в TUI и на дисплее так же, как для Spotify. Остановка всегда идёт через
штатное закрытие ALSA: процесс, убитый посреди записи, может оставить общий
микшер dmix в состоянии, в котором замолкает вся колонка вместе с Алисой.
Тяжёлый JS-контекст плеера освобождается после обработки ссылки. На диске остаются подготовленный скрипт и скомпилированный байткод QuickJS: следующие треки загружают байткод без повторного разбора JS. Кэш привязан к исходнику и сборке аддона; при несовпадении или повреждении он пересоздаётся. На тестовом плеере кэш байткода занимает около 9 МиБ на диске.
В локальном тесте обработчика на ПК после обработки оставалось 11–12 МиБ RSS. Пик составлял около 33 МиБ при готовом кэше и около 43 МиБ при первой компиляции; обработка с готовым кэшем занимала примерно 0,12 секунды. Это не замер полного аддона на станции: её расход ОЗУ ещё нужно проверить. Первый трек после запуска требует подготовки токена и плеера; следующие используют сохранённый скрипт и готовый минтер токенов.
Сборка на Linux:
scripts/bootstrap-arm.sh
scripts/build-youtube.shКод DIAL, SSDP и Lounge адаптирован из ytcast-open
(MIT). Уведомления ytcast-open, BgUtils, jsdom, quickjs-ng и libopus лежат в
youtube/licenses и входят в пакет.