YouTube Download & Per-User Permissions
- YouTube download — new yt-dlp integration with download modal, codec selection, metadata editing, and album art embedding (supports MP3, FLAC, Opus, OGG)
- Per-user upload/mkdir permissions — upload and create-folder can now be enabled/disabled per user
- Server-level mkdir config — global toggle to disable folder creation
- Rust parser — experimental Rust-based file scanner for faster library scanning, with pre-built binaries and CI/CD pipeline
- Vpath security — added path normalization to prevent directory traversal attacks
Server Audio & Remote Controls
- Server audio playback — Rust-based audio player that plays music through the server's speakers via HTTP API, with queue management, loop/shuffle modes
- Remote control page — redesigned remote control UI with album art, progress bar, volume control, and queue browsing
- Cross-compilation — custom Docker images for ARM Linux builds of the Rust audio player
6.0.0 — SQLite Migration, Velvet UI, and Major Feature Additions
Database
- SQLite migration — complete rewrite from LokiJS to Node.js built-in
node:sqlite(DatabaseSync) - Normalized schema — separate tables for artists, albums, tracks, genres with proper foreign keys
- Schema migration system — versioned migrations (V1-V8) using
PRAGMA user_version - Auto-migration from LokiJS — playlists, user metadata, shared playlists migrated automatically on first boot
- Genre support — normalized genres table with many-to-many track_genres junction table
- Track duration — scanner now extracts and stores audio duration from file metadata
- Force rescan — admin can trigger a full rescan that re-parses all files regardless of modification time, useful after schema changes
- Scan progress — real-time progress reporting via scan_progress table, visible in admin panel and Velvet UI
- In-memory caching — users, libraries, and user-library mappings cached with invalidation
- Busy timeout —
PRAGMA busy_timeout = 5000prevents "database is locked" errors during concurrent access
Velvet UI Integration
- Alternative frontend — Velvet UI imported as a selectable skin (
ui: 'velvet'in config) - Admin panel frontend selector — switch between Default and Velvet UIs from the admin panel with server restart
- Smart playlists — dynamic playlists with filters (genre, year, rating, play status, artist search, starred, fresh picks) and sort options
- ListenBrainz scrobbling — connect/disconnect, now-playing, and scrobble endpoints with token validation
- Discogs integration — admin config, cover art search with base64 thumbnails, Deezer search, and art embed endpoint
- Waveform visualization — ffmpeg-based peak analysis with 800-bar waveform data, disk + memory cache
- Your Stats / Wrapped — listening statistics with play event tracking, top songs/artists, listening by hour/weekday, personality type, session analysis
- Cue points — per-user bookmarks on audio tracks displayed as tick marks on the progress bar
- User settings persistence — 36+ UI preferences saved per user in the database
- YouTube download adapter — Velvet-compatible endpoints (
/ytdl/info,/ytdl/download) wrapping the existing yt-dlp API - ID3 tag writing — edit track metadata (title, artist, album, year, genre, track, disc) from the Now Playing modal via ffmpeg
- Last.fm similar artists — powers Auto-DJ recommendations via the Last.fm API
- Playlist rename — new endpoint for renaming playlists
FFmpeg
- Self-contained bootstrap — auto-downloads static ffmpeg binaries from BtbN/FFmpeg-Builds with SHA256 checksum verification
- Daily auto-update — checks for new ffmpeg versions on a daily interval
- Removed fluent-ffmpeg — all ffmpeg operations use direct
child_process.spawncalls - Removed ffbinaries — replaced with the custom download module
Transcode
- Fixed opus/aac transcoding — corrected ffmpeg container format flags (
-f oggfor opus,-f adtsfor aac) - Estimated Content-Length — calculates expected output size from duration × bitrate, enabling progress bars and seeking during streaming
- Smart cache — strong reference for song duration + 2 minutes, then moved to WeakRef for GC. No memory cap needed.
- Unified streaming — eliminated buffer/stream mode split. All requests stream immediately and cache in parallel.
- Client disconnect cleanup — kills ffmpeg process when client disconnects mid-stream
- Express 5 fix —
{*filepath}wildcard param returns array in Express 5, now joined back to string
Album Art
- Album art search — MusicBrainz, iTunes, and Deezer search from the UI with manual selection
- Album art upload — custom art upload with base64 encoding
- Album art embed — ffmpeg-based embedding into MP3, FLAC, M4A, AAC files
- File modification permissions — server-level and per-user control over file writes
- Compress album art toggle — Layout panel option to use compressed or full-size art in album grid
Security
- Path traversal prevention — centralized bounds check in
getVPathInfo()usingpath.resolve()+startsWith(base + sep) - Upload filename sanitization —
path.basename()strips directory components from uploaded filenames - M3U path traversal fix — entries containing
.., absolute paths, and Windows drive letters are rejected - Download directory fix —
archive.directory()now uses the requested subdirectory instead of the entire library root - M3U listing bounds check — resolved paths verified to stay within library root before returning to client
- Locked admin hardening — when admin API is locked with no users, server-level write flags (
noUpload,noMkdir,noFileModify) are forced on, and the public user gets no admin or write privileges - Library access control — all new endpoints use
getVPathInfo()for path validation instead of manual parsing
Default UI Improvements
- Album queue button — green play button on album grid cards to queue entire albums
- Popper menu dark theme — context menus and dropdown buttons updated for dark theme consistency
- File explorer header tooltips — SVG
<title>elements added to back, search, mkdir, upload, add-all, repeat, shuffle, auto-DJ, and visualizer icons - File explorer header icon hover — white-to-grey color transition on hover
Infrastructure
- Node.js >=22.5.0 — minimum version bumped for native SQLite support
- Electron 37 — bumped from 29 for Node 23+ with unflagged sqlite
- Scanner kill on shutdown — running scanner processes added to kill-list for clean server exit
- Removed dependencies — lokijs, ffbinaries, fluent-ffmpeg, escape-string-regexp