Перейти к содержимому

Устройства и адаптеры

Пустое состояние dashboard с кнопкой Scan for devices

Если bridge уже видит Bluetooth-адаптер, но ни одной колонки ещё не настроено, dashboard показывает Scan for devices. Этот shortcut теперь переводит прямо в Configuration → Devices → Discovery & import и сразу запускает сканирование.

Если же адаптер вообще не найден, empty state предлагает Add adapter, открывает Configuration → Bluetooth, создаёт пустую строку адаптера и ставит фокус в первое поле.

Вкладка Devices с fleet table и discovery workflow

Рекомендуемый сценарий такой:

  1. Откройте Configuration → Devices.
  2. Нажмите Scan в карточке Discovery & import.
  3. В результатах выберите Add или Add & Pair.
  4. Заполните имя плеера и дополнительные поля.
  5. Сохраните конфиг и при необходимости выполните перезапуск.
  • Сканирование идёт в фоне и интерфейс периодически опрашивает результат.
  • Найденные устройства можно сразу добавить в fleet table.
  • Add & Pair выполняет pairing/trust/connect до добавления строки в конфиг.
  • После завершения сканирования кнопка уходит в cooldown и не даёт спамить повторные попытки.

Bluetooth scan modal с выбором адаптера, audio-only filter, прогрессом и действиями импорта

Блок Already paired позволяет импортировать устройства, которые хост уже знает, без повторного сканирования.

Карточка Paired devices с действиями импорта и repair

Device fleet — основное место для управления колонками.

КолонкаЗа что отвечает
EnabledВременно исключает устройство из запуска
Player nameИмя в Music Assistant
MACBluetooth-адрес
AdapterПривязка к конкретному контроллеру
PortПользовательский sendspin listener port
Delaystatic_delay_ms
LiveRuntime badge из работающего bridge
RemoveУдаление строки из конфига

При раскрытии строки появляются advanced-поля: preferred format, listen host и keepalive interval.

Текущий device-flow использует такие network/runtime-поля:

ПолеТекущее поведение
listen_portЕсли задан, устройство всегда использует именно этот порт
listen_hostПереопределяет advertised host/address для listener’а этого устройства
keepalive_intervalЛюбое положительное значение включает keepalive-тишину; всё меньше 30 секунд поднимается до 30
keepalive_silenceLegacy-совместимое поле из старых addon-конфигов; отдельного переключателя для него в текущем web UI больше нет

Если listen_port пуст, runtime использует BASE_LISTEN_PORT + индекс устройства. Каждый эффективный listener port должен быть уникальным. Для multi-bridge setups на одном хосте либо задавайте разный диапазон BASE_LISTEN_PORT для каждого bridge, либо указывайте явные listen_port для всех колонок.

listen_host полезен в первую очередь там, где Music Assistant должен подключаться к bridge по адресу, отличному от автоопределённого.

Вкладка Bluetooth с naming адаптеров и recovery policy

Во вкладке Bluetooth доступны:

  • понятные имена адаптеров,
  • ручные adapter entries,
  • refresh detection,
  • policy-параметры восстановления,
  • переключатель Prefer SBC codec.

В поле Adapter можно указывать:

  • hci0, hci1 и т.д.,
  • или MAC-адрес адаптера.

Использование MAC особенно удобно в LXC-окружениях, где имя hciN может меняться после перезагрузки.

Dashboard теперь возвращает вас в точное место редактирования, а не просто открывает общий раздел:

  • Шестерёнка устройства → подсвечивает нужную строку в Configuration → Devices.
  • Shortcut/gear адаптера → подсвечивает нужную строку в Configuration → Bluetooth.
  • Бейдж группы → открывает соответствующие настройки группы в Music Assistant в новой вкладке.

Один и тот же fleet можно просматривать в двух layout’ах:

  • Режим сетки для небольшого числа устройств.
  • Режим списка для больших fleet’ов, с sortable columns и expandable rows.

По умолчанию bridge переключается в режим списка, если видно больше 6 устройств, но ваш ручной выбор запоминается в браузере и используется при следующем открытии.

Released device row с runtime-состоянием, готовым к reclaim

Из dashboard доступны такие действия:

ДействиеКогда использовать
ReconnectНужно принудительно переподключить BT без правки конфига
Re-pairPairing/trust state на хосте сломано или устарело
ReleaseНужно временно вернуть колонку телефону или ПК
ReclaimНужно снова отдать Bluetooth-управление bridge

Release не удаляет устройство из конфига — bridge просто перестаёт активно его переподключать до нажатия Reclaim.

Это отличается от других похожих действий:

ДействиеЧто меняется
ReleaseТолько runtime hand-off; устройство остаётся в конфиге и быстро возвращается через reclaim
DisableКонфигурируемый пропуск устройства на старте; строка остаётся в fleet table
Unpair / Re-pairМеняется Bluetooth trust state на уровне хоста

Если все настроенные колонки сейчас released, onboarding/recovery surfaces могут показать fleet-level reclaim action, чтобы быстро вернуть bridge ownership без обхода каждой строки вручную.

Во вкладке Bluetooth есть два параметра, которые напрямую влияют на доступность устройств:

  • BT check interval задаёт частоту проверки и попыток Bluetooth-восстановления.
  • Auto-disable threshold может сохранить устройство в disabled-состоянии после серии неудачных reconnect.

Если колонка постоянно флапает, bridge может auto-disable её, чтобы защитить остальную группу. После устранения причины Bluetooth-проблемы включите устройство снова в Configuration → Devices.

Для сложных колонок особенно полезны такие поля:

  • static_delay_ms — декларирует, сколько дополнительной задержки железо этой колонки добавляет после PulseAudio / PipeWire-sink, в который пишет bridge (BT-радио, кодек, DSP колонки, усилитель). Согласно Sendspin-протоколу, клиент вычитает это значение из времени проигрывания каждого чанка, поэтому аудио отдаётся на железо раньше ровно на static_delay_ms миллисекунд; железо добавляет свою реальную задержку обратно, и акустический выход приходит на запланированный таймштамп. В web UI для каждого нового устройства по умолчанию подставляется 300 мс — это разумная стартовая оценка задержки BT-пайплайна за sink’ом у типичных потребительских колонок, и полевые отчёты показали, что 300 мс заметно лучше 0 для A/V-синхронизации, особенно на Ubuntu / PipeWire-хостах. Увеличивайте значение для колонок, которые стабильно отстают от остальных в группе (слышно, что их выход опаздывает на несколько сотен мс) — это значит, что их реальная hw-задержка больше, чем компенсирует текущий static_delay_ms. Уменьшайте — для колонок, которые опережают группу. Отрицательные значения не принимаются: sendspin 7.0+ их отклоняет, а legacy-отрицательные значения в импортируемом конфиге при миграции клампятся в 0. Диапазон — 05 000 мс; дешёвым BT-колонкам с большими внутренними jitter-буферами могут понадобиться значения, близкие к 1 000 мс.
  • keepalive_interval — периодическая тишина, чтобы некоторые колонки не засыпали между треками.
  • keepalive_silence — legacy-boolean из старых addon-конфигов; сейчас keepalive фактически управляется через keepalive_interval > 0.
  • keep_alive_method — способ, которым bridge удерживает колонку в активном состоянии при включённом keep-alive:
    • infrasound (по умолчанию) — отправляет почти неслышимую 2 Hz пульсацию. Работает на колонках, которые в power-save заглушают обычную тишину.
    • silence — отправляет чистую цифровую тишину. Минимальное влияние на качество, но не сработает на колонках, глушащих линию при нулевых сэмплах.
    • none — отключает активную эмиссию полностью; режим «держим BT-линк, но молчим». Подходит для колонок, которые сами по себе не засыпают.
  • preferred_format — уменьшает ресэмплинг или нагрузку CPU в зависимости от настроек MA.

Измерение латентности каждой колонки через MassDroid

Заголовок раздела «Измерение латентности каждой колонки через MassDroid»

Для сложных многоспикерных групп подбор static_delay_ms чисто на слух — долгий процесс. Ускорить его помогает измерение реального round-trip времени (RTT) каждой колонки через MassDroid — сторонний нативный Android-клиент Music Assistant со встроенной акустической калибровкой. Использовать его нужно как диагностический инструмент, а не как прямой источник значений static_delay_ms.

Что именно измеряет MassDroid. После калибровки самого телефона как baseline MassDroid проигрывает шесть тональных импульсов 1 кГц через сопряжённую BT-колонку и записывает их обратно через микрофон. Нативный C++ DSP-пайплайн ловит начало каждого тона через bandpass-фильтрацию и envelope SNR, усредняет и выдаёт:

  • BT delay — абсолютный round-trip в миллисекундах (отправка сэмпла → DAC → транспорт → воздух → микрофон). Для типичных BT-колонок результат ~150–400 мс.
  • +X ms over phone — сколько из этого приходится на сам BT-путь (поверх baseline телефона).
  • QualityGOOD, MARGINAL или FAILED (по количеству пойманных тонов, разбросу между ними и SNR).

Почему это число нельзя подставить 1 : 1. MassDroid меряет полный акустический round-trip (DAC + транспорт + воздух + захват микрофоном). Sendspin-овский DAC-anchored sync уже забирает на себя ту часть пайплайна, которую видит PulseAudio / PipeWire; плюс mic-capture — это уже не сторона моста. Переносится другое — порядок и разница RTT между колонками: в группе колонка с максимальным RTT имеет больше всего невидимой остаточной hw-задержки и должна нести самый большой static_delay_ms; колонкам с меньшим RTT нужно меньшее значение.

Рекомендуемый порядок:

  1. Поставьте MassDroid на телефон с Android 8.0+ и укажите тот же MA-сервер.
  2. В MassDroid откройте плеер Sendspin (local) → меню «⋮» → Player Settings → сначала запустите Phone speaker calibration (обязательный baseline: Bluetooth отключён, громкость медиа 50–70 %, комната тихая).
  3. Последовательно сопрягайте телефон напрямую с каждой из проблемных BT-колонок и запускайте Bluetooth device calibration. Принимайте только результаты с оценкой GOOD; при MARGINAL/FAILED — повторите, поднеся телефон ближе и снизив шум.
  4. Запишите BT delay каждой колонки. Колонка с максимальным значением — самая «медленная» по железу: у неё больше всего некомпенсированной задержки за sink’ом.
  5. В качестве отправной точки поднимайте static_delay_ms у каждой колонки примерно на this_rtt − min_rtt сверх текущего дефолта, чтобы каждая колонка декларировала задержку, близкую к её реальной hw-латентности. Например, если одна колонка даёт 180 мс, другая 260 мс — поставьте «260-мсной» примерно на 80 мс больше, чем «180-мсной».
  6. Доведите на слух в групповом воспроизведении. Изменения применяются на лету через IPC-команду set_static_delay_ms — перезапуск демона не требуется.

Bridge поддерживает idle standby: после настраиваемого периода тишины Bluetooth-соединение разрывается, а колонка переходит в режим ожидания. Плеер MA остаётся видимым, и при запуске воспроизведения bridge автоматически переподключается («wake-on-play»).

  1. Установите Idle standby (min) в раскрытой строке устройства (Configuration → Devices). Значение 0 — всегда подключено.
  2. По истечении заданного времени тишины bridge отключает Bluetooth и перенаправляет аудио на null sink PulseAudio.
  3. На карточке устройства появляется бейдж 💤 Standby и кнопка ☀️ Wake.
  4. Когда MA отправляет команду воспроизведения, bridge автоматически переподключает Bluetooth (~5 с задержки).
  5. Участники sync-группы будят друг друга: если одно устройство просыпается, остальные следуют за ним.

Длительность этого окна подключения полностью зависит от прошивки колонки и не может быть изменена мостом:

КатегорияПримерыОкно подключения
Стационарные (от сети)Sonos, Marshall Stanmore/Woburn, умные колонкиБесконечно (всегда включены)
Аккумуляторные, auto-off выключенSony XM4/5, Bose SoundLink, JBL (через companion-приложение)До разряда батареи (6–24 ч)
Аккумуляторные, auto-off настраиваетсяSony (5 мин–3 ч), Bose (5–60 мин), JBL (10–60 мин)Зависит от настройки
Аккумуляторные, фиксированный auto-offIKEA ENEBY/SYMFONISK (~15–20 мин), бюджетные колонкиНельзя изменить

Многие колонки позволяют отключить или увеличить таймер auto-off через companion-приложение или комбинацию кнопок:

  • Sony — Sony Headphones Connect → System → Auto Power Off → Do not turn off
  • Bose — Bose app → Settings → Auto-Off → Never, или удержание кнопки Mute 10 с
  • JBL — JBL Portable / JBL One app → Settings → Auto-Off → Disable
  • Jabra — Jabra Sound+ app → Headset settings → Auto-off

Команды Bluetooth-протокола для изменения этого параметра не существует — настраивать нужно на самом устройстве.

  • Для стационарных колонок: idle standby работает отлично при любом таймауте.
  • Для аккумуляторных с отключённым auto-off: настраивайте idle standby свободно; wake-on-play будет работать до разряда батареи.
  • Для колонок с фиксированным auto-off: ставьте idle_disconnect_minutes меньше таймера auto-off колонки, чтобы bridge успел переподключиться до глубокого сна.
  • Keep-alive и idle standby взаимоисключающи — при включённом keep-alive idle standby автоматически отключается.

Keep-alive отправляет периодическую тишину, чтобы колонка не засыпала. Idle standby намеренно отключает соединение после тишины. Эти две функции преследуют противоположные цели, поэтому одновременно активна может быть только одна:

  • В UI включение одной отключает другую.
  • Если обе заданы в конфиге, keep-alive имеет приоритет — idle-таймер пропускается (предупреждение в логе при старте).