sonilo 0.4.0 → 0.5.1

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
@@ -239,6 +239,41 @@ interface VideoToVideoSfxParams {
239
239
  prompt?: string;
240
240
  segments?: SfxSegment[];
241
241
  }
242
+ /** Params for `videoToSound` and `videoToVideoSound`. Both endpoints take the
243
+ * identical form, so they share one params type. */
244
+ interface VideoToSoundParams {
245
+ video?: VideoInput;
246
+ videoUrl?: string;
247
+ /** Style hint for the generated music bed. */
248
+ musicPrompt?: string;
249
+ /** Description of the sound effects layered over the music. */
250
+ sfxPrompt?: string;
251
+ /** Per-segment SFX descriptions; must start at 0 and be contiguous. */
252
+ segments?: SfxSegment[];
253
+ /** Keep the source speech in the result. */
254
+ preserveSpeech?: boolean;
255
+ /** Duck the generated music under the source speech. Default-ON
256
+ * server-side: leave unset to keep it on, pass `false` to opt out. */
257
+ ducking?: boolean;
258
+ }
259
+ /** Result of a `videoToSound` / `videoToVideoSound` task (`tasks.get`) or its
260
+ * final state (`generate`).
261
+ *
262
+ * The combined music+SFX result is `output_url` — a bare presigned URL rather
263
+ * than a media object, since these endpoints render one artifact whose kind is
264
+ * announced by `output_type` ("audio" for video-to-sound, "video" for
265
+ * video-to-video-sound). `music`, `music_processed` and `sfx` are the
266
+ * individual stems; pass any of them, or `output_url` itself, to `download()`. */
267
+ interface SoundResult extends BaseTaskResult {
268
+ output_url?: string;
269
+ output_type?: "audio" | "video";
270
+ output_bytes?: number;
271
+ music?: SfxMedia;
272
+ /** Present only when `preserveSpeech`/`ducking` altered the music bed. */
273
+ music_processed?: SfxMedia;
274
+ sfx?: SfxMedia;
275
+ duration_seconds?: number;
276
+ }
242
277
 
243
278
  declare class Account {
244
279
  private readonly client;
@@ -332,6 +367,24 @@ declare class VideoToVideoSfx {
332
367
  generate(params: VideoToVideoSfxParams, opts?: WaitOptions): Promise<VideoResult>;
333
368
  }
334
369
 
370
+ /** Generate a combined music + sound-effects track for a video and get back
371
+ * the mixed audio. Async only. */
372
+ declare class VideoToSound {
373
+ private readonly client;
374
+ constructor(client: SoniloClient);
375
+ submit(params: VideoToSoundParams): Promise<SfxTask>;
376
+ generate(params: VideoToSoundParams, opts?: WaitOptions): Promise<SoundResult>;
377
+ }
378
+
379
+ /** Generate a combined music + sound-effects track for a video and get back a
380
+ * re-hosted video with that track muxed in. Async only. */
381
+ declare class VideoToVideoSound {
382
+ private readonly client;
383
+ constructor(client: SoniloClient);
384
+ submit(params: VideoToSoundParams): Promise<SfxTask>;
385
+ generate(params: VideoToSoundParams, opts?: WaitOptions): Promise<SoundResult>;
386
+ }
387
+
335
388
  interface SoniloClientOptions {
336
389
  /** Defaults to the SONILO_API_KEY environment variable (Node.js only). */
337
390
  apiKey?: string;
@@ -341,6 +394,14 @@ interface SoniloClientOptions {
341
394
  fetch?: typeof globalThis.fetch;
342
395
  /** Milliseconds before an in-flight request is aborted. Default 600000. */
343
396
  timeout?: number;
397
+ /**
398
+ * Identifies a wrapper built on this SDK (the CLI, the video kit) in the
399
+ * `X-Sonilo-Client` header. Leave unset for direct SDK use — without an
400
+ * override a wrapper's traffic is indistinguishable from the SDK's own.
401
+ */
402
+ clientName?: string;
403
+ /** Version reported alongside `clientName`. Defaults to the SDK's version. */
404
+ clientVersion?: string;
344
405
  }
345
406
  /** Milliseconds before an in-flight request is aborted, unless overridden. */
346
407
  declare const DEFAULT_TIMEOUT_MS = 600000;
@@ -349,6 +410,8 @@ declare class SoniloClient {
349
410
  private readonly apiKey;
350
411
  private readonly fetchFn;
351
412
  private readonly timeout;
413
+ private readonly clientName;
414
+ private readonly clientVersion;
352
415
  readonly account: Account;
353
416
  readonly tasks: Tasks;
354
417
  readonly textToMusic: TextToMusic;
@@ -357,6 +420,8 @@ declare class SoniloClient {
357
420
  readonly videoToSfx: VideoToSfx;
358
421
  readonly videoToVideoMusic: VideoToVideoMusic;
359
422
  readonly videoToVideoSfx: VideoToVideoSfx;
423
+ readonly videoToSound: VideoToSound;
424
+ readonly videoToVideoSound: VideoToVideoSound;
360
425
  constructor(options?: SoniloClientOptions);
361
426
  /**
362
427
  * Perform an authenticated request; throws a typed error on non-2xx.
@@ -422,9 +487,14 @@ declare class TaskTimeoutError extends SoniloError {
422
487
  declare class RequestTimeoutError extends SoniloError {
423
488
  }
424
489
 
425
- /** Fetch a result media file. The URL is presigned — no API key is sent. */
426
- declare function download(media: SfxMedia | undefined, fetchFn?: typeof globalThis.fetch, timeout?: number): Promise<Uint8Array>;
490
+ /** Fetch a result media file. The URL is presigned — no API key is sent.
491
+ *
492
+ * Accepts either a media object (`result.audio`, `result.music`, …) or a bare
493
+ * URL string, which is what the combined video-to-sound endpoints return as
494
+ * `output_url`. */
495
+ declare function download(media: SfxMedia | string | undefined, fetchFn?: typeof globalThis.fetch, timeout?: number): Promise<Uint8Array>;
427
496
 
428
- declare const VERSION = "0.4.0";
497
+ /** The SDK's own version. Generated by scripts/sync-versions.mjs — do not edit. */
498
+ declare const VERSION = "0.5.1";
429
499
 
430
- export { APIError, type AccountServices, type AudioChunkEvent, AuthenticationError, BadRequestError, type BaseTaskResult, type CompleteEvent, type CostEvent, type CostInfo, DEFAULT_TIMEOUT_MS, type DailyUsage, 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 StreamEvent, TaskFailedError, TaskTimeoutError, type TextToMusicParams, type TextToSfxParams, type TitleEvent, type Track, type UnknownEvent, type UsageResponse, type UsageSummary, VERSION, type VideoInput, type VideoResult, type VideoToMusicParams, type VideoToSfxParams, type VideoToVideoMusicParams, type VideoToVideoSfxParams, type WaitOptions, download, isAudioChunkEvent, isErrorEvent };
500
+ export { APIError, type AccountServices, type AudioChunkEvent, AuthenticationError, BadRequestError, type BaseTaskResult, type CompleteEvent, type CostEvent, type CostInfo, DEFAULT_TIMEOUT_MS, type DailyUsage, 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 SoundResult, type StreamEvent, TaskFailedError, TaskTimeoutError, type TextToMusicParams, type TextToSfxParams, type TitleEvent, type Track, type UnknownEvent, type UsageResponse, type UsageSummary, VERSION, type VideoInput, type VideoResult, type VideoToMusicParams, type VideoToSfxParams, type VideoToSoundParams, type VideoToVideoMusicParams, type VideoToVideoSfxParams, type WaitOptions, download, isAudioChunkEvent, isErrorEvent };
package/dist/index.d.ts CHANGED
@@ -239,6 +239,41 @@ interface VideoToVideoSfxParams {
239
239
  prompt?: string;
240
240
  segments?: SfxSegment[];
241
241
  }
242
+ /** Params for `videoToSound` and `videoToVideoSound`. Both endpoints take the
243
+ * identical form, so they share one params type. */
244
+ interface VideoToSoundParams {
245
+ video?: VideoInput;
246
+ videoUrl?: string;
247
+ /** Style hint for the generated music bed. */
248
+ musicPrompt?: string;
249
+ /** Description of the sound effects layered over the music. */
250
+ sfxPrompt?: string;
251
+ /** Per-segment SFX descriptions; must start at 0 and be contiguous. */
252
+ segments?: SfxSegment[];
253
+ /** Keep the source speech in the result. */
254
+ preserveSpeech?: boolean;
255
+ /** Duck the generated music under the source speech. Default-ON
256
+ * server-side: leave unset to keep it on, pass `false` to opt out. */
257
+ ducking?: boolean;
258
+ }
259
+ /** Result of a `videoToSound` / `videoToVideoSound` task (`tasks.get`) or its
260
+ * final state (`generate`).
261
+ *
262
+ * The combined music+SFX result is `output_url` — a bare presigned URL rather
263
+ * than a media object, since these endpoints render one artifact whose kind is
264
+ * announced by `output_type` ("audio" for video-to-sound, "video" for
265
+ * video-to-video-sound). `music`, `music_processed` and `sfx` are the
266
+ * individual stems; pass any of them, or `output_url` itself, to `download()`. */
267
+ interface SoundResult extends BaseTaskResult {
268
+ output_url?: string;
269
+ output_type?: "audio" | "video";
270
+ output_bytes?: number;
271
+ music?: SfxMedia;
272
+ /** Present only when `preserveSpeech`/`ducking` altered the music bed. */
273
+ music_processed?: SfxMedia;
274
+ sfx?: SfxMedia;
275
+ duration_seconds?: number;
276
+ }
242
277
 
243
278
  declare class Account {
244
279
  private readonly client;
@@ -332,6 +367,24 @@ declare class VideoToVideoSfx {
332
367
  generate(params: VideoToVideoSfxParams, opts?: WaitOptions): Promise<VideoResult>;
333
368
  }
334
369
 
370
+ /** Generate a combined music + sound-effects track for a video and get back
371
+ * the mixed audio. Async only. */
372
+ declare class VideoToSound {
373
+ private readonly client;
374
+ constructor(client: SoniloClient);
375
+ submit(params: VideoToSoundParams): Promise<SfxTask>;
376
+ generate(params: VideoToSoundParams, opts?: WaitOptions): Promise<SoundResult>;
377
+ }
378
+
379
+ /** Generate a combined music + sound-effects track for a video and get back a
380
+ * re-hosted video with that track muxed in. Async only. */
381
+ declare class VideoToVideoSound {
382
+ private readonly client;
383
+ constructor(client: SoniloClient);
384
+ submit(params: VideoToSoundParams): Promise<SfxTask>;
385
+ generate(params: VideoToSoundParams, opts?: WaitOptions): Promise<SoundResult>;
386
+ }
387
+
335
388
  interface SoniloClientOptions {
336
389
  /** Defaults to the SONILO_API_KEY environment variable (Node.js only). */
337
390
  apiKey?: string;
@@ -341,6 +394,14 @@ interface SoniloClientOptions {
341
394
  fetch?: typeof globalThis.fetch;
342
395
  /** Milliseconds before an in-flight request is aborted. Default 600000. */
343
396
  timeout?: number;
397
+ /**
398
+ * Identifies a wrapper built on this SDK (the CLI, the video kit) in the
399
+ * `X-Sonilo-Client` header. Leave unset for direct SDK use — without an
400
+ * override a wrapper's traffic is indistinguishable from the SDK's own.
401
+ */
402
+ clientName?: string;
403
+ /** Version reported alongside `clientName`. Defaults to the SDK's version. */
404
+ clientVersion?: string;
344
405
  }
345
406
  /** Milliseconds before an in-flight request is aborted, unless overridden. */
346
407
  declare const DEFAULT_TIMEOUT_MS = 600000;
@@ -349,6 +410,8 @@ declare class SoniloClient {
349
410
  private readonly apiKey;
350
411
  private readonly fetchFn;
351
412
  private readonly timeout;
413
+ private readonly clientName;
414
+ private readonly clientVersion;
352
415
  readonly account: Account;
353
416
  readonly tasks: Tasks;
354
417
  readonly textToMusic: TextToMusic;
@@ -357,6 +420,8 @@ declare class SoniloClient {
357
420
  readonly videoToSfx: VideoToSfx;
358
421
  readonly videoToVideoMusic: VideoToVideoMusic;
359
422
  readonly videoToVideoSfx: VideoToVideoSfx;
423
+ readonly videoToSound: VideoToSound;
424
+ readonly videoToVideoSound: VideoToVideoSound;
360
425
  constructor(options?: SoniloClientOptions);
361
426
  /**
362
427
  * Perform an authenticated request; throws a typed error on non-2xx.
@@ -422,9 +487,14 @@ declare class TaskTimeoutError extends SoniloError {
422
487
  declare class RequestTimeoutError extends SoniloError {
423
488
  }
424
489
 
425
- /** Fetch a result media file. The URL is presigned — no API key is sent. */
426
- declare function download(media: SfxMedia | undefined, fetchFn?: typeof globalThis.fetch, timeout?: number): Promise<Uint8Array>;
490
+ /** Fetch a result media file. The URL is presigned — no API key is sent.
491
+ *
492
+ * Accepts either a media object (`result.audio`, `result.music`, …) or a bare
493
+ * URL string, which is what the combined video-to-sound endpoints return as
494
+ * `output_url`. */
495
+ declare function download(media: SfxMedia | string | undefined, fetchFn?: typeof globalThis.fetch, timeout?: number): Promise<Uint8Array>;
427
496
 
428
- declare const VERSION = "0.4.0";
497
+ /** The SDK's own version. Generated by scripts/sync-versions.mjs — do not edit. */
498
+ declare const VERSION = "0.5.1";
429
499
 
430
- export { APIError, type AccountServices, type AudioChunkEvent, AuthenticationError, BadRequestError, type BaseTaskResult, type CompleteEvent, type CostEvent, type CostInfo, DEFAULT_TIMEOUT_MS, type DailyUsage, 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 StreamEvent, TaskFailedError, TaskTimeoutError, type TextToMusicParams, type TextToSfxParams, type TitleEvent, type Track, type UnknownEvent, type UsageResponse, type UsageSummary, VERSION, type VideoInput, type VideoResult, type VideoToMusicParams, type VideoToSfxParams, type VideoToVideoMusicParams, type VideoToVideoSfxParams, type WaitOptions, download, isAudioChunkEvent, isErrorEvent };
500
+ export { APIError, type AccountServices, type AudioChunkEvent, AuthenticationError, BadRequestError, type BaseTaskResult, type CompleteEvent, type CostEvent, type CostInfo, DEFAULT_TIMEOUT_MS, type DailyUsage, 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 SoundResult, type StreamEvent, TaskFailedError, TaskTimeoutError, type TextToMusicParams, type TextToSfxParams, type TitleEvent, type Track, type UnknownEvent, type UsageResponse, type UsageSummary, VERSION, type VideoInput, type VideoResult, type VideoToMusicParams, type VideoToSfxParams, type VideoToSoundParams, type VideoToVideoMusicParams, type VideoToVideoSfxParams, type WaitOptions, download, isAudioChunkEvent, isErrorEvent };
package/dist/index.js CHANGED
@@ -564,11 +564,72 @@ var VideoToVideoSfx = class {
564
564
  }
565
565
  };
566
566
 
567
+ // src/resources/soundForm.ts
568
+ async function buildSoundForm(params) {
569
+ if (params.video === void 0 === (params.videoUrl === void 0)) {
570
+ throw new SoniloError("Provide exactly one of video or videoUrl");
571
+ }
572
+ const form = new FormData();
573
+ if (params.video !== void 0) {
574
+ const { blob, filename } = await toUploadBlob(params.video);
575
+ form.set("video", blob, filename);
576
+ } else {
577
+ form.set("video_url", params.videoUrl);
578
+ }
579
+ if (params.musicPrompt !== void 0) form.set("music_prompt", params.musicPrompt);
580
+ if (params.sfxPrompt !== void 0) form.set("sfx_prompt", params.sfxPrompt);
581
+ if (params.segments !== void 0) {
582
+ form.set("segments", JSON.stringify(params.segments));
583
+ }
584
+ if (params.preserveSpeech !== void 0) {
585
+ form.set("preserve_speech", String(params.preserveSpeech));
586
+ }
587
+ if (params.ducking !== void 0) form.set("ducking", String(params.ducking));
588
+ return form;
589
+ }
590
+
591
+ // src/resources/videoToSound.ts
592
+ var VideoToSound = class {
593
+ constructor(client) {
594
+ this.client = client;
595
+ }
596
+ async submit(params) {
597
+ const res = await this.client.request("/v1/video-to-sound", {
598
+ method: "POST",
599
+ body: await buildSoundForm(params)
600
+ });
601
+ return await res.json();
602
+ }
603
+ async generate(params, opts) {
604
+ const task = await this.submit(params);
605
+ return this.client.tasks.wait(task.task_id, opts);
606
+ }
607
+ };
608
+
609
+ // src/resources/videoToVideoSound.ts
610
+ var VideoToVideoSound = class {
611
+ constructor(client) {
612
+ this.client = client;
613
+ }
614
+ async submit(params) {
615
+ const res = await this.client.request("/v1/video-to-video-sound", {
616
+ method: "POST",
617
+ body: await buildSoundForm(params)
618
+ });
619
+ return await res.json();
620
+ }
621
+ async generate(params, opts) {
622
+ const task = await this.submit(params);
623
+ return this.client.tasks.wait(task.task_id, opts);
624
+ }
625
+ };
626
+
567
627
  // src/version.ts
568
- var VERSION = "0.4.0";
628
+ var VERSION = "0.5.1";
569
629
 
570
630
  // src/client.ts
571
631
  var DEFAULT_BASE_URL = "https://api.sonilo.com";
632
+ var DEFAULT_CLIENT_NAME = "sdk-js";
572
633
  var DEFAULT_TIMEOUT_MS = 6e5;
573
634
  var SoniloClient = class {
574
635
  constructor(options = {}) {
@@ -583,6 +644,8 @@ var SoniloClient = class {
583
644
  this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
584
645
  this.fetchFn = (options.fetch ?? globalThis.fetch).bind(globalThis);
585
646
  this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
647
+ this.clientName = options.clientName ?? DEFAULT_CLIENT_NAME;
648
+ this.clientVersion = options.clientVersion ?? VERSION;
586
649
  this.account = new Account(this);
587
650
  this.tasks = new Tasks(this);
588
651
  this.textToMusic = new TextToMusic(this);
@@ -591,6 +654,8 @@ var SoniloClient = class {
591
654
  this.videoToSfx = new VideoToSfx(this);
592
655
  this.videoToVideoMusic = new VideoToVideoMusic(this);
593
656
  this.videoToVideoSfx = new VideoToVideoSfx(this);
657
+ this.videoToSound = new VideoToSound(this);
658
+ this.videoToVideoSound = new VideoToVideoSound(this);
594
659
  }
595
660
  /**
596
661
  * Perform an authenticated request; throws a typed error on non-2xx.
@@ -603,8 +668,8 @@ var SoniloClient = class {
603
668
  async request(path, init = {}, opts = {}) {
604
669
  const headers = new Headers(init.headers);
605
670
  headers.set("Authorization", `Bearer ${this.apiKey}`);
606
- headers.set("X-Sonilo-Client", "sdk-js");
607
- headers.set("X-Sonilo-Client-Version", VERSION);
671
+ headers.set("X-Sonilo-Client", this.clientName);
672
+ headers.set("X-Sonilo-Client-Version", this.clientVersion);
608
673
  const timeout = opts.timeout === void 0 ? this.timeout : opts.timeout;
609
674
  const ownsSignal = init.signal == null && timeout !== null;
610
675
  const signal = init.signal ?? (timeout === null ? void 0 : AbortSignal.timeout(timeout));
@@ -623,15 +688,16 @@ var SoniloClient = class {
623
688
 
624
689
  // src/download.ts
625
690
  async function download(media, fetchFn = globalThis.fetch, timeout = DEFAULT_TIMEOUT_MS) {
626
- if (!media?.url) {
691
+ const url = typeof media === "string" ? media : media?.url;
692
+ if (!url) {
627
693
  throw new SoniloError("No media to download");
628
694
  }
629
695
  let res;
630
696
  try {
631
- res = await fetchFn(media.url, { signal: AbortSignal.timeout(timeout) });
697
+ res = await fetchFn(url, { signal: AbortSignal.timeout(timeout) });
632
698
  } catch (err) {
633
699
  if (isTimeoutSignalError(err)) {
634
- throw new RequestTimeoutError(`Download of ${media.url} timed out after ${timeout}ms`);
700
+ throw new RequestTimeoutError(`Download of ${url} timed out after ${timeout}ms`);
635
701
  }
636
702
  throw err;
637
703
  }