Navidrome + ListenBrainz: сервер для треков и плейлистов
Настройте self‑hosted сервер Navidrome с интеграцией ListenBrainz: автоматический учёт прослушиваний, персональные плейлисты, поддержка Discovery для homelab.
Подготовка окружения и структуры папок
Обновите систему, установите 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 через плагины или сторонние скрипты.
Архитектура платформы:
- Хранилище музыки: том Docker с FLAC/MP3 файлами.
- Navidrome: сервер + веб-интерфейс.
- ListenBrainz: контейнер или внешний сервис; в этом гайде используем официальный Docker-образ.
- Интеграция: Navidrome отправляет скробблы в ListenBrainz через плагин или скрипт.
- Постобработка: скрипты для формирования плейлистов на основе данных 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. Первый вход — создание администратора.
Пользователи:
- Откройте веб-интерфейс.
- При первом запуске создайте админ-пользователя (логин/пароль).
- Добавьте обычных пользователей через интерфейс или конфиг.
Для автоматизации можно использовать файл конфигурации 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 хранит историю прослушиваний и позволяет строить рекомендации. Регистрация:
- Перейдите на
http://localhost:8000(веб-интерфейс ListenBrainz). - Создайте аккаунт (требуется email).
- Заполните профиль: любимые жанры, артисты.
Подключение аккаунта к Navidrome:
Navidrome не имеет встроенного плагина для ListenBrainz, но можно использовать сторонний скрипт. Пример на Python:
- Установите Python и зависимости:
sudo apt install python3-pip
pip3 install requests musicbrainzngs
- Создайте скрипт
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)
- Интеграция: 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" (открытие новых треков).
Как использовать данные:
- Сбор данных: После нескольких недель скробблинга у вас будет история прослушиваний.
- Формирование плейлистов:
- Используйте 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")
- Интеграция с 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".
- API endpoint:
Продвинутые рекомендации:
- Подключите 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 через медиа-плеер.
- Установите Home Assistant (Docker):
docker run -d --name homeassistant -p 8123:8123 ghcr.io/home-assistant/home-assistant:stable
- Настройте интеграцию через
configuration.yaml:
media_player:
- platform: subsonic
host: localhost
port: 4533
username: admin
password: your_password
ssl: false
- Управление: голосовые команды (через 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).