Skip to content

feat: stems option on text-to-music and video-to-music - #58

Merged
spencer-zqian merged 1 commit into
mainfrom
feat/stems
Aug 17, 2026
Merged

feat: stems option on text-to-music and video-to-music#58
spencer-zqian merged 1 commit into
mainfrom
feat/stems

Conversation

@spencer-zqian

Copy link
Copy Markdown
Contributor

Adds the API's new stems option to the core SDK and the CLI.

stems: true on textToMusic/videoToMusic async submits returns the generated track split into four separated instrument tracks — drums, bass, vocals, other — as a stems array alongside the clean audio. Free of charge; async-only (the SDK auto-selects async and rejects an explicit stream + stems client-side, same as ducking). On video-to-music it splits the generated music, never the video's own audio.

Result contract mirrored in the types: stems entries are looked up by stream_index, never position (a stream whose separation failed is absent), and stems_error can appear alongside a partial array — the CLI warns on a partial result and exits 0, and hard-fails only when --stems produced nothing, after the paid track is on disk. Separation adds 2-6 min typically with a 30-min ceiling, so the CLI uses a dedicated 40-min wait timeout for stems runs, following the dubbing precedent.

Changeset bumps sonilo 0.15.0→0.16.0 and sonilo-cli 0.14.0→0.15.0; sonilo-video-kit is not bumped (verified with changeset status).

Tests: 509 across the three workspaces, all green; lint + build clean.

stems: true (REST: stems, default false) also splits the generated track
into four separated stems — drums, bass, vocals, other. Free of charge.
On videoToMusic it splits the GENERATED music, never the source video's
own audio. It requires mode: "async" (the backend 400s it on the plain
stream), so only submit() sends it; stream()/generate() never do, and
videoToMusic.submit() auto-selects async, matching preserveSpeech and
ducking.

The task result gains two independent fields on MusicTaskResult: stems
(one StemsEntry — { stream_index, drums, bass, vocals, other }, each stem
an SfxMedia — per stream that separated successfully; looked up by
stream_index, never position, since the array can be shorter than audio)
and stems_error (why separation failed wholly or in part, or was skipped;
it can appear ALONGSIDE a partial stems array, so its presence never
means "no stems").

Separation runs after generation and typically adds 2-6 minutes to the
wait, giving up after 30 — so the CLI's --stems waits up to 40 minutes
(the generic 10 plus that ceiling), the way dubbing raises its own wait.
Both CLI commands write each arrived stem next to the main output with
the stem name inserted before the extension (per variant above
--variants 1), warn on stderr for a partial result, and exit non-zero
only when no stems came back at all.
@sapient-app

sapient-app Bot commented Aug 17, 2026

Copy link
Copy Markdown

Lightsage docs evals

Waiting for the staging docs URL before running evals.

Lightsage will start the selected PR evals automatically when GitHub reports a successful docs deployment for this PR. This usually happens within 15 minutes.

Commit: b1d3f84
Status: waiting for staging docs URL

@spencer-zqian
spencer-zqian merged commit f1cc567 into main Aug 17, 2026
1 check passed
@spencer-zqian
spencer-zqian deleted the feat/stems branch August 17, 2026 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant