Install
openclaw skills install @nickflach/album-releaseShip a complete AI album in one run: cache your own lyrics, render tracks via the Suno direct API, generate one cover per song in the OpenBotCity Pixel Atelier, build a 1080p album film with karaoke subtitles, upload to YouTube, deploy to an internet radio server, and premiere it on air. Use when releasing an album end-to-end, re-running a failed phase, or timing an on-air album premiere.
openclaw skills install @nickflach/album-releaseOne config JSON in, a released album out: audio, art, film, YouTube,
radio deploy, on-air premiere, social announce. Every phase is
idempotent — re-run scripts/release-album.sh after any failure and it
resumes where it stopped.
Proven end-to-end: a 7-song album went from blank page to on-air premiere in ~2.5 hours (music ~25 min, art ~9 min, film + upload ~15 min).
scripts/suno_album_builder.sh renders each track via
Suno V4_5PLUS custom mode (two variants per track), resumable via a
per-track ledger.art_prompt (75 s spacing to dodge the
creative-loop detector), then downloads the PNGs from the gallery.Phases: preflight → music → art → copy-music → fetch-art → transcribe → build-video → youtube → deploy → announce. Skip any subset with
RELEASE_SKIP="deploy,announce".
~/.suno_api_key (or SUNO_API_KEY /
SUNO_API_KEY_FILE env) — sunoapi.org-style direct API~/.openbotcity/credentials.json
({"jwt": "..."}; override with OBC_CREDENTIALS_FILE) — only for the
art phase.youtube.json — only for the
upload phaseserver/dj-engine.js ALBUMS with exact track titles, or preflight
aborts. Point RADIO_ROOT at the checkout if these scripts do not live
in its scripts/ directory.# 1. Write the config (full schema in release-album.sh header):
# name, out_dir, ledger, theme, default_style,
# tracks[{title, style, art_prompt}], release{lead_track, youtube_*,
# tracker_url, oracle_host, oracle_music_dir, ssh_key}
# 2. RECOMMENDED — write the lyrics yourself:
# pre-create <out_dir>/lyrics_<safe_title>.txt per track
# (safe_title = spaces→_, /→-, apostrophes deleted). A cache file
# >100 chars is used verbatim. Without a cache the builder calls an
# optional HRM lyrics generator (HRM_LYRICS_SRC) and skips the track
# if unavailable — so pre-caching is the portable path.
# 3. Run it (Windows: config path MUST be C:/Users/... style)
bash scripts/release-album.sh "/abs/path/my-album.json"
# Control publish timing by skipping phases, then re-running:
RELEASE_SKIP="deploy,announce" bash scripts/release-album.sh "<config>"
RELEASE_SKIP="deploy,announce".copy-music/deploy run
AFTER the ~9-minute art phase. scp <out_dir>/<safe_title>_v1.mp3 to
the host's music dir renamed to exact "<Title>.mp3", pull, restart.curl -G -X POST "http://localhost:8888/api/album/showcase" \
--data-urlencode "album=<ALBUM NAME>" \
--data-urlencode "duration=45" \
--data-urlencode "struggles=<the real making-of story — feeds the narration>"
C:/Users/... — the embedded
Python rejects MSYS /c/Users/... and the builder silently no-ops.theme and default_style are
interpolated into single-quoted inline Python — keep them
apostrophe-free. Per-track fields and lyrics are safe./artifacts/generate-image and
/buildings/enter — the /actions/* forms are MCP-only and 404.https://www.youtube.com/oembed?url=...) — uploads can vanish after
a 200.| File | Purpose |
|---|---|
scripts/release-album.sh | The pipeline (phase gate, config schema in header) |
scripts/suno_album_builder.sh | Suno direct-API track renderer (ledger-resumable) |
scripts/release-album-transcribe.py | Timestamped lyrics → ASS karaoke subtitles |
scripts/release-album-upload-youtube.js | Resumable YouTube upload |
scripts/post-track-announce.js | Social fan-out announce (runs where creds live) |