Files
NovaSonic/README.md
T
HoneyandClaude Sonnet 4.6 ba16f88355 docs: update README — accurate feature list + Android native app description
Removed:
- "WebView wrapper" — Android is native Jetpack Compose, not a WebView
- "Artwork pre-warming / pre-buffer on cold start" — not implemented this way
- ABS chapters/speed/sleep/progress on Android — web only for now

Added:
- Lyrics section: lrclib.net, fallback chain, in-memory cache, synced scroll
- Android: last played song in MiniPlayer across restarts
- Android: ABS library browser tab (hidden until configured)
- Android: no login flash on startup
- Settings: connection status dots, save button top+bottom, matched web order
- Multi-artist support in NowPlaying
- Artist cards with images in search
- Genre browsing
- ABS web vs Android split into separate entries
- Accurate Android project structure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 23:56:02 +02:00

241 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NovaSonic
A self-hosted music streaming PWA and Android app for Navidrome / Subsonic-compatible servers.
Built with Vite + vanilla ES modules (web) and Jetpack Compose + Media3/ExoPlayer (Android).
---
## Features
### Music Library
- Stream music from your Navidrome / Subsonic library
- Browse artists, albums, playlists, starred tracks, and random picks
- Sort and filter views with chip filters
- Search / filter bar inside playlist detail and favorites (instant, client-side)
- Play count display — optional toggle in Settings
- Star and context menu on every song row
- Genre browsing with genre-filtered song lists
### Lyrics
- Synced (word-by-word highlighted) and plain lyrics via lrclib.net
- Auto-fetched per track — no manual setup needed
- Fallback chain: exact match with duration → exact match without duration (catches version mismatches) → artist+title search → title-only search
- In-memory cache per session — no repeated network requests for the same track
- Android: smooth scroll animation keeps the active line centered
### 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
- Artist cards with images in search results
- Quick actions: play top songs, shuffle all, open concerts
### Playback
- Queue management with shuffle, repeat (all / one), and radio mode (endless similar songs)
- Spotify-style shuffle — pre-shuffles the full queue so every song plays exactly once
- Now Playing overlay: synced lyrics, queue view, star, multi-artist links
- Multi-artist support — OpenSubsonic `artists` array shown as individual clickable links
- Gapless-style playback — next track pre-buffered 60 seconds before current track ends
- Lock screen / notification media controls (Android / iOS / desktop)
- Scrobbling to Navidrome (configurable: 15 s / 30 s / ⅓ / ⅔ / end)
### Discovery (Erkunden tab)
- iTunes / Last.fm integration — charts, global search, 30-second previews, similar artists, recommendations
- Song Importer — paste a Spotify, YouTube, YouTube Music, or SoundCloud link to preview and download tracks
### Downloads (yt-dlp backend)
- Download individual tracks, full albums, or entire artists
- Sources: YouTube Music (primary), YouTube, SoundCloud, Spotify (via importer)
- iTunes enrichment — album, year, track number, genre, 1000×1000 cover art
- Duplicate detection — skips tracks already present on the server
- Standard filename: `01 - Artist - Title.ext`, organised into `AlbumArtist/Album/` folders
### Metadata Editor
- Edit title, artist, album artist, album, genre, year, track number, disc number
- Update embedded cover art via URL or file upload
- File renamed and moved automatically on save
- Navidrome rescan triggered after every save
### Playlists
- Create, edit, and delete playlists
- Add / remove tracks
- Filter/search within a playlist
### Audiobookshelf Integration (Web)
- Browse and stream audiobooks from your Audiobookshelf server
- Chapters list with chapter-by-chapter navigation
- Playback speed control
- Sleep timer
- Progress sync — current position saved back to ABS server
### Audiobookshelf Integration (Android)
- Browse ABS libraries and audiobook list with covers, author, and runtime
- Tab appears in navigation only when ABS URL + API key are configured in Settings
### Settings
- Connection status indicators (green / red dot) for ABS server and NovaSonic backend — tested live with a button
- Save button at top and bottom of settings for easy access
- Order matches web: Theme → Bibliothek → Audiobookshelf → Discover APIs → Navidrome Server
### App — Web PWA
- Installable on Android / iOS / desktop
- Randomized home greetings
- Multiple color themes, dark mode, mobile-first responsive layout
- German UI
### App — Android (native)
- Native Jetpack Compose app with Material3 design — not a WebView wrapper
- Media3 / ExoPlayer backend for reliable audio playback
- OS notification with skip / play / pause buttons
- Last played song persisted across restarts — shown in mini player bar; tap play to resume
- Audiobookshelf library browser (tab hidden until ABS is configured)
- No login screen flash on startup when credentials are already saved
---
## Project Structure
```
NovaSonic/
├── src/
│ ├── player/
│ │ ├── player.js # Playback, queue, transport, media session, preload
│ │ └── nowplaying.js # Now Playing overlay + synced lyrics
│ ├── 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 (web)
│ ├── ui/
│ │ ├── ui.js # Modals, sidebar, 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)
│ ├── utils.js # md5, esc, formatDur, toast
│ ├── api.js # Subsonic API, iTunes API, cover art, romaji display
│ └── main.js # App init, audio wiring, window globals
├── backend/
│ ├── novasonic-server.js # Express API: downloads, metadata, events proxy, ABS proxy
│ └── lib/
│ ├── config.js # Env var → config object
│ ├── jobs.js # In-memory download job store
│ ├── metadata.js # iTunes lookup, artwork, filename helpers
│ ├── ytdlp.js # yt-dlp download + ffmpeg metadata embedding
│ ├── squid.js # Qobuz (squid.wtf) download backend
│ ├── downloader.js # Unified downloadTrack / downloadAlbumTracks
│ └── romaji.js # Japanese → romaji search index
├── android/ # Native Android app (Jetpack Compose + Media3)
│ └── app/src/main/kotlin/com/novasonic/app/
│ ├── api/ # SubsonicClient, AbsClient, LrcLibClient, ItunesClient
│ ├── data/ # PrefsStore (DataStore), MusicRepository
│ ├── player/ # PlayerController, MusicService (Media3)
│ ├── ui/
│ │ ├── screen/ # HomeScreen, NowPlayingScreen, AbsScreen, SettingsScreen, …
│ │ ├── component/ # MiniPlayer, SongRow, SongContextSheet, …
│ │ └── theme/ # Color, Type, Theme
│ └── viewmodel/ # ViewModel per screen
├── public/
│ ├── sw.js # Service worker
│ ├── manifest.json # PWA manifest
│ └── config.js # Runtime config (generated by Docker entrypoint)
├── index.html
├── styles.css
├── vite.config.js
├── Dockerfile
├── docker-compose.yml
├── nginx.conf
└── docker-entrypoint.sh # Injects NAVIDROME_URL / BACKEND_URL at runtime
```
---
## Setup
### 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
docker compose up -d
```
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
4. Optionally add the NovaSonic backend URL in Settings to enable downloads
---
## Environment Variables
### Frontend container
| Variable | Description |
|---|---|
| `NAVIDROME_URL` | Pre-fills the Navidrome server URL on the login screen |
| `BACKEND_URL` | Pre-fills the download backend URL on the login screen |
### Backend container
| Variable | Default | Description |
|---|---|---|
| `PORT` | `3700` | Port the backend listens on |
| `MUSIC_PATH` | `/music` | Absolute path to your Navidrome music folder (mounted as volume) |
| `AUDIO_FMT` | `mp3` | Download output format (`mp3`, `flac`, `opus`, `best`) |
| `AUDIO_QUALITY` | `0` | yt-dlp audio quality (0 = best) |
| `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 |
---
## Development
```bash
npm install
npm run dev # Vite dev server with HMR
npm run build # Production build → dist/
npm run preview # Preview the production build locally
```