HoneyandClaude Sonnet 4.6 46eb8c826f fix: scan resource page JS for GQL hash (Spotify lazy-loads feature chunks)
fetchPlaylist/getAlbum/getTrack GraphQL hashes are not in homepage bundles
— they live in lazy-loaded chunks that only appear on the playlist/album/track
page. Fetch the specific page HTML to find the extra JS bundles, then scan
those for the persisted query hash. Also improved hash regex (no semicolon
restriction, wider window, fallback nearest-hex search).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:45:32 +02:00

NovaSonic

A self-hosted music streaming PWA for Navidrome / Subsonic-compatible servers.
Built with Vite + vanilla ES modules, served via nginx in Docker.


Features

  • 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

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

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/.

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

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
S
Description
No description provided
Readme
5 MiB
0 Stars 0 Watchers 0 Forks
2026-09-02 09:26:49 +02:00
Languages
Kotlin 47.4%
JavaScript 40.1%
CSS 5.5%
HTML 5.4%
Python 0.8%
Other 0.8%