Navidrome + ListenBrainz: сервер для треков и плейлистов

Настройте self‑hosted сервер Navidrome с интеграцией ListenBrainz: автоматический учёт прослушиваний, персональные плейлисты, поддержка Discovery для homelab.

Не указано
Алексей Кузнецов
Алексей Кузнецов
Системный администратор24 января 2026 г.

Подготовка окружения и структуры папок

Обновите систему, установите Docker и создайте директории для проекта. Это необходимо для хранения музыки, конфигов и баз данных.

# Обновление пакетов
sudo apt update && sudo apt upgrade -y

# Установка Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker

# Установка Docker Compose
sudo apt install docker-compose-plugin -y

# Создание структуры проекта
mkdir -p ~/music-platform/{musicdata,config,listenbrainz-data}
cd ~/music-platform

Настройка Docker Compose

Создайте файл docker-compose.yml, который определяет контейнеры Navidrome, ListenBrainz и PostgreSQL. Замените 'replace_with_strong_secret' на надежный ключ.

version: '3.8'

services:
  navidrome:
    image: deluan/navidrome:latest
    container_name: navidrome
    ports:
      - "4533:4533"
    volumes:
      - ./musicdata:/music:ro
      - ./config:/data
      - ./listenbrainz-data:/listenbrainz
    environment:
      - ND_SCANSCHEDULE=@every 1h
      - ND_LOGLEVEL=info
      - ND_BASEURL=/
      - ND_PORT=4533
      - ND_MUSICFOLDER=/music
    restart: unless-stopped
    networks:
      - music-net

  listenbrainz:
    image: metabrainz/listenbrainz:latest
    container_name: listenbrainz
    ports:
      - "8000:8000"
    volumes:
      - ./listenbrainz-data:/data
    environment:
      - LB_SECRET_KEY=replace_with_strong_secret
      - LB_DATABASE_URL=postgresql://listenbrainz:password@db/listenbrainz
    depends_on:
      - db
    restart: unless-stopped
    networks:
      - music-net

  db:
    image: postgres:14
    container_name: listenbrainz-db
    volumes:
      - ./listenbrainz-data/postgres:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=listenbrainz
      - POSTGRES_USER=listenbrainz
      - POSTGRES_PASSWORD=password
    restart: unless-stopped
    networks:
      - music-net

networks:
  music-net:
    driver: bridge

Запуск платформы

Запустите контейнеры в фоновом режиме и проверьте логи, чтобы убедиться в успешном запуске.

# Запуск контейнеров
docker compose up -d

# Проверка логов Navidrome
docker compose logs -f navidrome

# Проверка логов ListenBrainz
docker compose logs -f listenbrainz

Настройка Navidrome

Откройте http://localhost:4533, создайте администратора. Поместите музыкальные файлы в папку musicdata. Создайте конфиг navidrome.toml для точной настройки сканирования и вебхуков.

# Пример конфига config/navidrome.toml
[server]
port = 4533
address = "0.0.0.0"
scanSchedule = "@every 1h"

[auth]
jwtSecret = "your_jwt_secret_here"

[libraries]
[music]
path = "/music"
ignoreDot = true

[webhooks]
enabled = true
url = "http://your-script-host:5000/webhook"
events = ["track_played"]

Настройка ListenBrainz и интеграции

Откройте http://localhost:8000, зарегистрируйтесь и получите токен API в профиле. Для интеграции с Navidrome используйте Python-скрипт для отправки скробблов (прослушиваний) через API ListenBrainz, так как встроенного плагина нет.

# Установка зависимостей
sudo apt install python3-pip
pip3 install requests flask musicbrainzngs

# Пример скрипта scrobbler.py
import os
import json
import requests
from datetime import datetime

LB_URL = "http://localhost:8000"
LB_TOKEN = "ВАШ_ТОКЕН_ИЗ_LISTENBRAINZ"  # Получите в профиле

def send_listen(track, artist, album):
    payload = {
        "listen_type": "single",
        "payload": [{
            "listened_at": int(datetime.now().timestamp()),
            "track_metadata": {
                "track_name": track,
                "artist_name": artist,
                "release_name": album
            }
        }]
    }
    headers = {"Authorization": f"Token {LB_TOKEN}"}
    response = requests.post(f"{LB_URL}/1/submit-listens", json=payload, headers=headers)
    print(f"Status: {response.status_code}")

# Пример вызова
if __name__ == "__main__":
    send_listen("Track Name", "Artist Name", "Album Name")

Формирование рекомендаций Discovery

Используйте данные ListenBrainz для получения топ-артистов и поиска похожих через MusicBrainz API. Скрипт генерирует M3U плейлист или создает плейлист в Navidrome через Subsonic API.

import requests

LB_URL = "http://localhost:8000"
USERNAME = "ВАШ_ЮЗЕРНЕЙМ"

def get_top_artists():
    url = f"{LB_URL}/1/user/{USERNAME}/stats"
    response = requests.get(url)
    data = response.json()
    artists = data.get("artists", [])
    return [a["artist_name"] for a in artists[:10]]

def find_similar(artist):
    # Простой поиск по MusicBrainz
    mb_url = "https://musicbrainz.org/ws/2/artist/"
    params = {"query": artist, "fmt": "json"}
    headers = {"User-Agent": "music-platform/1.0"}
    response = requests.get(mb_url, params=params, headers=headers)
    # Упрощенная логика: возвращаем список условных похожих
    return [f"Similar to {artist} 1", f"Similar to {artist} 2"]

top = get_top_artists()
recommendations = []
for artist in top:
    recommendations.extend(find_similar(artist))

# Экспорт в M3U
with open("discovery_playlist.m3u", "w") as f:
    for rec in recommendations:
        f.write(f"#EXTINF:0,{rec}\n")
        f.write(f"https://your-server:4533/rest/download?u=admin&p=password&v=1.15.0&id=track_id\n")

print("Плейлист discovery_playlist.m3u создан.")

# Для создания в Navidrome используйте curl:
# curl -X POST "http://localhost:4533/rest/createPlaylist?u=admin&p=password&v=1.15.0&name=Discovery&songId=track1,track2"

Резервное копирование данных

Настройте регулярное копирование музыки и баз данных. Используйте rsync для файлов и pg_dump для PostgreSQL.

# Скрипт backup.sh
#!/bin/bash
BACKUP_DIR="/backup/music-platform"
mkdir -p $BACKUP_DIR

# Бэкап музыки
rsync -av ~/music-platform/musicdata/ $BACKUP_DIR/musicdata/

# Бэкап БД ListenBrainz
docker exec listenbrainz-db pg_dump -U listenbrainz listenbrainz > $BACKUP_DIR/listenbrainz.sql

# Архивация
tar -czf $BACKUP_DIR/backup-$(date +%Y%m%d).tar.gz $BACKUP_DIR/

# Очистка старых бэкапов (старше 7 дней)
find $BACKUP_DIR -name "backup-*.tar.gz" -mtime +7 -delete

# Добавление в cron (ежедневно в 2:00)
# 0 2 * * * ~/music-platform/backup.sh

Самостоятельное хранение музыки: построение платформы для навигации и открытия новых треков с помощью Navidrome и ListenBrainz

Введение

Современные стриминговые сервисы предлагают удобство, но часто ограничивают контроль над данными, алгоритмы рекомендаций и долгосрочную доступность контента. Самостоятельное хранение музыки (self-hosting) позволяет полностью владеть библиотекой, кастомизировать интерфейс и интегрироваться с открытыми системами для анализа предпочтений.

Решения вроде Spotify или Apple Music работают как закрытые экосистемы. Альтернатива на базе открытого ПО — Navidrome и ListenBrainz — дает:

  • Полный контроль над данными: музыка и метаданные хранятся на вашем сервере.
  • Открытый скробблинг: ListenBrainz, альтернатива Last.fm с открытыми данными и API.
  • Возможность построения персонализированных рекомендаций на основе ваших слушаний.
  • Интеграцию с домашним сервером и автоматизацией.

В этом гайде мы соберем платформу на Docker Compose: Navidrome как сервер и клиент для воспроизведения, ListenBrainz как база для анализа предпочтений. Предполагается базовое знакомство с Linux и командной строкой.

Основные компоненты

Navidrome — медиасервер для музыки с поддержкой Subsonic API. Основные возможности:

  • Сканирование библиотеки и генерация метаданных.
  • Веб-интерфейс и мобильные клиенты (Aurial, DSub, Substreamer).
  • Потоковое воспроизведение в форматах MP3, FLAC, OGG, AAC и др.
  • Пользователи и права доступа.

ListenBrainz — открытая платформа для скробблинга и анализа прослушиваний. Плюсы:

  • Независимость от коммерческих сервисов.
  • Экспорт данных в формате JSON/TSV.
  • Доступ к публичным данным для построения рекомендаций (например, через MusicBrainz).
  • Возможность интеграции с Navidrome через плагины или сторонние скрипты.

Архитектура платформы:

  1. Хранилище музыки: том Docker с FLAC/MP3 файлами.
  2. Navidrome: сервер + веб-интерфейс.
  3. ListenBrainz: контейнер или внешний сервис; в этом гайде используем официальный Docker-образ.
  4. Интеграция: Navidrome отправляет скробблы в ListenBrainz через плагин или скрипт.
  5. Постобработка: скрипты для формирования плейлистов на основе данных ListenBrainz.

Подготовка окружения

Для работы требуется Docker и Docker Compose. Установка на Ubuntu/Debian:

# Обновление пакетов
sudo apt update && sudo apt upgrade -y

# Установка Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker

# Установка Docker Compose (v2)
sudo apt install docker-compose-plugin -y

# Проверка
docker --version
docker compose version

Создайте структуру проекта:

mkdir ~/music-platform && cd ~/music-platform
mkdir -p musicdata config listenbrainz-data

Настройка томов для музыкальной библиотеки:

  • musicdata: папка с файлами музыки (FLAC/MP3). Поместите сюда свою коллекцию или скачайте тестовые файлы.
  • config: конфиги Navidrome.
  • listenbrainz-data: данные ListenBrainz (пользователи, история).

Пример структуры папок:

~/music-platform/
├── docker-compose.yml
├── musicdata/
│   ├── Artist1/
│   │   ├── Album1/
│   │   │   ├── 01 Track1.flac
│   │   │   └── cover.jpg
├── config/
│   └── navidrome.toml
└── listenbrainz-data/

docker-compose.yml — базовая конфигурация:

version: '3.8'

services:
  navidrome:
    image: deluan/navidrome:latest
    container_name: navidrome
    ports:
      - "4533:4533"
    volumes:
      - ./musicdata:/music:ro
      - ./config:/data
      - ./listenbrainz-data:/listenbrainz
    environment:
      - ND_SCANSCHEDULE=@every 1h
      - ND_LOGLEVEL=info
      - ND_BASEURL=/
      - ND_PORT=4533
      - ND_MUSICFOLDER=/music
    restart: unless-stopped
    networks:
      - music-net

  listenbrainz:
    image: metabrainz/listenbrainz:latest
    container_name: listenbrainz
    ports:
      - "8000:8000"
    volumes:
      - ./listenbrainz-data:/data
    environment:
      - LB_SECRET_KEY=replace_with_strong_secret
      - LB_DATABASE_URL=postgresql://listenbrainz:password@db/listenbrainz
    depends_on:
      - db
    restart: unless-stopped
    networks:
      - music-net

  db:
    image: postgres:14
    container_name: listenbrainz-db
    volumes:
      - ./listenbrainz-data/postgres:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=listenbrainz
      - POSTGRES_USER=listenbrainz
      - POSTGRES_PASSWORD=password
    restart: unless-stopped
    networks:
      - music-net

networks:
  music-net:
    driver: bridge

Примечания:

  • Замените replace_with_strong_secret на надежный ключ (например, сгенерированный через openssl rand -hex 32).
  • Для ListenBrainz требуется PostgreSQL; в примере используется встроенный контейнер.
  • Если порты заняты, измените ports (например, 4534:4533 для Navidrome).
  • Первый запуск может занять время на создание образов.

Запуск:

docker compose up -d

Проверка логов:

docker compose logs -f navidrome
docker compose logs -f listenbrainz

Настройка Navidrome

После запуска Navidrome доступен по http://localhost:4533. Первый вход — создание администратора.

Пользователи:

  1. Откройте веб-интерфейс.
  2. При первом запуске создайте админ-пользователя (логин/пароль).
  3. Добавьте обычных пользователей через интерфейс или конфиг.

Для автоматизации можно использовать файл конфигурации config/navidrome.toml:

# Пример конфига Navidrome
[server]
port = 4533
address = "0.0.0.0"
scanSchedule = "@every 1h"

[auth]
jwtSecret = "your_jwt_secret_here"

[libraries]
# Автоматическое сканирование папки /music
[music]
path = "/music"
ignoreDot = true

Сканирование библиотеки:

  • По умолчанию Navidrome сканирует автоматически по расписанию (установлено в docker-compose.yml: каждые 1 час).
  • Для принудительного сканирования: в веб-интерфейсе перейдите в "Settings" → "Scan".
  • Поддержка форматов: FLAC, MP3, OGG, AAC, ALAC, WAV. Убедитесь, что файлы имеют корректные теги (ID3 для MP3, Vorbis для FLAC).

Обложки альбомов:

  • Navidrome ищет файлы cover.jpg, folder.jpg или albumart.jpg в папке альбома.
  • Если обложки нет, можно загрузить через интерфейс: перейдите к альбому → "Edit" → "Upload Cover".
  • Для автоматизации используйте инструменты вроде beets (установка: pip install beets) для тегирования и загрузки обложек.

Поддержка потокового воспроизведения:

  • Navidrome транскодирует на лету, если клиент не поддерживает исходный формат (например, FLAC в MP3 для мобильных).
  • Настройки транскодирования в "Settings" → "Transcoding".
  • Для экономии трафика: установите битрейт (например, 128 kbps для MP3).
  • Тестирование: откройте трек в браузере или подключите клиент (например, Substreamer для Android).

Дополнительные настройки:

  • Персонализация: вкладки "Favorites", "Recently Added", "Genres".
  • Права доступа: админ может ограничивать доступ пользователей к определенным папкам.
  • Мобильные клиенты: установите приложение, использующее Subsonic API (например, DSub), и укажите адрес вашего сервера: http://your-server-ip:4533.

Интеграция ListenBrainz

ListenBrainz хранит историю прослушиваний и позволяет строить рекомендации. Регистрация:

  1. Перейдите на http://localhost:8000 (веб-интерфейс ListenBrainz).
  2. Создайте аккаунт (требуется email).
  3. Заполните профиль: любимые жанры, артисты.

Подключение аккаунта к Navidrome:

Navidrome не имеет встроенного плагина для ListenBrainz, но можно использовать сторонний скрипт. Пример на Python:

  1. Установите Python и зависимости:
sudo apt install python3-pip
pip3 install requests musicbrainzngs
  1. Создайте скрипт scrobbler.py:
import os
import json
import requests
from datetime import datetime

LB_URL = "http://listenbrainz:8000"
LB_TOKEN = "your_listenbrainz_token"  # Получите в профиле ListenBrainz

def send_listen(track, artist, album, duration):
    payload = {
        "listen_type": "single",
        "payload": [{
            "listened_at": int(datetime.now().timestamp()),
            "track_metadata": {
                "track_name": track,
                "artist_name": artist,
                "release_name": album
            }
        }]
    }
    headers = {"Authorization": f"Token {LB_TOKEN}"}
    response = requests.post(f"{LB_URL}/1/submit-listens", json=payload, headers=headers)
    print(f"Status: {response.status_code}")

# Пример: отправка скробла (вызов из Navidrome через webhook или cron)
if __name__ == "__main__":
    # Данные о треке (заполняются динамически)
    send_listen("Track Name", "Artist Name", "Album Name", 180)
  1. Интеграция: Navidrome поддерживает вебхуки для событий (в config/navidrome.toml):
[webhooks]
enabled = true
url = "http://your-script-host:5000/webhook"  # URL вашего скрипта
events = ["track_played"]

Запустите Flask-сервер для приема вебхуков:

pip3 install flask
# Создайте server.py и запустите: python3 server.py

Для простоты: используйте готовый интрумент вроде navidrome-listenbrainz-integration (замените на актуальный репозиторий) или настройте cron-скрипт, который парсит логи Navidrome.

Отправка скробблинга:

  • Navidrome записывает прослушивания в логи (файл navidrome.log в томе config).
  • Скрипт анализирует логи и отправляет данные в ListenBrainz.
  • Пример cron-задачи (каждые 5 минут):
*/5 * * * * cd ~/music-platform && python3 scrobbler.py

Формирование историй прослушивания:

  • В интерфейсе ListenBrainz: вкладка "Profile" → "History".
  • Экспорт данных: API http://localhost:8000/1/user/{username}/listens.
  • Анализ: используйте скрипты для подсчета топ-жанров или артистов.

Поиск и рекомендации

ListenBrainz предоставляет данные для построения персонализированных плейлистов "Discovery" (открытие новых треков).

Как использовать данные:

  1. Сбор данных: После нескольких недель скробблинга у вас будет история прослушиваний.
  2. Формирование плейлистов:
    • Используйте API MusicBrainz (интегрирован в ListenBrainz) для поиска похожих артистов.
    • Пример скрипта для генерации плейлиста "Discovery":
import requests

LB_URL = "http://localhost:8000"
USERNAME = "your_username"

def get_top_artists():
    url = f"{LB_URL}/1/user/{USERNAME}/stats"
    response = requests.get(url)
    data = response.json()
    artists = data.get("artists", [])
    return [a["artist_name"] for a in artists[:10]]

def find_similar(artist):
    # Используем MusicBrainz API для поиска похожих
    mb_url = "https://musicbrainz.org/ws/2/artist/"
    params = {"query": artist, "fmt": "json"}
    headers = {"User-Agent": "music-platform/1.0"}
    response = requests.get(mb_url, params=params, headers=headers)
    # Обработка результатов для рекомендаций
    # (упрощено: вернем 3 похожих артиста)
    return ["SimilarArtist1", "SimilarArtist2", "SimilarArtist3"]

top = get_top_artists()
recommendations = []
for artist in top:
    recs = find_similar(artist)
    recommendations.extend(recs)

# Создайте плейлист в Navidrome (через API) или экспортируйте в файл
with open("discovery_playlist.m3u", "w") as f:
    for rec in recommendations:
        f.write(f"#EXTINF:0,{rec}\n")
        f.write(f"https://your-server:4533/rest/download?u=admin&p=password&v=1.15.0&id=track_id\n")
  1. Интеграция с Navidrome: Используйте Subsonic API Navidrome для создания плейлистов:
    • API endpoint: /rest/createPlaylist.
    • Пример запроса: curl -X POST "http://localhost:4533/rest/createPlaylist?u=admin&p=password&v=1.15.0&name=Discovery&songId=track1,track2".

Продвинутые рекомендации:

  • Подключите Spotify API для дополнительных данных (опционально).
  • Используйте библиотеку spotipy для Python.
  • Периодически обновляйте плейлисты через cron.

Продвинутые сценарии

Автоматизация:

  • Запуск сканирования по расписанию: уже настроен в docker-compose.yml.
  • Автоматический импорт новой музыки: используйте inotify-tools для мониторинга папки:
sudo apt install inotify-tools
# Скрипт для обработки новых файлов
inotifywait -m /path/to/music -e create | while read path action file; do
  docker exec navidrome sh -c "navidrome scan"
done

Интеграция с домашним сервером (Home Assistant):

Home Assistant позволяет управлять Navidrome через медиа-плеер.

  1. Установите Home Assistant (Docker):
docker run -d --name homeassistant -p 8123:8123 ghcr.io/home-assistant/home-assistant:stable
  1. Настройте интеграцию через configuration.yaml:
media_player:
  - platform: subsonic
    host: localhost
    port: 4533
    username: admin
    password: your_password
    ssl: false
  1. Управление: голосовые команды (через Alexa/Google) для воспроизведения плейлистов.

Резервное копирование:

  • Музыка: регулярное копирование musicdata на внешний диск или в облако (rsync).
  • Данные Navidrome и ListenBrainz: бэкап томов Docker.

Пример скрипта backup.sh:

#!/bin/bash
BACKUP_DIR="/backup/music-platform"
mkdir -p $BACKUP_DIR
# Бэкап музыки
rsync -av ~/music-platform/musicdata/ $BACKUP_DIR/musicdata/
# Бэкап конфигов и данных БД
docker exec listenbrainz-db pg_dump -U listenbrainz listenbrainz > $BACKUP_DIR/listenbrainz.sql
# Архивация
tar -czf $BACKUP_DIR/backup-$(date +%Y%m%d).tar.gz $BACKUP_DIR/
# Очистка старых (оставить 7 дней)
find $BACKUP_DIR -name "backup-*.tar.gz" -mtime +7 -delete

Запуск через cron: 0 2 * * * ~/music-platform/backup.sh.

Преимущества и ограничения

Преимущества:

  • Стоимость: Один раз оплачивается хостинг (сервер или VPS от 5$/мес) или используйте домашний сервер (Raspberry Pi). Нет ежемесячных подписок.
  • Управление данными: Полный контроль; экспортируйте в любой формат. ListenBrainz — открытые данные, нет локдаунов.
  • Производительность: На современном железе (4+ ядра, 8+ RAM) Navidrome работает быстро даже с 100K+ треками. Латентность зависит от сети.
  • Кастомизация: Измените UI, добавьте скрипты, интегрируйте с другими сервисами.

Ограничения:

  • Начальные затраты: Время на настройку (2-4 часа) и железо. Без тех. навыков сложно.
  • Поддержка форматов: Не все форматы (например, Apple Lossless) поддерживаются без транскодинга.
  • Мобильные клиенты: Нет официального приложения; требуется стороннее (но много бесплатных).
  • Сетевые вопросы: Доступ извне требует настройки DNS/DDNS и SSL (используйте Let's Encrypt).
  • Масштабирование: Для больших библиотек (>1M треков) может потребоваться оптимизация БД.

Сравнение с Spotify:

  • Плюс: Нет рекламы, данные ваши.
  • Минус: Нет "радио" на базе AI (но можно приблизиться через ListenBrainz).

Заключение и призыв к действию

Самостоятельное хранение музыки с Navidrome и ListenBrainz — это мощная платформа для энтузиастов homelab и любителей музыки, которые ценят контроль и открытость. Вы получаете не только плеер, но и инструмент для анализа предпочтений и построения рекомендаций, интегрируемый с домашней автоматизацией.

Начните с малого: установите Docker, запустите контейнеры и добавьте несколько треков. Экспериментируйте с интеграциями — это инвестиция в ваш цифровой ассет. Если вы готовы к настройке, попробуйте уже сегодня. Для вопросов обратитесь к документации Navidrome (navidrome.org) или сообществу ListenBrainz (community.metabrainz.org).

Поделиться:TelegramX / TwitterVK