diff --git a/README.md b/README.md index c96c6d5..1f36117 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,106 @@ # NovaSonic -A self-hosted music streaming PWA for Navidrome / Subsonic-compatible backends. +A self-hosted music streaming PWA for Navidrome / Subsonic-compatible servers. +Built with Vite + vanilla ES modules, served via nginx in Docker. -## Stack +--- -- `index.html` — app shell -- `styles.css` — all styles -- `app.js` — frontend logic -- `sw.js` — service worker (offline caching) +## Features -## Setup +- Stream music from your Navidrome / Subsonic library +- Browse artists, albums, playlists, starred tracks and random picks +- Queue management with shuffle, repeat (all / once) and radio mode (endless random) +- Now Playing overlay with swipe-to-dismiss and lock screen media controls (Android/iOS) +- iTunes / Last.fm integration — charts, global search, 30s previews, recommendations +- Download tracks from YouTube/SoundCloud via yt-dlp directly into your music library +- Duplicate detection — skips tracks that already exist on the server +- Edit playlists (name, description, cover art, public toggle) +- PWA — installable, offline-capable via service worker +- Dark theme, mobile-first responsive layout -Point the app at your Navidrome server URL on first launch. +--- -## Docker +## Project Structure + +``` +Music_App/ +├── src/ # ES modules (Vite entry) +│ ├── state.js # Shared mutable state (S object) +│ ├── utils.js # md5, esc, formatDur, toast +│ ├── api.js # Subsonic API, Navidrome REST, iTunes API +│ ├── player.js # Playback, transport, queue, media session, preview +│ ├── views.js # Navigation, page loaders, card makers, search +│ ├── ui.js # Modals, overlays, sidebar, settings, context menu +│ ├── pwa.js # Service worker registration + update banner +│ └── main.js # App init, audio wiring, window globals +├── public/ # Static assets (copied as-is to dist/) +│ ├── sw.js # Service worker +│ ├── manifest.json # PWA manifest +│ ├── icon.svg # App icon +│ └── config.js # Runtime config placeholder (generated by Docker) +├── backend/ +│ └── novasonic-server.js # Node.js download backend (yt-dlp + ffmpeg) +├── index.html # App shell + Vite entry point +├── styles.css # All styles +├── vite.config.js +├── Dockerfile # Multi-stage: Node build → nginx serve +├── docker-compose.yml +├── nginx.conf +└── docker-entrypoint.sh # Injects NS_SERVER_URL / NS_BACKEND_URL at startup +``` + +--- + +## Docker Setup + +### Frontend only ```bash docker compose up -d ``` + +Environment variables (set in `docker-compose.yml` or via `-e`): + +| Variable | Description | +|---|---| +| `NS_SERVER_URL` | Pre-fills the Navidrome server URL on the login screen | +| `NS_BACKEND_URL` | Pre-fills the download backend URL | + +### With download backend + +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 | +|---|---|---| +| `PORT` | `3700` | Port the backend listens on | +| `MUSIC_PATH` | `/music` | Path to your Navidrome music folder (mount as volume) | +| `AUDIO_FMT` | `mp3` | Output format (`mp3`, `flac`, `opus`, …) | +| `AUDIO_QUALITY` | `0` | yt-dlp audio quality (0 = best) | +| `MAX_PARALLEL` | `2` | Maximum concurrent downloads | + +--- + +## 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 +``` + +--- + +## 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