๐Ÿ“ฆ jordojordo / resonance

Self-hosted music discovery pipeline with Navidrome, ListenBrainz, and Slskd

โ˜… 5 stars โ‘‚ 0 forks ๐Ÿ‘ 5 watching โš–๏ธ Apache License 2.0
listenbrainzmpdnavidromeself-hostedslskdsubsonicvibe
๐Ÿ“ฅ Clone https://github.com/jordojordo/resonance.git
HTTPS git clone https://github.com/jordojordo/resonance.git
SSH git clone git@github.com:jordojordo/resonance.git
CLI gh repo clone jordojordo/resonance
jordonet jordonet fix(preview): add album track selection for preview playback (#47) 99ca736 18 hours ago ๐Ÿ“ History
๐Ÿ“‚ master View all commits โ†’
๐Ÿ“ .github
๐Ÿ“ docs
๐Ÿ“ examples
๐Ÿ“ server
๐Ÿ“ ui
๐Ÿ“„ .dockerignore
๐Ÿ“„ .gitignore
๐Ÿ“„ CLAUDE.md
๐Ÿ“„ CONTRIBUTING.md
๐Ÿ“„ Dockerfile
๐Ÿ“„ LICENSE
๐Ÿ“„ package.json
๐Ÿ“„ pnpm-lock.yaml
๐Ÿ“„ README.md
๐Ÿ“„ README.md

Resonance

License Docker

Resonance is a self-hosted music discovery pipeline that automatically finds and downloads music based on your listening habits and existing library. It combines multiple discovery sources into a unified approval workflow with a modern web UI.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                              RESONANCE                                      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                             โ”‚
โ”‚    Your Music Library          Your Listening History                       โ”‚
โ”‚    (Navidrome/etc)             (ListenBrainz scrobbles)                     โ”‚
โ”‚          โ”‚                              โ”‚                                   โ”‚
โ”‚          โ–ผ                              โ–ผ                                   โ”‚
โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                             โ”‚
โ”‚    โ”‚ Catalog   โ”‚                 โ”‚ lb-fetch   โ”‚                             โ”‚
โ”‚    โ”‚ Discovery โ”‚                 โ”‚            โ”‚                             โ”‚
โ”‚    โ”‚ (Last.fm) โ”‚                 โ”‚(ListenBrainz)                            โ”‚
โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜                             โ”‚
โ”‚          โ”‚                              โ”‚                                   โ”‚
โ”‚          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                   โ”‚
โ”‚                         โ–ผ                                                   โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚              โ”‚   Pending Queue     โ”‚โ—„โ”€โ”€โ”€โ”€ Web UI (approve/reject)           โ”‚
โ”‚              โ”‚  (unified approval) โ”‚                                        โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚                         โ–ผ                                                   โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚              โ”‚  slskd-downloader   โ”‚                                        โ”‚
โ”‚              โ”‚   (Soulseek P2P)    โ”‚                                        โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚                         โ–ผ                                                   โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                        โ”‚
โ”‚              โ”‚  Downloaded Music   โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Your Music Library              โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                        โ”‚
โ”‚                                                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Features

  • Multi-source discovery - Combines ListenBrainz recommendations (based on what you listen to) with Last.fm similar artists (based on what you own)
  • Unified approval queue - Review all recommendations in one place before downloading
  • Preview player - Listen to 30-second audio previews before approving (via Deezer/Spotify)
  • Web UI - Dashboard with cover art, metadata, and one-click approve/reject
  • Automatic downloads - Integrates with slskd (Soulseek) for P2P music downloads
  • Library awareness - Checks your existing library to avoid duplicates
  • Flexible auth - Built-in API auth or integrate with Authelia/OAuth
  • Single container - Everything runs in one Docker image

Quick Start

Prerequisites

1. Create configuration

mkdir -p resonance/data
cd resonance

Create config.yaml:

# See examples/config.yaml for full configuration options

# ListenBrainz recommendations (based on listening history)
listenbrainz:
  username: "your_username"
  token: "your_token"           # From https://listenbrainz.org/settings/
  approval_mode: "manual"       # "auto" or "manual"

mode: album                     # "album" or "track"
fetch_count: 100

# slskd connection
slskd:
  host: "http://slskd:5030"
  api_key: "your_slskd_api_key"
  # Optional: Advanced search configuration (see docs/configuration.md)
  # search:
  #   album_query_template: "{artist} {album}"
  #   exclude_terms: ["live", "remix", "cover"]
  #   retry:
  #     enabled: true
  #     max_attempts: 3

# Catalog discovery (based on library artists โ†’ Last.fm similar)
catalog_discovery:
  enabled: true
  navidrome:
    host: "http://navidrome:4533"
    username: "your_username"
    password: "your_password"
  lastfm:
    api_key: "your_lastfm_api_key"
  max_artists_per_run: 10
  min_similarity: 0.3
  mode: "manual"

# Avoid downloading albums you already own (Optional)
library_duplicate:
  enabled: true
  # Auto-reject items that already exist in your library
  auto_reject: false

# Web UI settings
ui:
  auth:
    enabled: true
    type: "basic"               # "basic", "api_key", or "proxy"
    username: "admin"
    password: "changeme"        # Change this!

2. Run with Docker Compose

Create docker-compose.yaml:

services:
  resonance:
    image: ghcr.io/jordojordo/resonance:latest
    container_name: resonance
    volumes:
      - ./config.yaml:/config/config.yaml:ro
      - ./data:/data
    ports:
      - "8080:8080"
    restart: unless-stopped

docker compose up -d

3. Access the UI

Open http://localhost:8080 and log in with your configured credentials.

Discovery Sources

ListenBrainz (lb-fetch)

Fetches track recommendations from ListenBrainz based on your listening history (scrobbles). Recommendations are resolved to albums via MusicBrainz.

How it works:

  • You listen to music โ†’ Navidrome scrobbles to ListenBrainz
  • ListenBrainz builds a taste profile and generates recommendations
  • lb-fetch pulls recommendations every 6 hours
  • Tracks are resolved to parent albums
  • Albums go to pending queue (manual mode) or wishlist (auto mode)
Requirements:
  • ListenBrainz account with active scrobbling
  • Several weeks of listening history for good recommendations

Catalog Discovery

Finds new artists similar to ones you already own using Last.fm's similarity data.

How it works:

  • Scans your Navidrome library for artists
  • Queries Last.fm for similar artists
  • Ranks by aggregate similarity (artists similar to multiple library artists score higher)
  • Fetches discographies from MusicBrainz
  • Albums go to pending queue (manual mode) or wishlist (auto mode)
Requirements:
  • Navidrome with Subsonic API enabled
  • Last.fm API key

Configuration Reference

See docs/configuration.md for full configuration options.

Web UI

The web UI provides:

  • Dashboard - Quick stats and recent activity
  • Pending Queue - Review and approve/reject recommendations
  • Downloads - Monitor slskd download status
  • Settings - Configure discovery parameters

Authentication

Built-in Auth

Resonance includes built-in authentication options:

ui:
  auth:
    enabled: true
    type: "basic"        # HTTP Basic Auth
    username: "admin"
    password: "secure_password"

Or use API key authentication:

ui:
  auth:
    enabled: true
    type: "api_key"
    api_key: "your_secret_api_key"

Authelia Integration

For advanced authentication (SSO, 2FA, LDAP), integrate with Authelia via your reverse proxy. See docs/authelia-integration.md.

API

Resonance exposes a REST API for automation and integration:

GET  /api/v1/queue/pending      # List pending items
POST /api/v1/queue/approve      # Approve items
POST /api/v1/queue/reject       # Reject items
POST /api/v1/actions/lb-fetch   # Trigger lb-fetch
POST /api/v1/actions/catalog    # Trigger catalog discovery
GET  /api/v1/library/stats      # Library sync statistics
POST /api/v1/library/sync       # Trigger library sync
POST /api/v1/library/organize   # Trigger library organize
GET  /api/v1/library/organize/status # Library organize status
GET  /api/v1/health             # Health check

See docs/api.md for full API documentation.

Architecture

Resonance runs as a single Node.js process with background jobs scheduled via node-cron:

JobSchedulePurpose
lb-fetchEvery 6 hoursListenBrainz recommendations
catalog-discoveryWeeklyLast.fm similar artists
slskd-downloaderEvery hourProcess wishlist via slskd
library-syncDailySync Navidrome library albums
library-organizeManual (default)Move completed downloads into library
The web interface is served by Express with a Vue 3 ui.

See docs/architecture.md for technical details.

Environment Variables

VariableDefaultDescription
PORT8080HTTP server port
LOG_LEVELinfoLogging verbosity
LOG_TO_CONSOLEtrueLog to stdout/stderr
LOG_TO_FILEfalseLog to files in LOG_DIR
LOG_DIRDATA_PATHDirectory for log files (when enabled)
LB_FETCH_INTERVAL21600Seconds between lb-fetch runs (6h)
CATALOG_INTERVAL604800Seconds between catalog discovery (7d)
SLSKD_INTERVAL3600Seconds between download runs (1h)
RUN_JOBS_ON_STARTUPtrueRun discovery jobs immediately on startup
LIBRARY_SYNC_INTERVAL86400Seconds between library sync runs (24h)
LIBRARY_ORGANIZE_INTERVAL0Seconds between library organize runs (0 = manual only)

Data Directory

All state is stored in /data:

/data/
โ”œโ”€โ”€ resonance.sqlite          # SQLite database (queue, processed items, etc.)
โ””โ”€โ”€ wishlist.txt              # Albums to download (read by slskd-downloader)

Network Requirements

Resonance needs network access to:

ServicePurpose
slskdQueue downloads
NavidromeScan library artists
api.listenbrainz.orgFetch recommendations
ws.audioscrobbler.comLast.fm similar artists
musicbrainz.orgAlbum metadata
coverartarchive.orgAlbum artwork
api.deezer.comAudio previews (default)
api.spotify.comAudio previews (optional fallback)

Development

Building from source

git clone https://github.com/jordojordo/resonance.git
cd resonance
docker build -t resonance .

Running locally

pnpm --filter server install
pnpm --filter ui install

pnpm dev # Starts on http://localhost:5173, runs UI and server in parallel

See CONTRIBUTING.md for development guidelines.

Roadmap

  • ListenBrainz recommendations (lb-fetch)
  • Catalog-based discovery (Last.fm similar artists)
  • Unified pending queue with manual approval
  • Web UI with Vue 3 ui
  • Node.js/TypeScript server migration
  • Download status dashboard
  • Library duplicate checking
  • Socket updates
  • Mobile-responsive design
  • Notification webhooks (Discord, etc.)

Related Projects

  • slskd - Modern Soulseek client
  • Navidrome - Music streaming server
  • ListenBrainz - Open music listening data
  • Lidarr - Music collection manager (alternative approach)

License

Apache License 2.0 - See LICENSE for details.

Acknowledgments


Resonance - Let your music library guide you to new discoveries.