sonilo 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -64,6 +64,16 @@ interface TextToMusicParams {
64
64
  * meaningful via `submit()`; `stream()`/`generate()` never send it, since
65
65
  * they always request a plain stream. */
66
66
  variantsNum?: number;
67
+ /** Also split the generated track into four separated stems — `drums`,
68
+ * `bass`, `vocals`, `other` — delivered on the task result's `stems`
69
+ * array. Free of charge. Requires `mode: "async"` (the backend rejects it
70
+ * on the plain stream with a 400), so it is only meaningful via
71
+ * `submit()`; `stream()`/`generate()` never send it. Separation runs after
72
+ * generation and typically adds 2-6 minutes to the wait (it gives up after
73
+ * 30), so raise `tasks.wait`'s `timeout` accordingly. See `StemsEntry` for
74
+ * the result shape, and `MusicTaskResult.stems_error` for how failures are
75
+ * reported. */
76
+ stems?: boolean;
67
77
  /** Bounds the stream: aborting this cancels the in-flight generation.
68
78
  * Passed straight through to `fetch` — it is never rewrapped as
69
79
  * RequestTimeoutError, since the client's own absolute timeout does not
@@ -118,6 +128,17 @@ interface VideoToMusicParams {
118
128
  * default applies; `0` is a meaningful value and is sent. Out-of-range
119
129
  * values are rejected server-side with a 422. */
120
130
  promptInfluence?: number;
131
+ /** Also split the generated music into four separated stems — `drums`,
132
+ * `bass`, `vocals`, `other` — delivered on the task result's `stems`
133
+ * array. It splits the GENERATED music, never the source video's own
134
+ * audio. Free of charge. Requires `mode: "async"` (auto-selected by
135
+ * `submit()`; the backend rejects it on the plain stream with a 400), so
136
+ * it is only meaningful via `submit()` — `stream()`/`generate()` never
137
+ * send it. Separation runs after generation and typically adds 2-6
138
+ * minutes to the wait (it gives up after 30), so raise `tasks.wait`'s
139
+ * `timeout` accordingly. See `StemsEntry` for the result shape, and
140
+ * `MusicTaskResult.stems_error` for how failures are reported. */
141
+ stems?: boolean;
121
142
  }
122
143
  /** One service's free-trial allowance. `remaining` is already floored at 0,
123
144
  * so it is safe to compare directly. */
@@ -244,6 +265,21 @@ interface MusicTitle {
244
265
  summary?: string;
245
266
  display_tags?: string[];
246
267
  }
268
+ /** The four separated stems of one generated stream, present when the
269
+ * request set `stems: true`. Each stem is an ordinary media object
270
+ * (`url` / `content_type` / `file_size`), so any of them can be passed to
271
+ * `download()`. The stems normally follow the request's `outputFormat`;
272
+ * each stem's own `content_type` reports what was actually delivered. */
273
+ interface StemsEntry {
274
+ /** Which `audio` entry this stems set belongs to. Match on this field,
275
+ * never on array position — `stems` carries only the streams that
276
+ * separated successfully, so it can be shorter than `audio`. */
277
+ stream_index: number;
278
+ drums: SfxMedia;
279
+ bass: SfxMedia;
280
+ vocals: SfxMedia;
281
+ other: SfxMedia;
282
+ }
247
283
  /** State of an async video-to-music task (`tasks.get`) or its final result
248
284
  * (`tasks.wait<MusicTaskResult>()`). Only reachable via `videoToMusic.submit()`
249
285
  * with `mode: "async"`. */
@@ -259,6 +295,16 @@ interface MusicTaskResult extends BaseTaskResult {
259
295
  /** Music ducked under the source voice (per variant when `variantsNum` is
260
296
  * above 1); present only when `ducking` ran. */
261
297
  ducked?: MusicMediaEntry[];
298
+ /** Separated stems, one entry per stream that separated successfully;
299
+ * only appears when the request set `stems: true`. Look entries up by
300
+ * `stream_index`, never by array position — the array can be shorter than
301
+ * `audio` when separation failed for some streams (see `stems_error`). */
302
+ stems?: StemsEntry[];
303
+ /** Why stem separation failed wholly or in part, or was skipped. It can
304
+ * appear ALONGSIDE a partial `stems` array, so never treat its presence as
305
+ * "no stems" — check `stems` itself for what did arrive. Independent of
306
+ * the task's own `status`/`error`: the generation is intact either way. */
307
+ stems_error?: string;
262
308
  /** Variant 0's title — the top-level field always names the first variant,
263
309
  * even when `variantsNum` produced others with their own titles on
264
310
  * `audio[]`. */
@@ -596,8 +642,8 @@ declare class TextToMusic {
596
642
  /**
597
643
  * Submit an async text-to-music task; poll with
598
644
  * `client.tasks.wait<MusicTaskResult>(task.task_id)`. Required for
599
- * a non-m4a `outputFormat` and `variantsNum` above 1. `stream()`/`generate()`
600
- * remain the streaming path.
645
+ * a non-m4a `outputFormat`, `variantsNum` above 1, and `stems`.
646
+ * `stream()`/`generate()` remain the streaming path.
601
647
  */
602
648
  submit(params: TextToMusicParams): Promise<SfxTask>;
603
649
  }
@@ -610,9 +656,9 @@ declare class VideoToMusic {
610
656
  /**
611
657
  * Submit an async video-to-music task; poll its result with
612
658
  * `client.tasks.wait<MusicTaskResult>(task.task_id)`. Required for
613
- * `isolateVocals`/`preserveSpeech`, a non-m4a `outputFormat`, and
614
- * `variantsNum` above 1 — the backend rejects all of these on the plain
615
- * stream, and they only ever run in async mode.
659
+ * `isolateVocals`/`preserveSpeech`, a non-m4a `outputFormat`,
660
+ * `variantsNum` above 1, and `stems` — the backend rejects all of these on
661
+ * the plain stream, and they only ever run in async mode.
616
662
  */
617
663
  submit(params: VideoToMusicParams): Promise<SfxTask>;
618
664
  }
@@ -835,6 +881,6 @@ declare class RequestTimeoutError extends SoniloError {
835
881
  declare function download(media: SfxMedia | string | undefined, fetchFn?: typeof globalThis.fetch, timeout?: number): Promise<Uint8Array>;
836
882
 
837
883
  /** The SDK's own version. Generated by scripts/sync-versions.mjs — do not edit. */
838
- declare const VERSION = "0.15.0";
884
+ declare const VERSION = "0.16.0";
839
885
 
840
- export { APIError, type AccountServices, type AnalysisSegment, type AnalysisVariation, type AudioChunkEvent, type AudioDuckingParams, AuthenticationError, BadRequestError, type BaseTaskResult, type CompleteEvent, type CostEvent, type CostInfo, DEFAULT_TIMEOUT_MS, type DailyUsage, type DubbingLanguage, type DubbingParams, type DubbingResult, type DuckingResult, type ErrorEvent, GenerationError, type MusicMediaEntry, type MusicMuxEntry, type MusicTaskResult, type MusicTitle, PaymentRequiredError, RateLimitError, RequestTimeoutError, type Segment, type SegmentLabel, type SfxAudioFormat, type SfxError, type SfxMedia, type SfxResult, type SfxSegment, type SfxTask, SoniloClient, type SoniloClientOptions, SoniloError, type SoundOutputEntry, type SoundResult, type StreamEvent, TaskFailedError, TaskTimeoutError, type TextToMusicParams, type TextToSfxParams, type TitleEvent, type Track, TrialExhaustedError, type TrialQuota, type UnknownEvent, type UsageResponse, type UsageSummary, VERSION, type VideoAnalysisParams, type VideoAnalysisResult, type VideoInput, type VideoResult, type VideoToMusicParams, type VideoToSfxParams, type VideoToSoundParams, type VideoToVideoMusicParams, type VideoToVideoSfxParams, type VideoToVideoSoundParams, type WaitOptions, download, isAudioChunkEvent, isErrorEvent };
886
+ export { APIError, type AccountServices, type AnalysisSegment, type AnalysisVariation, type AudioChunkEvent, type AudioDuckingParams, AuthenticationError, BadRequestError, type BaseTaskResult, type CompleteEvent, type CostEvent, type CostInfo, DEFAULT_TIMEOUT_MS, type DailyUsage, type DubbingLanguage, type DubbingParams, type DubbingResult, type DuckingResult, type ErrorEvent, GenerationError, type MusicMediaEntry, type MusicMuxEntry, type MusicTaskResult, type MusicTitle, PaymentRequiredError, RateLimitError, RequestTimeoutError, type Segment, type SegmentLabel, type SfxAudioFormat, type SfxError, type SfxMedia, type SfxResult, type SfxSegment, type SfxTask, SoniloClient, type SoniloClientOptions, SoniloError, type SoundOutputEntry, type SoundResult, type StemsEntry, type StreamEvent, TaskFailedError, TaskTimeoutError, type TextToMusicParams, type TextToSfxParams, type TitleEvent, type Track, TrialExhaustedError, type TrialQuota, type UnknownEvent, type UsageResponse, type UsageSummary, VERSION, type VideoAnalysisParams, type VideoAnalysisResult, type VideoInput, type VideoResult, type VideoToMusicParams, type VideoToSfxParams, type VideoToSoundParams, type VideoToVideoMusicParams, type VideoToVideoSfxParams, type VideoToVideoSoundParams, type WaitOptions, download, isAudioChunkEvent, isErrorEvent };
package/dist/index.d.ts CHANGED
@@ -64,6 +64,16 @@ interface TextToMusicParams {
64
64
  * meaningful via `submit()`; `stream()`/`generate()` never send it, since
65
65
  * they always request a plain stream. */
66
66
  variantsNum?: number;
67
+ /** Also split the generated track into four separated stems — `drums`,
68
+ * `bass`, `vocals`, `other` — delivered on the task result's `stems`
69
+ * array. Free of charge. Requires `mode: "async"` (the backend rejects it
70
+ * on the plain stream with a 400), so it is only meaningful via
71
+ * `submit()`; `stream()`/`generate()` never send it. Separation runs after
72
+ * generation and typically adds 2-6 minutes to the wait (it gives up after
73
+ * 30), so raise `tasks.wait`'s `timeout` accordingly. See `StemsEntry` for
74
+ * the result shape, and `MusicTaskResult.stems_error` for how failures are
75
+ * reported. */
76
+ stems?: boolean;
67
77
  /** Bounds the stream: aborting this cancels the in-flight generation.
68
78
  * Passed straight through to `fetch` — it is never rewrapped as
69
79
  * RequestTimeoutError, since the client's own absolute timeout does not
@@ -118,6 +128,17 @@ interface VideoToMusicParams {
118
128
  * default applies; `0` is a meaningful value and is sent. Out-of-range
119
129
  * values are rejected server-side with a 422. */
120
130
  promptInfluence?: number;
131
+ /** Also split the generated music into four separated stems — `drums`,
132
+ * `bass`, `vocals`, `other` — delivered on the task result's `stems`
133
+ * array. It splits the GENERATED music, never the source video's own
134
+ * audio. Free of charge. Requires `mode: "async"` (auto-selected by
135
+ * `submit()`; the backend rejects it on the plain stream with a 400), so
136
+ * it is only meaningful via `submit()` — `stream()`/`generate()` never
137
+ * send it. Separation runs after generation and typically adds 2-6
138
+ * minutes to the wait (it gives up after 30), so raise `tasks.wait`'s
139
+ * `timeout` accordingly. See `StemsEntry` for the result shape, and
140
+ * `MusicTaskResult.stems_error` for how failures are reported. */
141
+ stems?: boolean;
121
142
  }
122
143
  /** One service's free-trial allowance. `remaining` is already floored at 0,
123
144
  * so it is safe to compare directly. */
@@ -244,6 +265,21 @@ interface MusicTitle {
244
265
  summary?: string;
245
266
  display_tags?: string[];
246
267
  }
268
+ /** The four separated stems of one generated stream, present when the
269
+ * request set `stems: true`. Each stem is an ordinary media object
270
+ * (`url` / `content_type` / `file_size`), so any of them can be passed to
271
+ * `download()`. The stems normally follow the request's `outputFormat`;
272
+ * each stem's own `content_type` reports what was actually delivered. */
273
+ interface StemsEntry {
274
+ /** Which `audio` entry this stems set belongs to. Match on this field,
275
+ * never on array position — `stems` carries only the streams that
276
+ * separated successfully, so it can be shorter than `audio`. */
277
+ stream_index: number;
278
+ drums: SfxMedia;
279
+ bass: SfxMedia;
280
+ vocals: SfxMedia;
281
+ other: SfxMedia;
282
+ }
247
283
  /** State of an async video-to-music task (`tasks.get`) or its final result
248
284
  * (`tasks.wait<MusicTaskResult>()`). Only reachable via `videoToMusic.submit()`
249
285
  * with `mode: "async"`. */
@@ -259,6 +295,16 @@ interface MusicTaskResult extends BaseTaskResult {
259
295
  /** Music ducked under the source voice (per variant when `variantsNum` is
260
296
  * above 1); present only when `ducking` ran. */
261
297
  ducked?: MusicMediaEntry[];
298
+ /** Separated stems, one entry per stream that separated successfully;
299
+ * only appears when the request set `stems: true`. Look entries up by
300
+ * `stream_index`, never by array position — the array can be shorter than
301
+ * `audio` when separation failed for some streams (see `stems_error`). */
302
+ stems?: StemsEntry[];
303
+ /** Why stem separation failed wholly or in part, or was skipped. It can
304
+ * appear ALONGSIDE a partial `stems` array, so never treat its presence as
305
+ * "no stems" — check `stems` itself for what did arrive. Independent of
306
+ * the task's own `status`/`error`: the generation is intact either way. */
307
+ stems_error?: string;
262
308
  /** Variant 0's title — the top-level field always names the first variant,
263
309
  * even when `variantsNum` produced others with their own titles on
264
310
  * `audio[]`. */
@@ -596,8 +642,8 @@ declare class TextToMusic {
596
642
  /**
597
643
  * Submit an async text-to-music task; poll with
598
644
  * `client.tasks.wait<MusicTaskResult>(task.task_id)`. Required for
599
- * a non-m4a `outputFormat` and `variantsNum` above 1. `stream()`/`generate()`
600
- * remain the streaming path.
645
+ * a non-m4a `outputFormat`, `variantsNum` above 1, and `stems`.
646
+ * `stream()`/`generate()` remain the streaming path.
601
647
  */
602
648
  submit(params: TextToMusicParams): Promise<SfxTask>;
603
649
  }
@@ -610,9 +656,9 @@ declare class VideoToMusic {
610
656
  /**
611
657
  * Submit an async video-to-music task; poll its result with
612
658
  * `client.tasks.wait<MusicTaskResult>(task.task_id)`. Required for
613
- * `isolateVocals`/`preserveSpeech`, a non-m4a `outputFormat`, and
614
- * `variantsNum` above 1 — the backend rejects all of these on the plain
615
- * stream, and they only ever run in async mode.
659
+ * `isolateVocals`/`preserveSpeech`, a non-m4a `outputFormat`,
660
+ * `variantsNum` above 1, and `stems` — the backend rejects all of these on
661
+ * the plain stream, and they only ever run in async mode.
616
662
  */
617
663
  submit(params: VideoToMusicParams): Promise<SfxTask>;
618
664
  }
@@ -835,6 +881,6 @@ declare class RequestTimeoutError extends SoniloError {
835
881
  declare function download(media: SfxMedia | string | undefined, fetchFn?: typeof globalThis.fetch, timeout?: number): Promise<Uint8Array>;
836
882
 
837
883
  /** The SDK's own version. Generated by scripts/sync-versions.mjs — do not edit. */
838
- declare const VERSION = "0.15.0";
884
+ declare const VERSION = "0.16.0";
839
885
 
840
- export { APIError, type AccountServices, type AnalysisSegment, type AnalysisVariation, type AudioChunkEvent, type AudioDuckingParams, AuthenticationError, BadRequestError, type BaseTaskResult, type CompleteEvent, type CostEvent, type CostInfo, DEFAULT_TIMEOUT_MS, type DailyUsage, type DubbingLanguage, type DubbingParams, type DubbingResult, type DuckingResult, type ErrorEvent, GenerationError, type MusicMediaEntry, type MusicMuxEntry, type MusicTaskResult, type MusicTitle, PaymentRequiredError, RateLimitError, RequestTimeoutError, type Segment, type SegmentLabel, type SfxAudioFormat, type SfxError, type SfxMedia, type SfxResult, type SfxSegment, type SfxTask, SoniloClient, type SoniloClientOptions, SoniloError, type SoundOutputEntry, type SoundResult, type StreamEvent, TaskFailedError, TaskTimeoutError, type TextToMusicParams, type TextToSfxParams, type TitleEvent, type Track, TrialExhaustedError, type TrialQuota, type UnknownEvent, type UsageResponse, type UsageSummary, VERSION, type VideoAnalysisParams, type VideoAnalysisResult, type VideoInput, type VideoResult, type VideoToMusicParams, type VideoToSfxParams, type VideoToSoundParams, type VideoToVideoMusicParams, type VideoToVideoSfxParams, type VideoToVideoSoundParams, type WaitOptions, download, isAudioChunkEvent, isErrorEvent };
886
+ export { APIError, type AccountServices, type AnalysisSegment, type AnalysisVariation, type AudioChunkEvent, type AudioDuckingParams, AuthenticationError, BadRequestError, type BaseTaskResult, type CompleteEvent, type CostEvent, type CostInfo, DEFAULT_TIMEOUT_MS, type DailyUsage, type DubbingLanguage, type DubbingParams, type DubbingResult, type DuckingResult, type ErrorEvent, GenerationError, type MusicMediaEntry, type MusicMuxEntry, type MusicTaskResult, type MusicTitle, PaymentRequiredError, RateLimitError, RequestTimeoutError, type Segment, type SegmentLabel, type SfxAudioFormat, type SfxError, type SfxMedia, type SfxResult, type SfxSegment, type SfxTask, SoniloClient, type SoniloClientOptions, SoniloError, type SoundOutputEntry, type SoundResult, type StemsEntry, type StreamEvent, TaskFailedError, TaskTimeoutError, type TextToMusicParams, type TextToSfxParams, type TitleEvent, type Track, TrialExhaustedError, type TrialQuota, type UnknownEvent, type UsageResponse, type UsageSummary, VERSION, type VideoAnalysisParams, type VideoAnalysisResult, type VideoInput, type VideoResult, type VideoToMusicParams, type VideoToSfxParams, type VideoToSoundParams, type VideoToVideoMusicParams, type VideoToVideoSfxParams, type VideoToVideoSoundParams, type WaitOptions, download, isAudioChunkEvent, isErrorEvent };
package/dist/index.js CHANGED
@@ -305,8 +305,8 @@ var TextToMusic = class {
305
305
  /**
306
306
  * Submit an async text-to-music task; poll with
307
307
  * `client.tasks.wait<MusicTaskResult>(task.task_id)`. Required for
308
- * a non-m4a `outputFormat` and `variantsNum` above 1. `stream()`/`generate()`
309
- * remain the streaming path.
308
+ * a non-m4a `outputFormat`, `variantsNum` above 1, and `stems`.
309
+ * `stream()`/`generate()` remain the streaming path.
310
310
  */
311
311
  async submit(params) {
312
312
  const mode = params.mode ?? "async";
@@ -326,6 +326,9 @@ var TextToMusic = class {
326
326
  if (params.variantsNum !== void 0) {
327
327
  form.set("variants_num", String(params.variantsNum));
328
328
  }
329
+ if (params.stems !== void 0) {
330
+ form.set("stems", String(params.stems));
331
+ }
329
332
  const res = await this.client.request("/v1/text-to-music", {
330
333
  method: "POST",
331
334
  body: form
@@ -409,9 +412,9 @@ var VideoToMusic = class {
409
412
  /**
410
413
  * Submit an async video-to-music task; poll its result with
411
414
  * `client.tasks.wait<MusicTaskResult>(task.task_id)`. Required for
412
- * `isolateVocals`/`preserveSpeech`, a non-m4a `outputFormat`, and
413
- * `variantsNum` above 1 — the backend rejects all of these on the plain
414
- * stream, and they only ever run in async mode.
415
+ * `isolateVocals`/`preserveSpeech`, a non-m4a `outputFormat`,
416
+ * `variantsNum` above 1, and `stems` — the backend rejects all of these on
417
+ * the plain stream, and they only ever run in async mode.
415
418
  */
416
419
  async submit(params) {
417
420
  if (params.video === void 0 === (params.videoUrl === void 0)) {
@@ -421,11 +424,11 @@ var VideoToMusic = class {
421
424
  const needsAsync = params.isolateVocals || params.preserveSpeech || params.ducking !== void 0 || // Any non-m4a container is a finalize-time transcode, so it needs
422
425
  // async. Checking != "m4a" rather than == "wav" keeps this correct
423
426
  // as formats are added (mp3 landed after the original check).
424
- params.outputFormat !== void 0 && params.outputFormat !== "m4a" || params.variantsNum !== void 0 && params.variantsNum > 1;
427
+ params.outputFormat !== void 0 && params.outputFormat !== "m4a" || params.variantsNum !== void 0 && params.variantsNum > 1 || params.stems !== void 0;
425
428
  if (mode === void 0) mode = "async";
426
429
  if (needsAsync && mode !== "async") {
427
430
  throw new SoniloError(
428
- 'isolateVocals/preserveSpeech/ducking/outputFormat other than "m4a"/variantsNum > 1 require mode: "async"'
431
+ 'isolateVocals/preserveSpeech/ducking/stems/outputFormat other than "m4a"/variantsNum > 1 require mode: "async"'
429
432
  );
430
433
  }
431
434
  const form = new FormData();
@@ -455,6 +458,9 @@ var VideoToMusic = class {
455
458
  if (params.variantsNum !== void 0) {
456
459
  form.set("variants_num", String(params.variantsNum));
457
460
  }
461
+ if (params.stems !== void 0) {
462
+ form.set("stems", String(params.stems));
463
+ }
458
464
  if (params.promptInfluence !== void 0) {
459
465
  form.set("prompt_influence", String(params.promptInfluence));
460
466
  }
@@ -783,7 +789,7 @@ var VideoAnalysis = class {
783
789
  };
784
790
 
785
791
  // src/version.ts
786
- var VERSION = "0.15.0";
792
+ var VERSION = "0.16.0";
787
793
 
788
794
  // src/client.ts
789
795
  var DEFAULT_BASE_URL = "https://api.sonilo.com";