docs: rewrite README with current features, structure and env vars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-06-08 21:56:54 +02:00
1 parent fc2c5de1fb
commit 28489f722a
1 file changed
+123 -92
+123 -92
View File
@@ -1,70 +1,69 @@
# NovaSonic # NovaSonic
A self-hosted music streaming PWA for Navidrome / Subsonic-compatible servers. A self-hosted music streaming PWA and Android app for Navidrome / Subsonic-compatible servers.
Built with Vite + vanilla ES modules, served via nginx in Docker. Built with Vite + vanilla ES modules, served via nginx in Docker.
--- ---
## Features ## Features
### Home
- Hero card — large banner featuring a random pick from your most-played and recently played albums, labelled "Meistgespielt" or "Zuletzt gehört" accordingly
- Genre browser — top 15 genres (by song count) as a colored card grid; click to browse songs, hover-play to instantly shuffle the genre
### Music Library ### Music Library
- Stream music from your Navidrome / Subsonic library - Stream music from your Navidrome / Subsonic library
- Browse artists, albums, playlists, starred tracks, and random picks - Browse artists, albums, playlists, starred tracks, and random picks
- Sort and filter views (albums, favorites) with chip filters - Sort and filter views with chip filters
- Search/filter bar inside playlist detail and favorites (instant, client-side) - Search / filter bar inside playlist detail and favorites (instant, client-side)
- Synced and plain lyrics via LRCLIB (auto-fetched per track) - Synced and plain lyrics via LRCLIB (auto-fetched per track)
- Play count display — optional toggle in Settings; always shown on artist pages - Play count display — optional toggle in Settings
- Star and context-menu on every song row (artist top songs, all-songs view, playlists, albums) - Star and context menu on every song row
### Artist Pages
- Full-bleed hero card — artist photo as portrait + blurred background (desktop); full-bleed image with name overlay (mobile)
- Bio, similar artists, top songs pulled from Last.fm via Navidrome
- Concert events via Ticketmaster (upcoming shows with venue, date, ticket link)
- Albums cross-referenced against iTunes catalog — shows what's downloaded, partially downloaded, or missing
- Quick actions: play top songs, shuffle all, open concerts
### Playback ### Playback
- Queue management with shuffle, repeat (all / once), and radio mode (endless random) - Queue management with shuffle, repeat (all / one), and radio mode (endless random)
- Spotify-style shuffle — pre-shuffles the full queue so every song plays exactly once - Spotify-style shuffle — pre-shuffles the full queue so every song plays exactly once
- Now Playing overlay with swipe-to-dismiss; queue tab stays active when selecting a song from the queue - Now Playing overlay with swipe-to-dismiss
- Lock screen media controls (Android / iOS via Media Session API) - Gapless-style playback — next track pre-buffered 60 seconds before current track ends
- Gapless-style queue with prev/next, skip forward/back - Lock screen / notification media controls (Android / iOS / desktop)
- Scrobbling — plays are reported to Navidrome after 15 seconds of continuous playback - Scrobbling — reported to Navidrome (configurable: 15 s / 30 s / ⅓ / ⅔ / end)
### Discovery ### Discovery
- iTunes / Last.fm integration — charts, global search, 30-second previews, similar artists, recommendations - iTunes / Last.fm integration — charts, global search, 30-second previews, similar artists, recommendations
- Song Importer — paste a link from Spotify, YouTube, YouTube Music, or SoundCloud to preview and download tracks, enriched with iTunes metadata and cover art - Song Importer — paste a Spotify, YouTube, YouTube Music, or SoundCloud link to preview and download tracks
### Downloads (yt-dlp backend) ### Downloads (yt-dlp backend)
- Download individual tracks, full albums, or entire artists - Download individual tracks, full albums, or entire artists
- Sources: YouTube Music (primary), YouTube, SoundCloud, Spotify (via playlist importer) - Sources: YouTube Music (primary), YouTube, SoundCloud, Spotify (via importer)
- iTunes enrichment — album, year, track number, genre, 1000×1000 cover art - iTunes enrichment — album, year, track number, genre, 1000×1000 cover art
- Duplicate detection — skips tracks already present on the server - Duplicate detection — skips tracks already present on the server
- Standard filename convention: `{01 - }Artist1, Artist2 - Title.ext` - Standard filename: `01 - Artist - Title.ext`, organised into `AlbumArtist/Album/` folders
- Files organised into `MusicRoot/AlbumArtist/Album/` folders automatically
### Metadata Editor ### Metadata Editor
- Edit title, artist, album artist, album, genre, year, track number, disc number from within the app - Edit title, artist, album artist, album, genre, year, track number, disc number
- Update embedded cover art via URL or file upload - Update embedded cover art via URL or file upload
- Artist separator normalization — accepts `•`, `·`, `;`, `,` as input; stores as `;` for track artist and `,` for album artist (Navidrome/MusicBrainz style) - File renamed and moved automatically on save
- File renamed automatically on save to match the standard naming convention - Navidrome rescan triggered after every save
- File moved to the correct `AlbumArtist/Album/` folder when those fields change
- Empty folders cleaned up after a move
- Navidrome rescan triggered automatically after every save
### Playlists ### Playlists
- Create, edit, and delete playlists - Create, edit, and delete playlists
- Edit playlist name, description, cover art, and public/private toggle - Edit name, description, cover art, public/private toggle
- Add / remove tracks; reorder via drag and drop - Add / remove tracks; reorder via drag and drop
### Audiobookshelf Integration ### Audiobookshelf Integration
- Connect to your Audiobookshelf server (URL + API key) - Browse and stream audiobooks from your Audiobookshelf server
- Browse and stream audiobooks from your ABS library - Chapters list, playback speed, sleep timer, progress sync
- Full player: chapters list, playback speed, sleep timer (preset or custom minutes), progress sync
### App ### App
- PWA — installable on Android / iOS / desktop, offline-capable via service worker - PWA — installable on Android / iOS / desktop
- Android APK (WebView wrapper with native Media3/ExoPlayer backend) - Android APK — native WebView wrapper with Media3 / ExoPlayer backend
- Robust Android queue sync — song identity verified via media ID on every resume to prevent stale-state mismatches - Native OS notification with skip buttons
- Multiple color themes - Pre-buffers last played track on cold start for instant resume
- Dark theme, mobile-first responsive layout - Artwork pre-warming so notification never shows blank cover
- Multiple color themes, dark mode, mobile-first responsive layout
- German UI - German UI
--- ---
@@ -72,84 +71,126 @@ Built with Vite + vanilla ES modules, served via nginx in Docker.
## Project Structure ## Project Structure
``` ```
Music_App/ NovaSonic/
├── src/ # ES modules (Vite entry) ├── src/
│ ├── player/
│ │ ├── player.js # Playback, queue, transport, media session, preload
│ │ └── nowplaying.js # Now Playing overlay
│ ├── views/
│ │ ├── detail.js # Artist / album detail pages
│ │ ├── views.js # Navigation, page loaders, search
│ │ ├── events.js # Ticketmaster concert events
│ │ ├── home.js # Home page, artist image cache
│ │ ├── search.js # Search, artist/album navigation
│ │ ├── playlists.js # Playlist management
│ │ ├── spotify.js # Spotify importer
│ │ ├── youtube.js # YouTube importer
│ │ ├── soundcloud.js # SoundCloud importer
│ │ ├── navigation.js # Client-side router
│ │ └── abs.js # Audiobookshelf integration
│ ├── ui/
│ │ ├── ui.js # Modals, sidebar, settings, context menu
│ │ ├── components.js # Song rows, cards, shared UI
│ │ ├── downloads.js # Download modal + job tracker
│ │ ├── metadata.js # Metadata editor
│ │ ├── modals.js # Song info, events modals
│ │ ├── notify.js # Toast notifications
│ │ └── settings.js # Settings page
│ ├── state.js # Shared mutable state (S object) │ ├── state.js # Shared mutable state (S object)
│ ├── utils.js # md5, esc, formatDur, toast │ ├── utils.js # md5, esc, formatDur, toast
│ ├── api.js # Subsonic API, Navidrome REST, iTunes API │ ├── api.js # Subsonic API, iTunes API, cover art
│ ├── player.js # Playback, transport, queue, media session, preview
│ ├── views.js # Navigation, page loaders, card makers, search
│ ├── ui.js # Modals, overlays, sidebar, settings, context menu, metadata editor
│ ├── nowplaying.js # Now Playing overlay
│ ├── abs.js # Audiobookshelf integration
│ ├── spotify.js # Spotify importer (resolve + download)
│ ├── youtube.js # YouTube / YouTube Music importer
│ ├── soundcloud.js # SoundCloud importer
│ ├── components.js # Shared UI components (song rows, cards)
│ ├── themes.js # Theme switching
│ ├── pwa.js # Service worker registration + update banner
│ └── main.js # App init, audio wiring, window globals │ └── main.js # App init, audio wiring, window globals
├── backend/ ├── backend/
│ ├── novasonic-server.js # Express API: download jobs, metadata edit, resolvers │ ├── novasonic-server.js # Express API: downloads, metadata, events proxy
│ ├── spotify_resolve.py # Spotify page scraper (track/album/playlist metadata)
│ └── lib/ │ └── lib/
│ ├── config.js # Backend config (env vars, paths, format) │ ├── config.js # Env var → config object
│ ├── jobs.js # In-memory job store + log helper │ ├── jobs.js # In-memory download job store
│ ├── metadata.js # iTunes lookup, artwork download, lyrics fetch, filename helpers │ ├── metadata.js # iTunes lookup, artwork, lyrics, filename helpers
│ ├── ytdlp.js # yt-dlp download cascade + ffmpeg metadata embedding │ ├── ytdlp.js # yt-dlp download + ffmpeg metadata embedding
│ ├── squid.js # Squid/Qobuz download backend │ ├── squid.js # Qobuz (squid.wtf) download backend
│ ├── downloader.js # Unified downloadTrack / downloadAlbumTracks entry point │ ├── downloader.js # Unified downloadTrack / downloadAlbumTracks
│ └── romaji.js # Japanese → romaji index for search │ └── romaji.js # Japanese → romaji search index
├── public/ # Static assets (copied as-is to dist/) ├── android/ # Android APK (WebView + Media3/ExoPlayer)
├── public/
│ ├── sw.js # Service worker │ ├── sw.js # Service worker
│ ├── manifest.json # PWA manifest │ ├── manifest.json # PWA manifest
│ ├── icon.svg # App icon │ └── config.js # Runtime config (generated by Docker entrypoint)
│ └── config.js # Runtime config placeholder (generated by Docker) ├── index.html
├── android/ # Android WebView APK wrapper ├── styles.css
├── index.html # App shell + Vite entry point
├── styles.css # All styles
├── vite.config.js ├── vite.config.js
├── Dockerfile # Multi-stage: Node build → nginx serve ├── Dockerfile
├── docker-compose.yml ├── docker-compose.yml
├── nginx.conf ├── nginx.conf
└── docker-entrypoint.sh # Injects NS_SERVER_URL / NS_BACKEND_URL at startup └── docker-entrypoint.sh # Injects NAVIDROME_URL / BACKEND_URL at runtime
``` ```
--- ---
## Docker Setup ## Setup
### Frontend only ### 1. Clone and configure
```bash
git clone <repo>
cd NovaSonic
cp .env.example .env
```
Edit `.env`:
```env
NAVIDROME_URL=https://music.yourdomain.com
BACKEND_URL=https://novasonic-api.yourdomain.com
MUSIC_PATH=/srv/navidrome/music # absolute path to your music folder on the host
AUDIO_FMT=mp3 # mp3 | flac | opus | best
AUDIO_QUALITY=0 # 0 = best (yt-dlp)
MAX_PARALLEL=2
DOWNLOAD_BACKEND=auto # ytdlp | squid | auto
SQUID_QUALITY=mp3 # mp3 | flac | hi-res
TICKETMASTER_API_KEY= # optional — free key from developer.ticketmaster.com
```
### 2. Start
```bash ```bash
docker compose up -d docker compose up -d
``` ```
Environment variables (set in `docker-compose.yml` or via `-e`): This starts both the frontend (nginx on port 8080) and the backend (Node.js on port 3700). Route both ports through your reverse proxy.
### 3. First launch
1. Open the app and enter your Navidrome server URL, username and password
2. Optionally add a Last.fm API key in Settings for recommendations and artist bios
3. Optionally connect Audiobookshelf in Settings to stream audiobooks
---
## Environment Variables
### Frontend container
| Variable | Description | | Variable | Description |
|---|---| |---|---|
| `NS_SERVER_URL` | Pre-fills the Navidrome server URL on the login screen | | `NAVIDROME_URL` | Pre-fills the Navidrome server URL on the login screen |
| `NS_BACKEND_URL` | Pre-fills the download backend URL | | `BACKEND_URL` | Pre-fills the download backend URL on the login screen |
### With download backend ### Backend container
The backend requires `yt-dlp` and `ffmpeg`. A separate `docker-compose.yml` lives in `backend/`.
```bash
cd backend
docker compose up -d
```
Environment variables for the backend:
| Variable | Default | Description | | Variable | Default | Description |
|---|---|---| |---|---|---|
| `PORT` | `3700` | Port the backend listens on | | `PORT` | `3700` | Port the backend listens on |
| `MUSIC_PATH` | `/music` | Path to your Navidrome music folder (mount as volume) | | `MUSIC_PATH` | `/music` | Absolute path to your Navidrome music folder (mounted as volume) |
| `AUDIO_FMT` | `mp3` | Output format (`mp3`, `flac`, `opus`, …) | | `AUDIO_FMT` | `mp3` | Download output format (`mp3`, `flac`, `opus`, `best`) |
| `AUDIO_QUALITY` | `0` | yt-dlp audio quality (0 = best) | | `AUDIO_QUALITY` | `0` | yt-dlp audio quality (0 = best) |
| `MAX_PARALLEL` | `2` | Maximum concurrent downloads | | `MAX_PARALLEL` | `2` | Max concurrent download jobs |
| `DOWNLOAD_BACKEND` | `auto` | `ytdlp` / `squid` / `auto` (tries Qobuz first, falls back to yt-dlp) |
| `SQUID_QUALITY` | `mp3` | Qobuz quality: `mp3`, `flac`, `hi-res` |
| `TICKETMASTER_API_KEY` | — | Free API key from [developer.ticketmaster.com](https://developer.ticketmaster.com) — enables concert events on artist pages |
--- ---
@@ -161,13 +202,3 @@ npm run dev # Vite dev server with HMR
npm run build # Production build → dist/ npm run build # Production build → dist/
npm run preview # Preview the production build locally npm run preview # Preview the production build locally
``` ```
---
## First Launch
1. Open the app in a browser
2. Enter your Navidrome server URL, username and password
3. Optionally add a Last.fm API key (Settings) for recommendations and similar artists
4. Optionally add the backend URL (Settings) to enable yt-dlp downloads
5. Optionally connect Audiobookshelf (Settings) to stream audiobooks