branderson f7b59e7e14 test: close coverage gaps found in final branch review
- add test_rebuild_inherits_the_parents_cover: covers the cover_path
  inheritance mechanism in the rebuild endpoint (Task 2's upload-retention
  design relied on it, but nothing exercised it)
- tighten test_lineage_marker_survives_in_the_accessibility_tree to assert
  the literal " rebuilt" screen-reader text, not just that rebuilt_from
  is referenced somewhere in paintCard
- normalize submit's youtube_url/genre/language the same way rebuild does,
  for symmetry, plus a pinning test
- pin acquire's stage outputs to [meta.json, audio.wav] in test_acquire.py,
  since web.py's _require_source hardcodes those same filenames
2026-07-27 02:55:56 -07:00
2026-07-25 21:38:24 -07:00
2026-07-25 21:38:24 -07:00

karaoke-maker

A CLI and minimal web UI that turns a song — title, artist, lyrics you supply, and a YouTube URL or local video file — into a playable UltraStar-format song folder for Melody Mania, a commercial UltraStar Deluxe fork.

The pipeline:

  1. acquire — download audio/video via yt-dlp (or use a local video file)
  2. separate — split vocals/instrumental with Demucs
  3. transcribe — send the vocal stem to your own intranet OpenAI-compatible Whisper server, as a sanity check that the supplied lyrics match the audio and to locate vocal sections
  4. align — forced-align the supplied reference lyrics against the vocal stem with wav2vec2 (torchaudio's MMS_FA) to get word timings
  5. pitch — track pitch on the vocal stem with torchcrepe
  6. notes — turn word timings + pitch into UltraStar notes
  7. grid — quantise notes to a beat grid
  8. package — write the final song folder (.txt + .mp3 + video + cover)

The shipped .mp3 is the full original mix (vocals included) — the separated stems are used for analysis only and are not included in the output.

The output is a best-effort draft, not a finished song. Every run ends by printing the low-confidence regions it found (e.g. 3 low-confidence notes near 0:42–0:47) — open the result in an UltraStar editor such as Yass or USDX and touch those spots up before playing.

Configuration

Config is TOML. Resolution order:

  1. --config <path> passed explicitly on the command line
  2. the KARAOKE_MAKER_CONFIG environment variable
  3. ~/.config/karaoke-maker/config.toml

Copy the example and fill in your Whisper server:

cp config.example.toml config.toml
$EDITOR config.toml   # set whisper_url at minimum

See config.example.toml for every available field (whisper_url, whisper_api_key, whisper_model, output_dir, work_dir, creator, demucs_model, crepe_model, device, bind_host, port).

Docker

cp config.example.toml config.toml
$EDITOR config.toml
docker compose up -d

The web UI is then at http://localhost:8000. Downloaded model weights (Demucs, wav2vec2, ...) are cached under ./data on the host so they survive container recreation.

Run the CLI inside the container instead of the web UI:

docker compose run --rm karaoke-maker karaoke-maker make \
  --title "Song Title" --artist "Artist Name" \
  --lyrics /data/lyrics.txt --youtube https://youtu.be/...

GPU passthrough requires the NVIDIA Container Toolkit installed on the host; docker-compose.yml requests one GPU via the nvidia device driver.

Bare-metal

pip install -e .
karaoke-maker make --help
karaoke-maker make --title TITLE --artist ARTIST --lyrics LYRICS_FILE \
  (--youtube URL | --video PATH) \
  [--genre GENRE] [--year YEAR] [--language LANGUAGE] [--cover COVER_IMAGE] \
  [--bpm BPM] [--force-from STAGE] [--config CONFIG]

Run the web UI instead with karaoke-maker serve [--config CONFIG].

Re-running a stage

Each stage caches its output under work_dir. If a later stage needs another pass (e.g. you want to retry alignment with different lyrics, or pitch tracking looks off), re-run with --force-from <stage> to redo that stage and everything after it, reusing the cached output of everything before it:

karaoke-maker make --title "..." --artist "..." --lyrics lyrics.txt \
  --youtube https://youtu.be/... --force-from align

Valid stages, in pipeline order: acquire, separate, transcribe, align, pitch, notes, grid, package.

S
Description
Self-hosted karaoke chart builder for UltraStar and compatible games. Give it a song's video and lyrics and it charts the notes, timing and pitch, ready for your collection. Fix anything in the built-in editor; your edits survive when you rebuild your whole collection after a songtrace update.
Readme AGPL-3.0
3.3 MiB
Languages
Python 71.5%
HTML 15%
JavaScript 12%
Shell 1.4%
Dockerfile 0.1%