Как управлять музыкой в умном доме?

Проблема

Не скажу, что я заядлый меломан, но музыка у меня всегда звучит фоном — она помогает держать дневной рабочий ритм. Слушаю много и очень разное: смена направлений не даёт уху привыкнуть и держит в тонусе. Львиную долю времени я слушаю собственный медиасервер. Там собрано только то, что мне действительно нравится, — но нет развитой системы рекомендаций, выравнивания звука и прочих аудиофильских фишек. Можно, конечно, слушать через стриминговые платформы: там и рекомендации умные, и звук выровнен, и других плюшек хватает. Но там многого просто нет — в силу текущей политической ситуации, да и в принципе не может быть. К тому же платформы неохотно делятся своими наработками и привязывают прослушивание к своим сервисам и/или аудиоустройствам, а их рекомендации заточены на удержание слушателя на платформе. В идеале хотелось бы получить один собственный сервис, который вберёт все плюсы обоих подходов и избавит от минусов.

Долгое время я относился к Home Assistant (далее HA) исключительно как к системе для автоматизации умного дома. Да, я знал, что в его арсенале есть поддержка DLNA, Chromecast, AirPlay и множества других протоколов, но воспринимал это скорее как приятный бонус, а не как основу для организации домашней аудиосистемы. HA — это целая операционная система, требующая постоянно работающего сервера, с большим количеством встроенных сервисов, которые не имеют отношения к музыке. Казалось бы, не про Hi-Fi всё это.

Однако в поисках удобного способа воспроизведения я в конце концов наткнулся на Music Assistant (далее — MA). MA — это менеджер музыкальной библиотеки, интегрируемый в HA. Он поддерживает как офлайн-контент, так и множество различных онлайн-сервисов и может транслировать вашу музыку на широкий спектр поддерживаемых проигрывателей. Но самое интересное здесь то, что это не «ещё один плеер», в котором можно войти в один из сервисов и пользоваться каждым по отдельности. Здешняя «кухня» по своей организации больше напоминает то, как это устроено в ROON.

В этой статье попробуем настроить MA.

        ---
title: Схема работы Music Assistant
---
flowchart TD
    subgraph Users [Пользователи]
        U1[Веб-интерфейс MA]
        U2[Home Assistant UI]
        U3[Голосовые команды]
    end

    subgraph Core [Ядро системы]
        MA[Music Assistant Server]
        HA[Home Assistant]
    end

    subgraph Providers [Музыкальные провайдеры]
        MP1[Spotify / Tidal / Qobuz]
        MP2[Яндекс.Музыка]
        MP3[Локальные файлы / Jellyfin]
    end

    subgraph Players [Плееры и устройства]
        PP1[AirPlay / Chromecast / DLNA]
        PP2[Яндекс.Станция]
        PP3[Sonos / Другие]
    end

    U1 --> MA
    U2 --> HA
    U3 --> HA
    HA <--> MA
    MA --> MP1
    MA --> MP2
    MA --> MP3
    MA --> PP1
    MA --> PP2
    MA --> PP3
    

docker-compose

Создаём файлы и необходимые каталоги:

mkdir config_music_assistant
touch docker-compose.yml

Редактируем через nano docker-compose.yml:

services:
  music-assistant-server:
    image: ghcr.io/music-assistant/server:latest
    container_name: music-assistant-server
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./config_music_assistant:/data/
    cap_add:
      - SYS_ADMIN
      - DAC_READ_SEARCH
    security_opt:
      - apparmor:unconfined
    environment:
      - LOG_LEVEL=debug

По умолчанию сервис будет доступен по адресу http://<ip>:8095. Добавляем источники музыки, я добавил следующие:

Название источника

Описание

Jellyfin Media Server Library

Слушайте музыку в потоковом режиме с вашего собственного сервера Jellyfin.

Music Assistant

Встроенный/универсальный провайдер, обрабатывающий универсальные адреса и плейлисты.

Radio Paradise

Слушайте эклектичный радио-микс, составленный людьми (всегда без рекламы) — проект, поддерживаемый слушателями и любимый во всем мире.

Yandex Music Vadim

Потоковая музыка, персональные рекомендации и FLAC без потерь качества в «Яндекс Музыке», включая подборку «Моя волна» и синхронизацию с библиотекой.

Для проигрывания у меня настроены следующие провайдеры плееров:

Название провайдера

Описание

Bluesound

Передавайте аудиосигнал высокого разрешения на колонки Bluesound и мультирум-системы.

Chromecast

Транслируйте музыку и подкасты на устройства Chromecast или Google Cast.

DLNA

Воспроизводите музыку на поддерживаемых устройствах, совместимых с UPnP/DLNA.

Home Assistant MediaPlayers

Управляйте воспроизведением музыки на (поддерживаемых) медиаплеерах Home Assistant в вашем умном доме.

Sendspin

Sendspin — это протокол воспроизведения, управления и синхронизации аудио, разработанный фондом Open Home Foundation; он является встроенным протоколом воспроизведения в приложении Music Assistant и используется для воспроизведения на поддерживаемых клиентах, таких как веб-интерфейс Music Assistant, поддерживаемые (мобильные) клиенты и поддерживаемое оборудование.

Sync Group Player

Создавайте (постоянные) группы синхронизации, чтобы объединить колонки, поддерживающие совместимые протоколы/экосистемы, для синхронного воспроизведения звука.

Universal Player

Предоставляет поддержку для плееров, для которых в приложении Music Assistant отсутствует собственный (специфичный для производителя) провайдер, но которые поддерживают один или несколько универсальных протоколов потоковой передачи, таких как AirPlay, Chromecast или DLNA. Создается автоматически для устройств, поддерживающих только протоколы.

Yandex Station

Воспроизведение музыки на умных колонках «Яндекс Станция» через локальный протокол «Глагол».

Добавляем плееры для проигрывания, у меня такой список:

Название плеера

Устройство / Модель

Провайдеры (протоколы)

Яндекс Мини

Яндекс / Станция Мини (2019)

Home Assistant MediaPlayers

TV

Xiaomi / MiTV-MZTU1

Chromecast, Sendspin

Web (Firefox on Linux)

Unknown / Web Player

Sendspin

Добавляем провайдеров метаданных:

Название провайдера

Описание

Cover Art Archive

Предоставляет обложки альбомов из Cover Art Archive — официального хранилища обложек для MusicBrainz.

fanart.tv

Предоставляет высококачественные изображения исполнителей и обложки альбомов с сайта Fanart.tv, которые используются во всем пользовательском интерфейсе Music Assistant.

Genius Lyrics

Альтернативный источник текстов песен, берущий тексты с сайта Genius в качестве дополнения к материалам других провайдеров.

iTunes Artwork

Предоставляет высококачественные изображения исполнителей и обложки альбомов с сайта Fanart.tv, которые используются во всем пользовательском интерфейсе Music Assistant.

Last.fm

Получайте музыкальные рекомендации от Last.fm на основе вашей истории прослушивания.

LRCLIB

Основной провайдер текстов песен, предоставляющий синхронизированные и несинхронизированные тексты из базы данных LrcLib.

MusicBrainz

MusicBrainz — это открытая музыкальная энциклопедия, которая собирает метаданные о музыке и предоставляет их в открытый доступ. Music Assistant использует MusicBrainz в первую очередь для идентификации (уникальных) медиафайлов, поэтому этот источник данных отключить невозможно. Однако обратите внимание, что поиск будет осуществляться только в том случае, если эта информация отсутствует локально.

Playlist Metadata

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

The Audio DB

Предоставляет изображения исполнителей, обложки альбомов и подробные текстовые метаданные из TheAudioDB для использования в пользовательском интерфейсе Music Assistant.

Wikipedia

Поставщик многоязычных биографий исполнителей и других сопутствующих текстов.

В соответствующем разделе подключаем удаленный доступ.

Умный дом

Если всё верно настроено, то HA сам найдёт MA и предложит добавить его к вашим интеграциям. Через HACS устанавливаем Music Assistant Media Player Card

При необходимости можем сделать автоматизацию, например, каждый день включать отобранную музыку:

[
    {
        "id": "1111111111111111",
        "type": "inject",
        "z": "a1b2c3d4e5f60789",
        "name": "19:00 Ежедневно",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "00 19 * * *",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 150,
        "y": 160,
        "wires": [
            [
                "2222222222222222"
            ]
        ]
    },
    {
        "id": "2222222222222222",
        "type": "api-call-service",
        "z": "a1b2c3d4e5f60789",
        "name": "Включить плейлист",
        "server": "28fc66d2974fc1f6",
        "version": 7,
        "debugenabled": false,
        "action": "media_player.play_media",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "media_player.gostinaia_tv"
        ],
        "labelId": [],
        "data": "{\"media_content_id\":\"library://playlist/56\",\"media_content_type\":\"playlist\"}",
        "dataType": "json",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "blockInputOverrides": false,
        "domain": "media_player",
        "service": "play_media",
        "x": 380,
        "y": 160,
        "wires": [
            [
                "3333333333333333"
            ]
        ]
    },
    {
        "id": "3333333333333333",
        "type": "api-call-service",
        "z": "a1b2c3d4e5f60789",
        "name": "Установить громкость 30%",
        "server": "28fc66d2974fc1f6",
        "version": 7,
        "debugenabled": false,
        "action": "media_player.volume_set",
        "floorId": [],
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "media_player.gostinaia_tv"
        ],
        "labelId": [],
        "data": "{\"volume_level\":0.3}",
        "dataType": "json",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "blockInputOverrides": false,
        "domain": "media_player",
        "service": "volume_set",
        "x": 660,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "28fc66d2974fc1f6",
        "type": "server",
        "name": "Home Assistant",
        "version": 6,
        "addon": false,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": [
            "y",
            "yes",
            "true",
            "on",
            "home",
            "open"
        ],
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30",
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": ": ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "default",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": false
    },
    {
        "id": "6138a49f25a26822",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-home-assistant-websocket": "0.80.3"
        }
    }
]

Смартфон

Я установил из Google Play или см. на странице разработчиков. В своих проектах использую Nginx Proxy Manager, но быстро не смог подобрать нужную конфигурацию, поэтому пробросил порты на роутере и подключаюсь напрямую через ip:port.

Итог

Что имеем после произведённых изменений:

  1. Единая библиотека музыки из всех ваших сервисов (медиасервер, Yandex Music, локальные файлы) в одном интерфейсе.

  2. Трансляция музыки на широкий спектр поддерживаемых проигрывателей, включая Яндекс.Станции.

  3. Автоматизации.

Music Assistant превращает Home Assistant в полноценный музыкальный центр, который объединяет все ваши источники музыки и все ваши плееры в единую экосистему. Это не просто «ещё один плеер», а полноценный менеджер музыкальной библиотеки, который по своей организации не уступает коммерческим решениям вроде ROON.

Ссылки:

  1. Зачем нужен собственный сервер в 2025?

  2. Как установить Docker?

  3. Как запустить медиасервер?

  4. Как запустить сервис по управлению умным домом?

  5. Как запустить прокси-сервер для сервисов?