# 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. The server also has a **web UI** (`http://:8099/`, made for phones, can be added to the home screen): search song sources on the internet, download songs into the library with one tap, and browse the library. ## Running it (Docker) ``` docker run -d --name vocaluxe-song-server -p 8099:8080 --user 99:100 \ -v /mnt/user/karaoke/songs:/songs \ -e Usdb__User=... -e Usdb__Password=... \ 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` (the web UI asks for it) | | `Library__DownloadFolder` | `Downloads` | Where downloaded songs go, below the library root (`/`) | | `Usdb__User`, `Usdb__Password` | empty | Account at usdb.animux.de; enables the USDB source | The library must be writable for downloads. The image contains yt-dlp (newest at build time; YouTube changes often, so rebuild the image when downloads start failing), ffmpeg and deno. 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`: ```xml http://192.168.1.108:8099 ``` Local song folders keep working alongside the server. The cache is in the Vocaluxe data folder under `SongServer/_`; 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. ## Song sources (search and download) Research (2026-11): where UltraStar songs come from. | Source | What it has | Used here | |---|---|---| | [UltraStar-Deluxe/songs](https://github.com/UltraStar-Deluxe/songs) | ~40 Creative Commons / public domain songs **with audio** and covers | **Yes**, source `free`, no account | | [USDB](https://usdb.animux.de) | The largest database (tens of thousands of songs), only the text files; free account needed. Songs reference audio/video (mostly YouTube) and covers (fanart.tv) in `#VIDEO` (`v=`, `a=`, `co=`, `bg=`) or in comments | **Yes**, source `usdb`: text from USDB, media via yt-dlp, like [usdb_syncer](https://github.com/bohning/usdb_syncer) | | [UltraStar-es](https://ultrastar-es.org/en/canciones) | Large Spanish database (also other languages) | Not yet | | [Performous packs](https://performous.org/songs) | 4 zip packs (libre, restricted, Jonathan Coulton, Shearer; CC licenses) | Not yet (Coulton songs are in `free`) | | TXT-only GitHub repos (razzertronic/usdx-songs, derco0n/UltrastarSongs, ...) | Text files without media | Not yet | | [UltraSinger](https://github.com/rakuri255/UltraSinger) | Creates a song from any audio with AI | Planned: songs that exist nowhere | Songs, videos and lyrics can be copyrighted. The `free` source only has openly licensed songs; what you download from USDB/YouTube is your own responsibility. New sources implement `Sources/ISongSource.cs` (search + download into a folder) and are registered in `Program.cs`. Downloads run one at a time; a song is downloaded into `Downloads/.incoming/` and moved into place when complete. ## 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 | | `GET /sources` | Song sources, enabled or not (with the reason) | | `GET /search?q=` | Search all enabled sources at once; results say whether a song is in the library | | `GET /downloads` | Download jobs with state and progress | | `POST /downloads` | Queue a download: `{"source", "sourceId", "artist", "title"}` from a search result | ## 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` (pushes `:` and `:latest`). Tests: `Tests/SongServer`.