- Sources: "free" (Creative Commons songs with media from github.com/UltraStar-Deluxe/songs) and "usdb" (usdb.animux.de with an account; audio/video via yt-dlp from the song's #VIDEO hints or YouTube links in the comments, covers from fanart.tv/YouTube) - Aggregated search (all sources in parallel, in-library flag), download queue into <library>/Downloads/<source>/<Artist - Title>, then rescan - Web UI in wwwroot (plain JS, no build): search, downloads with progress, library; phone first, dark mode, installable - Docker image with yt-dlp, ffmpeg and deno; library mounted writable - Tests for matching, USDB parsing and song rewriting Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
96 lines
6.1 KiB
Markdown
96 lines
6.1 KiB
Markdown
# 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://<server>: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 (`<source>/<Artist - Title>`) |
|
|
| `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
|
|
<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.
|
|
|
|
## 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/<job>` 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<version>`
|
|
(pushes `:<version>` and `:latest`). Tests: `Tests/SongServer`.
|