- VocaluxeSongServer: ASP.NET Core server that scans an UltraStar library and serves the song list (ETag), single files (Range) and zip bundles; optional API key; Dockerfile and Gitea workflow for git.disi.dev/projects/vocaluxe-song-server - Game: config section SongServer (Url, ApiKey). At song loading, the song text files are mirrored into a local cache that is loaded like a song folder; without connection the last library is used - VocaluxeLib: CSongFiles hook for all song file access; media are downloaded on demand (covers in the background, preview audio, everything before singing with progress in the sing screen) - Tests for scanner, API and downloads (incl. resume); AGENTS.md for the fork Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vocaluxe song server
A central song library for Vocaluxe. The server hosts the UltraStar song folders (text file, audio, video, cover, backgrounds). Vocaluxe mirrors the song text files at startup and downloads audio, video and images only when they are needed, then keeps them in a local cache.
Running it (Docker)
docker run -d --name vocaluxe-song-server -p 8099:8080 \
-v /mnt/user/karaoke/songs:/songs:ro \
git.disi.dev/projects/vocaluxe-song-server:latest
| Setting (environment variable) | Default | Meaning |
|---|---|---|
Library__Path |
/songs |
Root folder of the song library; any folder structure below it works |
Library__ScanIntervalMinutes |
10 |
Rescan interval; 0 = only at startup and via the rescan endpoint |
Library__ApiKey |
empty | If set, clients must send it as X-Api-Key |
A song is any .txt file with #TITLE, #ARTIST and #MP3 (or #AUDIO). All files in its folder are served.
Files outside song folders are never served.
Using it in Vocaluxe
In config.xml:
<SongServer>
<Url>http://192.168.1.108:8099</Url>
<ApiKey />
</SongServer>
Local song folders keep working alongside the server. The cache is in the Vocaluxe data folder under
SongServer/<host>_<port>; it mirrors the server, so songs removed on the server disappear from it. Without a
connection Vocaluxe uses the library of the last start, and every song whose files were downloaded before can be sung.
What is downloaded when:
- Startup: the song list and all song text files (only changed ones after the first time). Covers are downloaded by the cover loader in the background.
- Song selected (preview): the audio file; the preview starts when it's there. The video is downloaded in the background.
- Song started: everything still missing (video, instrumental/vocals, backgrounds). The sing screen shows the progress and starts the song when the download is finished.
API
All endpoints are under /api/v1 (plus GET /health). Paths are relative to the library root and use /.
The types are in Contracts/LibraryDtos.cs, which Vocaluxe links in.
| Endpoint | What it does |
|---|---|
GET /library |
Songs (id, path, title, artist) and all files (path, size, modified); ETag/304 |
GET /files/{path} |
One file, with Range support (resumable downloads) |
POST /files/bundle |
Several files as a zip, body {"paths": [...]} (max. 2000), used for text files |
POST /library/rescan |
Rescan now instead of waiting for the interval |
Building and releasing
dotnet run --project VocaluxeSongServer -- --Library:Path=D:\Songs --urls http://localhost:8099 runs it locally.
The image is built by .gitea/workflows/song-server.yml: set VERSION, then push the tag songserver-v<version>
(pushes :<version> and :latest). Tests: Tests/SongServer.