124 lines
5.2 KiB
Markdown
124 lines
5.2 KiB
Markdown
# VibeSonic
|
|
|
|
VibeSonic is a lightweight, self-hosted music/media server written in Go.
|
|
It follows the same philosophy as other small `Vibe*` tools: a single Go
|
|
binary, SQLite storage, server-rendered Bootstrap 5 templates, dark mode
|
|
by default, minimal JavaScript, and no external services (no Redis, no
|
|
message broker, no microservices, nothing Kubernetes-specific).
|
|
|
|
**This is Phase 2 of 4.** Phase 1 built the foundation (config, schema,
|
|
auth, scanner, metadata, streaming, cover art, web UI shell). Phase 2
|
|
adds a **complete implementation of the original Subsonic REST API
|
|
through version 1.16.1** under `/rest/*` — every endpoint, backed by
|
|
real data, including transcoding, HLS, a real mpv-backed jukebox, and a
|
|
real podcast subsystem. See
|
|
[`docs/subsonic-compatibility.md`](docs/subsonic-compatibility.md) for
|
|
the full endpoint-by-endpoint matrix. OpenSubsonic extensions are not
|
|
yet implemented (Phase 3).
|
|
|
|
## Features
|
|
|
|
### Phase 1: foundation
|
|
|
|
- SQLite storage (WAL mode, foreign keys, versioned migrations) with a
|
|
schema already modeling artists, albums, songs, genres, contributors,
|
|
playlists, favorites, ratings, scrobbles, playback history, bookmarks,
|
|
play queues, shares, podcasts, internet radio, and settings
|
|
- Native authentication: Argon2id password hashing, HTTP-only signed
|
|
session cookies, CSRF-protected forms, session revocation
|
|
- Optional Navidrome-style external authentication via a trusted reverse
|
|
proxy header, gated on the real TCP peer address (never on
|
|
spoofable `X-Forwarded-For`/`X-Real-IP`/`Forwarded` headers)
|
|
- A library scanner supporting multiple music folders, incremental
|
|
rescans, new/changed/deleted/renamed file detection, and a bounded
|
|
worker pool — never a blind full rebuild
|
|
- Real metadata extraction via `ffprobe` (multi-artist, multi-genre,
|
|
MusicBrainz IDs, ReplayGain, embedded artwork/lyrics, sort fields, and
|
|
more)
|
|
- Stable, opaque, URL-safe IDs that survive restarts and rescans
|
|
- Direct media streaming with HTTP range request support, correct MIME
|
|
types, and no full-file buffering
|
|
- Cover art discovery (embedded artwork or folder images) with a
|
|
resized-image disk cache
|
|
- A server-rendered, dark-mode, keyboard-friendly web UI: browsing,
|
|
search, playlists, favorites, a persistent bottom player, and an admin
|
|
section (users, music folders, scanner status, system settings)
|
|
- `/healthz` and `/readyz`
|
|
|
|
### Phase 2: Subsonic REST API
|
|
|
|
- All 76 endpoints of the original Subsonic API through 1.16.1 —
|
|
browsing (filesystem and ID3), search, playlists, favorites/ratings/
|
|
scrobbling, sharing, user management with the full permission model,
|
|
bookmarks, play queue, chat, and library scan status
|
|
- Real ffmpeg-backed transcoding (mp3/opus/aac) and HLS segmenting for
|
|
`stream`/`hls`, bounded concurrency, killed on client disconnect
|
|
- A real podcast subsystem: RSS feed refresh, bounded background
|
|
downloads, restart recovery, downloaded episodes stream like any other
|
|
song
|
|
- A real jukebox backed by `mpv` over its JSON IPC socket — server-side
|
|
playback, not a simulation; administratively unavailable (with a clear
|
|
error) if `mpv` isn't installed
|
|
- Both original Subsonic auth modes (token/salt and password, including
|
|
`enc:` hex), verified against an AES-256-GCM-encrypted credential kept
|
|
separate from the Argon2id hash used for native login — see
|
|
[`docs/subsonic-compatibility.md`](docs/subsonic-compatibility.md#authentication)
|
|
- `/rest/*` authentication is entirely independent of the browser
|
|
session/CSRF/external-auth flow
|
|
|
|
## Quick start
|
|
|
|
```
|
|
go build -o vibesonic ./cmd/vibesonic
|
|
VIBESONIC_SESSION_SECRET=$(openssl rand -hex 32) ./vibesonic
|
|
```
|
|
|
|
Then open `http://localhost:8080` — on a fresh database you'll land on
|
|
the setup wizard, which creates the administrator account, your first
|
|
music folder, and kicks off the first scan.
|
|
|
|
`ffmpeg`/`ffprobe` should be on `PATH` (or pointed to via
|
|
`VIBESONIC_FFMPEG_PATH`/`VIBESONIC_FFPROBE_PATH`) for metadata reading,
|
|
cover art extraction, and transcoding/HLS to work. `mpv` should be on
|
|
`PATH` (or pointed to via `VIBESONIC_MPV_PATH`) for the jukebox to be
|
|
available — without it, `jukeboxControl` returns a clear "unavailable"
|
|
error rather than pretending to work.
|
|
|
|
### Docker
|
|
|
|
```
|
|
docker compose up -d
|
|
```
|
|
|
|
See [`docker-compose.yml`](docker-compose.yml) — mount your music
|
|
directory read-only at `/music` and set `VIBESONIC_SESSION_SECRET`.
|
|
|
|
### systemd
|
|
|
|
See [`systemd/vibesonic.service`](systemd/vibesonic.service).
|
|
|
|
## Configuration
|
|
|
|
VibeSonic is configured entirely through `VIBESONIC_*` environment
|
|
variables — see [`docs/configuration.md`](docs/configuration.md) for the
|
|
full list and defaults. There is no separate config file.
|
|
|
|
## Documentation
|
|
|
|
- [`docs/architecture.md`](docs/architecture.md) — how the pieces fit together
|
|
- [`docs/configuration.md`](docs/configuration.md) — every environment variable
|
|
- [`docs/external-auth.md`](docs/external-auth.md) — trusted reverse-proxy authentication
|
|
- [`docs/subsonic-compatibility.md`](docs/subsonic-compatibility.md) — protocol endpoint status
|
|
|
|
## Development
|
|
|
|
```
|
|
go fmt ./...
|
|
go vet ./...
|
|
go test ./...
|
|
```
|
|
|
|
Most tests exercise real SQLite databases and, where relevant, the real
|
|
`ffmpeg`/`ffprobe` binaries (skipped automatically if not installed).
|
|
No mocks are used for the database.
|