HoneyandClaude Opus 4.8 1e69831dd8 feat: move the whole metadata/search stack from iTunes to Deezer (1.3)
Apple's iTunes /search returns 403 from server/datacenter IPs, which had broken global
search, charts, album/artist/single downloads and the metadata-editor autofill in
production. Everything now sources metadata from Deezer (free, no key, more requests,
returns explicit versions + real artist images + durations). Web + Android share one
source, so an artist resolves to one consistent name everywhere. Deezer results are
mapped to the legacy "ItunesItem" shape, so the UI + download flow are unchanged.

Backend:
- New backend/lib/deezer.js: lookupTrackMeta, fetchAlbumTracks, searchAlbumTracks,
  fetchArtistAlbums (+ pure pickTrackMatch/mapAlbumTrack for tests).
- metadata.js drops the iTunes lookups; novasonic-server download paths (track, album,
  artist, playlist enrich, spotify artwork) + autofill now use Deezer.
- Artist download uses Deezer discography (real albums only), not the iTunes album search.
- Editor autofill endpoint /api/itunes/lookup -> /api/meta/lookup; removed the dead
  iTunes /search proxy and the Apple charts RSS proxy.
- backend/test/deezer.test.js: unit tests for numbering, mixed-artist album-artist
  stability, explicit flags, the Japanese-title match guard (npm test; RUN_LIVE=1 for live).

Web:
- api.js search/lookups already on Deezer; charts now use Deezer /chart. Artist cards
  show the real Deezer photo. Visible "iTunes"/"Apple Music" labels -> "Deezer"
  (search badge, charts badge, preview bar, editor button, artist heading). SW ns-v51.

Android:
- New DeezerModels.kt with Dz* models + mappers to ItunesItem/ItunesRssEntry.
- ItunesClient is Deezer-backed (search = tracks+albums+artists in parallel; album/artist
  lookups; /chart charts), same method signatures. Visible strings -> Deezer.

Docs: README, CLAUDE.md and CHANGELOG (1.3) updated; Platform Parity Matrix reflects the
shared Deezer source + Android non-local artist page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-31 12:48:33 +02:00

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

  • Library — Stream from Navidrome / Subsonic; browse artists, albums, playlists, genres, starred, and random; search; star + context menu on every row.
  • Playback — Queue with shuffle, repeat, and radio mode (endless similar songs); gapless-style preload; lock-screen / notification controls; Navidrome scrobbling.
  • Lyrics — Synced and plain lyrics via lrclib.net, auto-fetched and cached per session.
  • Artist pages — Hero card, Last.fm bio / similar / top songs, Ticketmaster events, and a Deezer cross-reference showing owned vs. missing tracks.
  • Playlists — Create, rename, delete, add/remove tracks, and upload a cover (Web + Android).
  • Importer & downloads — Paste a Spotify / YouTube / YouTube Music / SoundCloud link to download via yt-dlp, with Deezer metadata enrichment and duplicate detection.
  • Metadata editor (web) — Edit tags + cover art; files are renamed/moved and Navidrome is rescanned on save.
  • Offline (Android) — Download albums, playlists, or single songs to private storage; an Offline tab to play and manage them (works without a server connection); downloaded tracks play from disk on every screen.
  • Audiobookshelf — Browse and stream audiobooks with chapter navigation, speed control, sleep timer, and progress sync.

Web is an installable PWA (themes, German UI); Android is native Jetpack Compose + Media3/ExoPlayer with a mini player, media/ABS notifications, and Android Auto. See CHANGELOG.md for the full web/Android parity matrix.


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
│   │   ├── 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, 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               # Helpers (md5, esc, formatDur, toast)
│   ├── api.js                 # Subsonic API, Deezer API, cover art
│   └── 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
│       ├── deezer.js          # Deezer metadata: track/album/artist lookups
│       ├── metadata.js        # Artwork, filename helpers, duplicate detection
│       ├── ytdlp.js           # yt-dlp download + ffmpeg metadata embedding
│       ├── 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 (Deezer-backed)
│       ├── data/              # PrefsStore (DataStore), MusicRepository, StarState
│       ├── offline/           # Room DB, DAO, OfflineRepository, DownloadWorker (offline downloads)
│       ├── 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

git clone <repo>
cd NovaSonic
cp .env.example .env

Edit .env:

NAVIDROME_URL=https://music.yourdomain.com
BACKEND_URL=https://novasonic-api.yourdomain.com

MUSIC_PATH=/srv/navidrome/music

AUDIO_FMT=mp3          # mp3 | flac | opus | best
AUDIO_QUALITY=0        # 0 = best (yt-dlp)
MAX_PARALLEL=2

TICKETMASTER_API_KEY=  # optional — free key from developer.ticketmaster.com

2. Start

docker compose up -d

Frontend on port 8080, backend on port 3700. Route both through your reverse proxy.

3. First launch

  1. Enter your Navidrome server URL, username, and password
  2. Optionally add a Last.fm API key in Settings for bios and recommendations
  3. Optionally connect Audiobookshelf in Settings
  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
AUDIO_FMT mp3 Download format (mp3, flac, opus, best)
AUDIO_QUALITY 0 yt-dlp audio quality (0 = best)
MAX_PARALLEL 2 Max concurrent download jobs
TICKETMASTER_API_KEY — Free key from developer.ticketmaster.com

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
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%