A simple local music/video player — the playback companion to the
ndisc suite (ndisc,
ndisc.tree,
ndisc.smpl).
Stack: Tauri 2 desktop binary + React 19 + TypeScript + Tailwind v3,
mirroring the rest of the suite (shared palette, Section, cn). Audio
plays through a native Rust engine (rodio on a dedicated thread) —
WebKit2GTK can't play local media — while video plays in a webview
<video> fed by a small in-process loopback HTTP server (tiny_http).
The library is indexed into SQLite (rusqlite) with tags + embedded
covers read via lofty.
Status: beta (v0.2.0-beta.1). Playlists, video playback, BPM, a spectrum visualiser and a sortable table view are all in; see the CHANGELOG for the running roadmap.
- Library index — scan a music root (default
/data/music) into a local SQLite cache: artist/album/title/year/track-no, duration, codec, and a folder or embedded cover per album. Inline tag edits are written back to disk vialofty(set_track_field). - Two browse views — an Artist → Album → Track collection tree
(lazy-loaded per album) and a flat, sortable/virtualised table view
(
list_all_tracks). - Native audio playback —
rodio-backed play / pause / stop, previous / next, click-to-seek, volume; spacebar toggles play/pause. Shuffle and repeat (off / all / one). - Video playback — mp4 / m4v play with picture via the loopback media server.
- Now playing — large cover art with title / artist / album, plus a
real-time spectrum visualiser (
audio_spectrum). - Playlists — a working playlist that auto-persists by path, with
Strawberry-compatible
.xspfload / save and drag-reorder. - Queue — the current play order; click to jump.
- BPM — per-track BPM (
track_bpm) read from the suite-sharedbpm.jsonstore, with an aubio fallback. - Library health — flags unplayable / undecodable formats with an
acknowledge action (
library_health). - Current — a read view of the suite's Nostr
feed.v1stream (CurrentView,useFeed). - Theming — three-way switch (fizx → upleb → mono).
- Responsive auto-collapse of panels at narrow widths.
- A "verify library" decode-probe pass — catch corrupt files of a supported format that the scan-time check can't flag.
- Further video-section work beyond current playback.
See the CHANGELOG "Roadmap" for the full list.
Tauri's Linux prerequisites plus GStreamer codecs for the formats you play:
sudo apt update
sudo apt install \
libwebkit2gtk-4.1-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libssl-dev \
build-essential \
curl wget file \
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libavPlus a Node toolchain (18+) and Rust (rustup).
make deps # npm install + cargo fetch
make dev # opens the Tauri window with hot reloadmake install # user-level (default PREFIX=$HOME/.local)
sudo make install PREFIX=/usr/local
make uninstall
make check # tsc + vite build + cargo checkThe desktop entry is generated from nplay.desktop.in with the install
paths substituted in.