samsar-js 0.48.32 → 0.48.34
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/README.md +50 -9
- package/dist/index.d.ts +130 -2
- package/dist/index.js +99 -126
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,6 +37,10 @@ const video = await samsar.createVideoFromText(
|
|
|
37
37
|
image_model: 'GPTIMAGE2',
|
|
38
38
|
video_model: 'RUNWAYML',
|
|
39
39
|
duration: 30,
|
|
40
|
+
backingtrack_model: 'LYRIA3',
|
|
41
|
+
tts_model: 'OPENAI',
|
|
42
|
+
speakerOptions: { openAISpeakers: ['nova'] },
|
|
43
|
+
inference_model: 'gpt-5.5',
|
|
40
44
|
font_key: 'Poppins',
|
|
41
45
|
enable_subtitles: true,
|
|
42
46
|
},
|
|
@@ -67,6 +71,10 @@ const videoFromImages = await samsar.createVideoFromImageList(
|
|
|
67
71
|
video_model: 'RUNWAYML',
|
|
68
72
|
aspect_ratio: '16:9',
|
|
69
73
|
language: 'en',
|
|
74
|
+
backingtrack_model: 'ELEVENLABS_MUSIC',
|
|
75
|
+
tts_model: 'ELEVENLABS',
|
|
76
|
+
speakerOptions: { elevenLabsSpeakers: ['EXAVITQu4vr4xnSDxMaL'] },
|
|
77
|
+
inference_model: 'gemini-3.1-pro',
|
|
70
78
|
font_key: 'Poppins',
|
|
71
79
|
enable_subtitles: true,
|
|
72
80
|
},
|
|
@@ -107,6 +115,20 @@ await samsar.createVideoFromImageList({
|
|
|
107
115
|
],
|
|
108
116
|
});
|
|
109
117
|
|
|
118
|
+
// Create a video and generate the outro with a center logo/CTA image instead of a QR code
|
|
119
|
+
await samsar.createVideoFromImageList({
|
|
120
|
+
image_urls: ['https://example.com/a.jpg', 'https://example.com/b.jpg'],
|
|
121
|
+
prompt: 'Product launch teaser with a branded CTA outro',
|
|
122
|
+
video_model: 'RUNWAYML',
|
|
123
|
+
aspect_ratio: '9:16',
|
|
124
|
+
generate_outro_image: true,
|
|
125
|
+
outro_cta_image: {
|
|
126
|
+
top_text: 'Shop the drop',
|
|
127
|
+
middle_image: { url: 'https://cdn.example.com/drop-logo.png' },
|
|
128
|
+
bottom_text: 'Limited availability',
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
110
132
|
// Create the same generated QR outro and per-scene footer CTAs from one CTA link
|
|
111
133
|
await samsar.createVideoFromImageList({
|
|
112
134
|
image_urls: [
|
|
@@ -146,6 +168,20 @@ await samsar.updateVideoOutroImage(
|
|
|
146
168
|
{ webhookUrl: 'https://example.com/webhook' },
|
|
147
169
|
);
|
|
148
170
|
|
|
171
|
+
// Update an existing outro by generating a new CTA outro with a center logo/CTA image
|
|
172
|
+
await samsar.updateVideoOutroImage(
|
|
173
|
+
{
|
|
174
|
+
videoSessionId: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
|
|
175
|
+
generate_outro_image: true,
|
|
176
|
+
outro_cta_image: {
|
|
177
|
+
top_text: 'Shop the drop',
|
|
178
|
+
middle_image: { url: 'https://cdn.example.com/drop-logo.png' },
|
|
179
|
+
bottom_text: 'Limited availability',
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
{ webhookUrl: 'https://example.com/webhook' },
|
|
183
|
+
);
|
|
184
|
+
|
|
149
185
|
// Update the footer CTA on an existing video session
|
|
150
186
|
await samsar.updateVideoFooterImage(
|
|
151
187
|
{
|
|
@@ -489,13 +525,15 @@ const externalRender = await platform.createExternalVideoFromText(externalUser,
|
|
|
489
525
|
enable_subtitles: true,
|
|
490
526
|
});
|
|
491
527
|
|
|
492
|
-
// Update an external user's existing outro by generating a
|
|
528
|
+
// Update an external user's existing outro by generating a center logo/CTA image outro
|
|
493
529
|
const externalOutroUpdate = await platform.updateExternalVideoOutroImage(externalUser, {
|
|
494
530
|
request_id: externalRender.data.request_id,
|
|
495
531
|
generate_outro_image: true,
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
532
|
+
outro_cta_image: {
|
|
533
|
+
top_text: 'Shop the drop',
|
|
534
|
+
middle_image: { url: 'https://cdn.example.com/drop-logo.png' },
|
|
535
|
+
bottom_text: 'Limited availability',
|
|
536
|
+
},
|
|
499
537
|
add_outro_animation: true,
|
|
500
538
|
});
|
|
501
539
|
console.log(externalOutroUpdate.data.request_id);
|
|
@@ -574,14 +612,17 @@ console.log(externalLibrary.data.requests.map((request) => request.request_id));
|
|
|
574
612
|
|
|
575
613
|
Video model support notes:
|
|
576
614
|
- `createVideoFromText` image model keys include: `GPTIMAGE2`, `IMAGEN4`, `SEEDREAM`, `NANOBANANA2`, `NANOBANANAPRO`, `CUSTOM_TEXT_TO_IMAGE`.
|
|
577
|
-
- `createVideoFromText` supports these video models: `RUNWAYML`, `VEO3.1I2V`, `VEO3.1I2VFAST`, `SEEDANCEI2V` (Seedance 1.5), `KLINGIMGTOVID3PRO`, and `HAPPYHORSEI2V`.
|
|
578
|
-
- `createVideoFromText` accepts either a provided outro (`outro_image_url`) or server-generated
|
|
579
|
-
- `createVideoFromImageList` supports `RUNWAYML`, `VEO3.1I2V`, `VEO3.1I2VFAST`, `SEEDANCEI2V`, `KLINGIMGTOVID3PRO`, and `HAPPYHORSEI2V` via `video_model`; if omitted, it defaults to `RUNWAYML`. It also accepts the same `image_model` keys as text-to-video. Use `aspect_ratio: '16:9'` or `'9:16'`; omitted or invalid values fall back to `16:9`.
|
|
580
|
-
- `
|
|
615
|
+
- `createVideoFromText` supports these video models: `RUNWAYML`, `VEO3.1I2V`, `VEO3.1I2VFAST`, `COSMOS3SUPERI2V`, `SEEDANCEI2V` (Seedance 1.5), `KLINGIMGTOVID3PRO`, and `HAPPYHORSEI2V`.
|
|
616
|
+
- `createVideoFromText` accepts either a provided outro (`outro_image_url`) or a server-generated CTA outro (`generate_outro_image: true` with `cta_url` for a QR center image, or `outro_cta_image` for a supplied center logo/CTA image). It can also render bottom CTA footer QR cards with `add_footer_animation` and `footer_metadata`; one footer item applies to every generated scene, while multiple items map by scene index.
|
|
617
|
+
- `createVideoFromImageList` supports `RUNWAYML`, `VEO3.1I2V`, `VEO3.1I2VFAST`, `COSMOS3SUPERI2V`, `SEEDANCEI2V`, `KLINGIMGTOVID3PRO`, and `HAPPYHORSEI2V` via `video_model`; if omitted, it defaults to `RUNWAYML`. It also accepts the same `image_model` keys as text-to-video. Use `aspect_ratio: '16:9'` or `'9:16'`; omitted or invalid values fall back to `16:9`.
|
|
618
|
+
- Text and image-list video creation both accept optional `backingtrack_model` / `backing_track_model` / `backingTrackModel` / `music_provider` / `musicProvider`, `tts_model` / `ttsModel` / `tts_provider` / `ttsProvider`, `speakerOptions` / `speaker_options`, and `inference_model` / `inferenceModel`. The adapter normalizes these to `backingtrack_model`, `tts_model`, `speakerOptions`, and `inference_model` in the request payload. Omit `inference_model` to use the account default; supported request values are `gpt-5.5` and `gemini-3.1-pro`. When `tts_model` is set, Samsar limits assignment to the matching speaker list (`openAISpeakers`, `elevenLabsSpeakers`, or `googleSpeakers`; Google TTS requests should include `googleSpeakerDetails`).
|
|
619
|
+
- `video_model_sub_type` is no longer used by the API and is stripped from text and image-list payloads before sending.
|
|
620
|
+
- `createVideoFromImageList` accepts either a provided outro (`outro_image_url`) or a server-generated CTA outro (`generate_outro_image: true` with `cta_url` for a QR center image, or `outro_cta_image` for a supplied center logo/CTA image). Do not combine the two modes in a single request.
|
|
621
|
+
- `outro_cta_image` uses the structured shape `{ top_text, middle_image, bottom_text }`. `middle_image` accepts a public image URL (`{ url }`, `{ image_url }`) or image data (`{ data_url }`, `{ image_data, mime_type }`) and is resized into the same center area used by QR outros without changing aspect ratio.
|
|
581
622
|
- `createVideoFromImageList` can render per-scene footer QR cards by setting `add_footer_animation: true` and providing one `footer_metadata` item per image scene.
|
|
582
623
|
- `createVideoFromImageList` can also generate QR outro CTA text and each scene footer CTA from a single link by setting `express_cta_generation: true` with `cta_url`. CamelCase `expressCtaGeneration` and compatibility aliases `auto_generate_cta_text` / `generate_cta_texts` are normalized to the same API field.
|
|
583
624
|
- `createVideoFromImageList` accepts `limit_single_narrator: true` to keep all narration under one narrator identity. `add_narrator_avatar: true` automatically enables `limit_single_narrator`, generates an influencer-style human narrator avatar, and overlays it bottom-center or centered in the footer row when footer metadata is present.
|
|
584
|
-
- `updateVideoOutroImage` accepts either a replacement outro image URL (`outro_image_url`, `outroImageUrl`, `new_outro_image_url`) or a generated
|
|
625
|
+
- `updateVideoOutroImage` accepts either a replacement outro image URL (`outro_image_url`, `outroImageUrl`, `new_outro_image_url`) or a generated CTA outro (`generate_outro_image: true` with `cta_url` or `outro_cta_image`, or just `cta_url` / `outro_cta_image` when no outro image URL is supplied). Generated outro updates reuse the existing session image layers for tiling and only queue frame/video regeneration.
|
|
585
626
|
- `updateVideoFooterImage` updates the footer CTA on a cloned session with `cta_text`, `cta_logo`, and/or `cta_url`, or removes all scene footers with `remove_footer: true`. Footer updates queue only frame/video regeneration.
|
|
586
627
|
- `cloneVideo` creates a deep copy of a completed session and queues only the final video render so the clone receives a new rendered video path and URL. It does not charge credits.
|
|
587
628
|
- Main video methods and external-user methods accept the same generated outro and footer parameters. The API can resolve either internal session ids or external `extreq_...` ids on repeated video routes, so client code can keep using `translateVideo`, `joinVideos`, `addSubtitles`, `removeSubtitles`, `addVideoOutroImage`, `updateVideoOutroImage`, and `updateVideoFooterImage`; the explicit external variants are available when you want to call `/external_users/*` directly. Do not strip the `extreq_` prefix.
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,83 @@ export interface FontOptions {
|
|
|
36
36
|
language?: string;
|
|
37
37
|
family?: string;
|
|
38
38
|
}
|
|
39
|
+
export type BackingTrackModel = 'LYRIA3' | 'LYRIA2' | 'ELEVENLABS_MUSIC' | 'Lyria 3' | 'Lyria 2' | 'ElevenLabs music' | string;
|
|
40
|
+
export type TTSModel = 'ELEVENLABS' | 'OPENAI' | 'GOOGLE' | 'ElevenLabs' | 'OpenAI' | 'Google TTS' | string;
|
|
41
|
+
export type InferenceModel = 'gpt-5.5' | 'GPT 5.5' | 'gemini-3.1-pro' | 'Gemini 3.1 Pro' | string;
|
|
42
|
+
export interface GoogleTTSSpeakerDetail {
|
|
43
|
+
provider?: 'GOOGLE' | string;
|
|
44
|
+
value?: string;
|
|
45
|
+
voiceId?: string;
|
|
46
|
+
name?: string;
|
|
47
|
+
label?: string;
|
|
48
|
+
languageCode?: string;
|
|
49
|
+
languageCodes?: string[];
|
|
50
|
+
Gender?: 'M' | 'F' | '' | string | null;
|
|
51
|
+
gender?: string;
|
|
52
|
+
genderCode?: string;
|
|
53
|
+
ssmlGender?: string;
|
|
54
|
+
naturalSampleRateHertz?: number | null;
|
|
55
|
+
voiceType?: string;
|
|
56
|
+
previewRequiresAuth?: boolean;
|
|
57
|
+
[key: string]: unknown;
|
|
58
|
+
}
|
|
59
|
+
export interface TTSSpeakerOptions {
|
|
60
|
+
allowOpenAI?: boolean;
|
|
61
|
+
allowElevenLabs?: boolean;
|
|
62
|
+
allowGoogle?: boolean;
|
|
63
|
+
openAISpeakers?: string[];
|
|
64
|
+
elevenLabsSpeakers?: string[];
|
|
65
|
+
googleSpeakers?: string[];
|
|
66
|
+
googleSpeakerDetails?: GoogleTTSSpeakerDetail[];
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
}
|
|
69
|
+
export type OutroCtaImageSource = string | {
|
|
70
|
+
url?: string;
|
|
71
|
+
image_url?: string;
|
|
72
|
+
imageUrl?: string;
|
|
73
|
+
public_url?: string;
|
|
74
|
+
publicUrl?: string;
|
|
75
|
+
source_url?: string;
|
|
76
|
+
sourceUrl?: string;
|
|
77
|
+
source?: string;
|
|
78
|
+
src?: string;
|
|
79
|
+
image?: string;
|
|
80
|
+
data_url?: string;
|
|
81
|
+
dataUrl?: string;
|
|
82
|
+
image_data?: string;
|
|
83
|
+
imageData?: string;
|
|
84
|
+
data?: string;
|
|
85
|
+
mime_type?: string;
|
|
86
|
+
mimeType?: string;
|
|
87
|
+
content_type?: string;
|
|
88
|
+
contentType?: string;
|
|
89
|
+
[key: string]: unknown;
|
|
90
|
+
};
|
|
91
|
+
export interface OutroCtaImagePayload {
|
|
92
|
+
top_text?: string;
|
|
93
|
+
topText?: string;
|
|
94
|
+
cta_text_top?: string;
|
|
95
|
+
ctaTextTop?: string;
|
|
96
|
+
middle_image?: OutroCtaImageSource;
|
|
97
|
+
middleImage?: OutroCtaImageSource;
|
|
98
|
+
center_image?: OutroCtaImageSource;
|
|
99
|
+
centerImage?: OutroCtaImageSource;
|
|
100
|
+
middle?: OutroCtaImageSource;
|
|
101
|
+
center?: OutroCtaImageSource;
|
|
102
|
+
bottom_text?: string;
|
|
103
|
+
bottomText?: string;
|
|
104
|
+
cta_text_bottom?: string;
|
|
105
|
+
ctaTextBottom?: string;
|
|
106
|
+
url?: string;
|
|
107
|
+
image_url?: string;
|
|
108
|
+
imageUrl?: string;
|
|
109
|
+
src?: string;
|
|
110
|
+
data_url?: string;
|
|
111
|
+
dataUrl?: string;
|
|
112
|
+
image_data?: string;
|
|
113
|
+
imageData?: string;
|
|
114
|
+
[key: string]: unknown;
|
|
115
|
+
}
|
|
39
116
|
export type V2StepGenerationMode = 'one_step' | 'two_step';
|
|
40
117
|
export interface V2StepGenerationOptions {
|
|
41
118
|
auto_render_full_video?: boolean;
|
|
@@ -50,7 +127,19 @@ export interface CreateVideoFromTextInput extends V2StepGenerationOptions {
|
|
|
50
127
|
duration: number;
|
|
51
128
|
tone?: string;
|
|
52
129
|
aspect_ratio?: string;
|
|
53
|
-
|
|
130
|
+
backingtrack_model?: BackingTrackModel;
|
|
131
|
+
backing_track_model?: BackingTrackModel;
|
|
132
|
+
backingTrackModel?: BackingTrackModel;
|
|
133
|
+
music_provider?: BackingTrackModel;
|
|
134
|
+
musicProvider?: BackingTrackModel;
|
|
135
|
+
tts_model?: TTSModel;
|
|
136
|
+
ttsModel?: TTSModel;
|
|
137
|
+
tts_provider?: TTSModel;
|
|
138
|
+
ttsProvider?: TTSModel;
|
|
139
|
+
inference_model?: InferenceModel;
|
|
140
|
+
inferenceModel?: InferenceModel;
|
|
141
|
+
speakerOptions?: TTSSpeakerOptions;
|
|
142
|
+
speaker_options?: TTSSpeakerOptions;
|
|
54
143
|
font_key?: string;
|
|
55
144
|
fontKey?: string;
|
|
56
145
|
subtitle_font?: string;
|
|
@@ -85,6 +174,10 @@ export interface CreateVideoFromTextInput extends V2StepGenerationOptions {
|
|
|
85
174
|
ctaTextBottom?: string;
|
|
86
175
|
cta_logo?: string;
|
|
87
176
|
ctaLogo?: string;
|
|
177
|
+
outro_cta_image?: OutroCtaImagePayload | string;
|
|
178
|
+
outroCtaImage?: OutroCtaImagePayload | string;
|
|
179
|
+
cta_image?: OutroCtaImagePayload | string;
|
|
180
|
+
ctaImage?: OutroCtaImagePayload | string;
|
|
88
181
|
add_footer_animation?: boolean;
|
|
89
182
|
addFooterAnimation?: boolean;
|
|
90
183
|
footer_metadata?: FooterMetadataItem[];
|
|
@@ -118,7 +211,7 @@ export interface FooterMetadataItem {
|
|
|
118
211
|
footerLogoImagePath?: string;
|
|
119
212
|
}
|
|
120
213
|
export type ImageListToVideoAspectRatio = '16:9' | '9:16';
|
|
121
|
-
export type ImageListToVideoModel = 'RUNWAYML' | 'VEO3.1I2V' | 'VEO3.1I2VFAST' | 'SEEDANCEI2V' | 'KLINGIMGTOVID3PRO' | 'HAPPYHORSEI2V';
|
|
214
|
+
export type ImageListToVideoModel = 'RUNWAYML' | 'VEO3.1I2V' | 'VEO3.1I2VFAST' | 'COSMOS3SUPERI2V' | 'SEEDANCEI2V' | 'KLINGIMGTOVID3PRO' | 'HAPPYHORSEI2V';
|
|
122
215
|
export interface ImageListToVideoItem {
|
|
123
216
|
image_url?: string;
|
|
124
217
|
imageUrl?: string;
|
|
@@ -155,6 +248,19 @@ export interface CreateVideoFromImageListInput extends V2StepGenerationOptions {
|
|
|
155
248
|
aspectRatio?: ImageListToVideoAspectRatio;
|
|
156
249
|
language?: string;
|
|
157
250
|
languageString?: string | null;
|
|
251
|
+
backingtrack_model?: BackingTrackModel;
|
|
252
|
+
backing_track_model?: BackingTrackModel;
|
|
253
|
+
backingTrackModel?: BackingTrackModel;
|
|
254
|
+
music_provider?: BackingTrackModel;
|
|
255
|
+
musicProvider?: BackingTrackModel;
|
|
256
|
+
tts_model?: TTSModel;
|
|
257
|
+
ttsModel?: TTSModel;
|
|
258
|
+
tts_provider?: TTSModel;
|
|
259
|
+
ttsProvider?: TTSModel;
|
|
260
|
+
inference_model?: InferenceModel;
|
|
261
|
+
inferenceModel?: InferenceModel;
|
|
262
|
+
speakerOptions?: TTSSpeakerOptions;
|
|
263
|
+
speaker_options?: TTSSpeakerOptions;
|
|
158
264
|
font_key?: string;
|
|
159
265
|
fontKey?: string;
|
|
160
266
|
subtitle_font?: string;
|
|
@@ -193,6 +299,10 @@ export interface CreateVideoFromImageListInput extends V2StepGenerationOptions {
|
|
|
193
299
|
ctaTextBottom?: string;
|
|
194
300
|
cta_logo?: string;
|
|
195
301
|
ctaLogo?: string;
|
|
302
|
+
outro_cta_image?: OutroCtaImagePayload | string;
|
|
303
|
+
outroCtaImage?: OutroCtaImagePayload | string;
|
|
304
|
+
cta_image?: OutroCtaImagePayload | string;
|
|
305
|
+
ctaImage?: OutroCtaImagePayload | string;
|
|
196
306
|
add_footer_animation?: boolean;
|
|
197
307
|
addFooterAnimation?: boolean;
|
|
198
308
|
footer_metadata?: FooterMetadataItem[];
|
|
@@ -319,6 +429,10 @@ export interface UpdateVideoOutroImageInput {
|
|
|
319
429
|
ctaTextBottom?: string;
|
|
320
430
|
cta_logo?: string;
|
|
321
431
|
ctaLogo?: string;
|
|
432
|
+
outro_cta_image?: OutroCtaImagePayload | string;
|
|
433
|
+
outroCtaImage?: OutroCtaImagePayload | string;
|
|
434
|
+
cta_image?: OutroCtaImagePayload | string;
|
|
435
|
+
ctaImage?: OutroCtaImagePayload | string;
|
|
322
436
|
[key: string]: unknown;
|
|
323
437
|
}
|
|
324
438
|
export interface UpdateVideoOutroImageResponse {
|
|
@@ -389,6 +503,20 @@ export interface AddVideoOutroImageInput {
|
|
|
389
503
|
outro_focus_area?: OutroFocusArea | null;
|
|
390
504
|
outroFocustArea?: OutroFocusArea | null;
|
|
391
505
|
outroFocusArea?: OutroFocusArea | null;
|
|
506
|
+
generate_outro_image?: boolean;
|
|
507
|
+
generateOutroImage?: boolean;
|
|
508
|
+
cta_url?: string;
|
|
509
|
+
ctaUrl?: string;
|
|
510
|
+
cta_text_top?: string;
|
|
511
|
+
ctaTextTop?: string;
|
|
512
|
+
cta_text_bottom?: string;
|
|
513
|
+
ctaTextBottom?: string;
|
|
514
|
+
cta_logo?: string;
|
|
515
|
+
ctaLogo?: string;
|
|
516
|
+
outro_cta_image?: OutroCtaImagePayload | string;
|
|
517
|
+
outroCtaImage?: OutroCtaImagePayload | string;
|
|
518
|
+
cta_image?: OutroCtaImagePayload | string;
|
|
519
|
+
ctaImage?: OutroCtaImagePayload | string;
|
|
392
520
|
[key: string]: unknown;
|
|
393
521
|
}
|
|
394
522
|
export interface AddVideoOutroImageResponse {
|
package/dist/index.js
CHANGED
|
@@ -41,6 +41,58 @@ function assertOptionalBoolean(value, fieldName, context = 'createVideoFromImage
|
|
|
41
41
|
throw new Error(`${fieldName} must be a boolean for ${context}`);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
function hasOutroCtaImageSource(value) {
|
|
45
|
+
if (typeof value === 'string') {
|
|
46
|
+
return Boolean(value.trim());
|
|
47
|
+
}
|
|
48
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const record = value;
|
|
52
|
+
const middleImage = getFirstDefinedInputValue(record, [
|
|
53
|
+
'middle_image',
|
|
54
|
+
'middleImage',
|
|
55
|
+
'center_image',
|
|
56
|
+
'centerImage',
|
|
57
|
+
'middle',
|
|
58
|
+
'center',
|
|
59
|
+
]);
|
|
60
|
+
if (middleImage !== undefined) {
|
|
61
|
+
return hasOutroCtaImageSource(middleImage);
|
|
62
|
+
}
|
|
63
|
+
return Boolean(getTrimmedString(record.url) ??
|
|
64
|
+
getTrimmedString(record.image_url) ??
|
|
65
|
+
getTrimmedString(record.imageUrl) ??
|
|
66
|
+
getTrimmedString(record.public_url) ??
|
|
67
|
+
getTrimmedString(record.publicUrl) ??
|
|
68
|
+
getTrimmedString(record.source_url) ??
|
|
69
|
+
getTrimmedString(record.sourceUrl) ??
|
|
70
|
+
getTrimmedString(record.source) ??
|
|
71
|
+
getTrimmedString(record.src) ??
|
|
72
|
+
getTrimmedString(record.image) ??
|
|
73
|
+
getTrimmedString(record.middle_image_url) ??
|
|
74
|
+
getTrimmedString(record.middleImageUrl) ??
|
|
75
|
+
getTrimmedString(record.center_image_url) ??
|
|
76
|
+
getTrimmedString(record.centerImageUrl) ??
|
|
77
|
+
getTrimmedString(record.data_url) ??
|
|
78
|
+
getTrimmedString(record.dataUrl) ??
|
|
79
|
+
getTrimmedString(record.image_data) ??
|
|
80
|
+
getTrimmedString(record.imageData) ??
|
|
81
|
+
getTrimmedString(record.data));
|
|
82
|
+
}
|
|
83
|
+
function normalizeOutroCtaImageInput(raw, context) {
|
|
84
|
+
const value = resolveAliasedInputValue(raw, ['outro_cta_image', 'outroCtaImage', 'cta_image', 'ctaImage'], 'outro_cta_image');
|
|
85
|
+
if (value === undefined || value === null) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
if (typeof value !== 'string' && (typeof value !== 'object' || Array.isArray(value))) {
|
|
89
|
+
throw new Error(`outro_cta_image must be a string or object for ${context}`);
|
|
90
|
+
}
|
|
91
|
+
if (!hasOutroCtaImageSource(value)) {
|
|
92
|
+
throw new Error(`outro_cta_image.middle_image is required for ${context}`);
|
|
93
|
+
}
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
44
96
|
function getFirstDefinedInputValue(raw, aliases) {
|
|
45
97
|
for (const alias of aliases) {
|
|
46
98
|
if (Object.prototype.hasOwnProperty.call(raw, alias)) {
|
|
@@ -135,8 +187,13 @@ function normalizeCreateVideoFromTextInput(input) {
|
|
|
135
187
|
['cta_text_top', ['cta_text_top', 'ctaTextTop']],
|
|
136
188
|
['cta_text_bottom', ['cta_text_bottom', 'ctaTextBottom']],
|
|
137
189
|
['cta_logo', ['cta_logo', 'ctaLogo']],
|
|
190
|
+
['outro_cta_image', ['outro_cta_image', 'outroCtaImage', 'cta_image', 'ctaImage']],
|
|
138
191
|
['add_footer_animation', ['add_footer_animation', 'addFooterAnimation']],
|
|
139
192
|
['footer_metadata', ['footer_metadata', 'footerMetadata']],
|
|
193
|
+
['backingtrack_model', ['backingtrack_model', 'backing_track_model', 'backingTrackModel', 'music_provider', 'musicProvider']],
|
|
194
|
+
['tts_model', ['tts_model', 'ttsModel', 'tts_provider', 'ttsProvider']],
|
|
195
|
+
['inference_model', ['inference_model', 'inferenceModel']],
|
|
196
|
+
['speakerOptions', ['speakerOptions', 'speaker_options']],
|
|
140
197
|
['enable_subtitles', ['enable_subtitles', 'enableSubtitles']],
|
|
141
198
|
['font_key', ['font_key', 'fontKey']],
|
|
142
199
|
];
|
|
@@ -146,6 +203,8 @@ function normalizeCreateVideoFromTextInput(input) {
|
|
|
146
203
|
normalized[canonicalName] = value;
|
|
147
204
|
}
|
|
148
205
|
}
|
|
206
|
+
delete normalized.video_model_sub_type;
|
|
207
|
+
delete normalized.videoModelSubType;
|
|
149
208
|
assertOptionalBoolean(normalized.enable_subtitles, 'enable_subtitles', 'createVideoFromText');
|
|
150
209
|
assertOptionalBoolean(normalized.add_outro_animation, 'add_outro_animation', 'createVideoFromText');
|
|
151
210
|
assertOptionalBoolean(normalized.add_outro_focus_area, 'add_outro_focus_area', 'createVideoFromText');
|
|
@@ -153,11 +212,21 @@ function normalizeCreateVideoFromTextInput(input) {
|
|
|
153
212
|
assertOptionalBoolean(normalized.add_footer_animation, 'add_footer_animation', 'createVideoFromText');
|
|
154
213
|
if (normalized.generate_outro_image === true) {
|
|
155
214
|
const ctaUrl = typeof normalized.cta_url === 'string' ? normalized.cta_url.trim() : '';
|
|
156
|
-
|
|
157
|
-
|
|
215
|
+
const outroCtaImage = normalizeOutroCtaImageInput(normalized, 'createVideoFromText');
|
|
216
|
+
if (outroCtaImage !== undefined) {
|
|
217
|
+
normalized.outro_cta_image = outroCtaImage;
|
|
218
|
+
}
|
|
219
|
+
if (!ctaUrl && !outroCtaImage) {
|
|
220
|
+
throw new Error('cta_url or outro_cta_image is required when generate_outro_image is true for createVideoFromText');
|
|
158
221
|
}
|
|
159
222
|
}
|
|
160
|
-
else
|
|
223
|
+
else {
|
|
224
|
+
const outroCtaImage = normalizeOutroCtaImageInput(normalized, 'createVideoFromText');
|
|
225
|
+
if (outroCtaImage !== undefined) {
|
|
226
|
+
normalized.outro_cta_image = outroCtaImage;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (normalized.generate_outro_image !== true && normalized.add_outro_focus_area === true && normalized.add_outro_animation !== true) {
|
|
161
230
|
throw new Error('add_outro_focus_area requires add_outro_animation to be true for createVideoFromText');
|
|
162
231
|
}
|
|
163
232
|
return normalized;
|
|
@@ -191,8 +260,13 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
191
260
|
['cta_text_top', ['cta_text_top', 'ctaTextTop']],
|
|
192
261
|
['cta_text_bottom', ['cta_text_bottom', 'ctaTextBottom']],
|
|
193
262
|
['cta_logo', ['cta_logo', 'ctaLogo']],
|
|
263
|
+
['outro_cta_image', ['outro_cta_image', 'outroCtaImage', 'cta_image', 'ctaImage']],
|
|
194
264
|
['add_footer_animation', ['add_footer_animation', 'addFooterAnimation']],
|
|
195
265
|
['footer_metadata', ['footer_metadata', 'footerMetadata']],
|
|
266
|
+
['backingtrack_model', ['backingtrack_model', 'backing_track_model', 'backingTrackModel', 'music_provider', 'musicProvider']],
|
|
267
|
+
['tts_model', ['tts_model', 'ttsModel', 'tts_provider', 'ttsProvider']],
|
|
268
|
+
['inference_model', ['inference_model', 'inferenceModel']],
|
|
269
|
+
['speakerOptions', ['speakerOptions', 'speaker_options']],
|
|
196
270
|
['limit_single_narrator', ['limit_single_narrator', 'limitSingleNarrator']],
|
|
197
271
|
['add_narrator_avatar', ['add_narrator_avatar', 'addNarratorAvatar']],
|
|
198
272
|
['enable_subtitles', ['enable_subtitles', 'enableSubtitles']],
|
|
@@ -204,6 +278,8 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
204
278
|
normalized[canonicalName] = value;
|
|
205
279
|
}
|
|
206
280
|
}
|
|
281
|
+
delete normalized.video_model_sub_type;
|
|
282
|
+
delete normalized.videoModelSubType;
|
|
207
283
|
assertOptionalBoolean(normalized.enable_subtitles, 'enable_subtitles');
|
|
208
284
|
assertOptionalBoolean(normalized.add_outro_animation, 'add_outro_animation');
|
|
209
285
|
assertOptionalBoolean(normalized.add_outro_focus_area, 'add_outro_focus_area');
|
|
@@ -212,6 +288,10 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
212
288
|
assertOptionalBoolean(normalized.add_footer_animation, 'add_footer_animation');
|
|
213
289
|
assertOptionalBoolean(normalized.limit_single_narrator, 'limit_single_narrator');
|
|
214
290
|
assertOptionalBoolean(normalized.add_narrator_avatar, 'add_narrator_avatar');
|
|
291
|
+
const outroCtaImage = normalizeOutroCtaImageInput(normalized, 'createVideoFromImageList');
|
|
292
|
+
if (outroCtaImage !== undefined) {
|
|
293
|
+
normalized.outro_cta_image = outroCtaImage;
|
|
294
|
+
}
|
|
215
295
|
if (normalized.add_narrator_avatar === true) {
|
|
216
296
|
normalized.limit_single_narrator = true;
|
|
217
297
|
}
|
|
@@ -228,8 +308,8 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
228
308
|
}
|
|
229
309
|
if (normalized.generate_outro_image === true) {
|
|
230
310
|
const ctaUrl = typeof normalized.cta_url === 'string' ? normalized.cta_url.trim() : '';
|
|
231
|
-
if (!ctaUrl) {
|
|
232
|
-
throw new Error('cta_url is required when generate_outro_image is true for createVideoFromImageList');
|
|
311
|
+
if (!ctaUrl && !outroCtaImage) {
|
|
312
|
+
throw new Error('cta_url or outro_cta_image is required when generate_outro_image is true for createVideoFromImageList');
|
|
233
313
|
}
|
|
234
314
|
}
|
|
235
315
|
else if (normalized.add_outro_focus_area === true && normalized.add_outro_animation !== true) {
|
|
@@ -358,8 +438,9 @@ function normalizeUpdateVideoOutroImageInput(input, context = 'updateVideoOutroI
|
|
|
358
438
|
raw.ctaTextBottom;
|
|
359
439
|
const ctaLogo = raw.cta_logo ??
|
|
360
440
|
raw.ctaLogo;
|
|
441
|
+
const outroCtaImage = normalizeOutroCtaImageInput(raw, context);
|
|
361
442
|
const generateOutroImage = rawGenerateOutroImage === true ||
|
|
362
|
-
(rawGenerateOutroImage === undefined && !outroImageUrl && Boolean(ctaUrl));
|
|
443
|
+
(rawGenerateOutroImage === undefined && !outroImageUrl && (Boolean(ctaUrl) || Boolean(outroCtaImage)));
|
|
363
444
|
if (!videoSessionId) {
|
|
364
445
|
throw new Error(`videoSessionId is required for ${context}`);
|
|
365
446
|
}
|
|
@@ -372,15 +453,15 @@ function normalizeUpdateVideoOutroImageInput(input, context = 'updateVideoOutroI
|
|
|
372
453
|
if (rawAddOutroFocusArea !== undefined && typeof rawAddOutroFocusArea !== 'boolean') {
|
|
373
454
|
throw new Error(`add_outro_focus_area must be a boolean for ${context}`);
|
|
374
455
|
}
|
|
375
|
-
if (generateOutroImage && outroImageUrl) {
|
|
376
|
-
throw new Error(`Use either generate_outro_image with cta_url or outro_image_url for ${context}`);
|
|
456
|
+
if ((generateOutroImage || outroCtaImage) && outroImageUrl) {
|
|
457
|
+
throw new Error(`Use either generate_outro_image with cta_url/outro_cta_image or outro_image_url for ${context}`);
|
|
377
458
|
}
|
|
378
459
|
if (!generateOutroImage && !outroImageUrl) {
|
|
379
460
|
throw new Error(`outro_image_url is required for ${context} unless generate_outro_image is true`);
|
|
380
461
|
}
|
|
381
462
|
if (generateOutroImage) {
|
|
382
|
-
if (!ctaUrl || !String(ctaUrl).trim()) {
|
|
383
|
-
throw new Error(`cta_url is required when generate_outro_image is true for ${context}`);
|
|
463
|
+
if ((!ctaUrl || !String(ctaUrl).trim()) && !outroCtaImage) {
|
|
464
|
+
throw new Error(`cta_url or outro_cta_image is required when generate_outro_image is true for ${context}`);
|
|
384
465
|
}
|
|
385
466
|
}
|
|
386
467
|
else if (rawAddOutroFocusArea === true && rawAddOutroAnimation !== true) {
|
|
@@ -401,7 +482,8 @@ function normalizeUpdateVideoOutroImageInput(input, context = 'updateVideoOutroI
|
|
|
401
482
|
videoSessionId: String(videoSessionId),
|
|
402
483
|
...(outroImageUrl ? { outro_image_url: String(outroImageUrl) } : {}),
|
|
403
484
|
generate_outro_image: generateOutroImage,
|
|
404
|
-
...(generateOutroImage ? { cta_url: String(ctaUrl).trim() } : {}),
|
|
485
|
+
...(generateOutroImage && ctaUrl ? { cta_url: String(ctaUrl).trim() } : {}),
|
|
486
|
+
...(generateOutroImage && outroCtaImage ? { outro_cta_image: outroCtaImage } : {}),
|
|
405
487
|
...(ctaTextTop ? { cta_text_top: String(ctaTextTop) } : {}),
|
|
406
488
|
...(ctaTextBottom ? { cta_text_bottom: String(ctaTextBottom) } : {}),
|
|
407
489
|
...(ctaLogo ? { cta_logo: String(ctaLogo) } : {}),
|
|
@@ -867,8 +949,9 @@ export class SamsarClient {
|
|
|
867
949
|
}, options);
|
|
868
950
|
}
|
|
869
951
|
async addV2VideoOutroImage(input, options) {
|
|
952
|
+
const normalizedInput = normalizeUpdateVideoOutroImageInput(input, 'addV2VideoOutroImage');
|
|
870
953
|
return this.postV2('add_outro_image', {
|
|
871
|
-
input,
|
|
954
|
+
input: normalizedInput,
|
|
872
955
|
webhookUrl: options?.webhookUrl,
|
|
873
956
|
}, options);
|
|
874
957
|
}
|
|
@@ -1472,61 +1555,9 @@ export class SamsarClient {
|
|
|
1472
1555
|
* re-running frame/video generation.
|
|
1473
1556
|
*/
|
|
1474
1557
|
async addVideoOutroImage(input, options) {
|
|
1475
|
-
const
|
|
1476
|
-
const videoSessionId = raw.videoSessionId ??
|
|
1477
|
-
raw.video_session_id ??
|
|
1478
|
-
raw.videoSessionID ??
|
|
1479
|
-
raw.session_id ??
|
|
1480
|
-
raw.sessionId ??
|
|
1481
|
-
raw.sessionID ??
|
|
1482
|
-
raw.request_id ??
|
|
1483
|
-
raw.requestId;
|
|
1484
|
-
const outroImageUrl = raw.outro_image_url ??
|
|
1485
|
-
raw.outroImageUrl ??
|
|
1486
|
-
raw.new_outro_image_url ??
|
|
1487
|
-
raw.newOutroImageUrl;
|
|
1488
|
-
const rawAddOutroAnimation = raw.add_outro_animation ??
|
|
1489
|
-
raw.addOutroAnimation;
|
|
1490
|
-
const rawAddOutroFocusArea = raw.add_outro_focus_area ??
|
|
1491
|
-
raw.addOutroFocusArea;
|
|
1492
|
-
const rawOutroFocusArea = raw.outro_focust_area ??
|
|
1493
|
-
raw.outro_focus_area ??
|
|
1494
|
-
raw.outroFocustArea ??
|
|
1495
|
-
raw.outroFocusArea;
|
|
1496
|
-
if (!videoSessionId) {
|
|
1497
|
-
throw new Error('videoSessionId is required for addVideoOutroImage');
|
|
1498
|
-
}
|
|
1499
|
-
if (!outroImageUrl) {
|
|
1500
|
-
throw new Error('outro_image_url is required for addVideoOutroImage');
|
|
1501
|
-
}
|
|
1502
|
-
if (rawAddOutroAnimation !== undefined && typeof rawAddOutroAnimation !== 'boolean') {
|
|
1503
|
-
throw new Error('add_outro_animation must be a boolean for addVideoOutroImage');
|
|
1504
|
-
}
|
|
1505
|
-
if (rawAddOutroFocusArea !== undefined && typeof rawAddOutroFocusArea !== 'boolean') {
|
|
1506
|
-
throw new Error('add_outro_focus_area must be a boolean for addVideoOutroImage');
|
|
1507
|
-
}
|
|
1508
|
-
if (rawAddOutroFocusArea === true && rawAddOutroAnimation !== true) {
|
|
1509
|
-
throw new Error('add_outro_focus_area requires add_outro_animation to be true for addVideoOutroImage');
|
|
1510
|
-
}
|
|
1511
|
-
if (rawAddOutroFocusArea === true) {
|
|
1512
|
-
if (!rawOutroFocusArea || typeof rawOutroFocusArea !== 'object' || Array.isArray(rawOutroFocusArea)) {
|
|
1513
|
-
throw new Error('outro_focust_area must be an object with x, y, width, height for addVideoOutroImage');
|
|
1514
|
-
}
|
|
1515
|
-
const { x, y, width, height } = rawOutroFocusArea;
|
|
1516
|
-
const isInvalid = [x, y, width, height].some((value) => typeof value !== 'number' || !Number.isFinite(value));
|
|
1517
|
-
if (isInvalid) {
|
|
1518
|
-
throw new Error('outro_focust_area x, y, width, height must be valid numbers for addVideoOutroImage');
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1558
|
+
const normalizedInput = normalizeUpdateVideoOutroImageInput(input, 'addVideoOutroImage');
|
|
1521
1559
|
const body = {
|
|
1522
|
-
input:
|
|
1523
|
-
...input,
|
|
1524
|
-
videoSessionId: String(videoSessionId),
|
|
1525
|
-
outro_image_url: String(outroImageUrl),
|
|
1526
|
-
...(rawAddOutroAnimation !== undefined ? { add_outro_animation: rawAddOutroAnimation === true } : {}),
|
|
1527
|
-
...(rawAddOutroFocusArea !== undefined ? { add_outro_focus_area: rawAddOutroFocusArea === true } : {}),
|
|
1528
|
-
...(rawOutroFocusArea !== undefined ? { outro_focust_area: rawOutroFocusArea } : {}),
|
|
1529
|
-
},
|
|
1560
|
+
input: normalizedInput,
|
|
1530
1561
|
webhookUrl: options?.webhookUrl,
|
|
1531
1562
|
};
|
|
1532
1563
|
const response = await this.post('video/add_outro_image', body, options);
|
|
@@ -1554,68 +1585,10 @@ export class SamsarClient {
|
|
|
1554
1585
|
* Add or replace an outro image for an external-user video request by resolving the external request id.
|
|
1555
1586
|
*/
|
|
1556
1587
|
async addExternalVideoOutroImage(externalUser, input, options) {
|
|
1557
|
-
const
|
|
1558
|
-
const videoSessionId = raw.videoSessionId ??
|
|
1559
|
-
raw.video_session_id ??
|
|
1560
|
-
raw.videoSessionID ??
|
|
1561
|
-
raw.session_id ??
|
|
1562
|
-
raw.sessionId ??
|
|
1563
|
-
raw.sessionID ??
|
|
1564
|
-
raw.request_id ??
|
|
1565
|
-
raw.requestId ??
|
|
1566
|
-
raw.source_request_id ??
|
|
1567
|
-
raw.sourceRequestId ??
|
|
1568
|
-
raw.external_request_id ??
|
|
1569
|
-
raw.externalRequestId ??
|
|
1570
|
-
raw.external_session_id ??
|
|
1571
|
-
raw.externalSessionId;
|
|
1572
|
-
const outroImageUrl = raw.outro_image_url ??
|
|
1573
|
-
raw.outroImageUrl ??
|
|
1574
|
-
raw.new_outro_image_url ??
|
|
1575
|
-
raw.newOutroImageUrl;
|
|
1576
|
-
const rawAddOutroAnimation = raw.add_outro_animation ??
|
|
1577
|
-
raw.addOutroAnimation;
|
|
1578
|
-
const rawAddOutroFocusArea = raw.add_outro_focus_area ??
|
|
1579
|
-
raw.addOutroFocusArea;
|
|
1580
|
-
const rawOutroFocusArea = raw.outro_focust_area ??
|
|
1581
|
-
raw.outro_focus_area ??
|
|
1582
|
-
raw.outroFocustArea ??
|
|
1583
|
-
raw.outroFocusArea;
|
|
1584
|
-
if (!videoSessionId) {
|
|
1585
|
-
throw new Error('videoSessionId is required for addExternalVideoOutroImage');
|
|
1586
|
-
}
|
|
1587
|
-
if (!outroImageUrl) {
|
|
1588
|
-
throw new Error('outro_image_url is required for addExternalVideoOutroImage');
|
|
1589
|
-
}
|
|
1590
|
-
if (rawAddOutroAnimation !== undefined && typeof rawAddOutroAnimation !== 'boolean') {
|
|
1591
|
-
throw new Error('add_outro_animation must be a boolean for addExternalVideoOutroImage');
|
|
1592
|
-
}
|
|
1593
|
-
if (rawAddOutroFocusArea !== undefined && typeof rawAddOutroFocusArea !== 'boolean') {
|
|
1594
|
-
throw new Error('add_outro_focus_area must be a boolean for addExternalVideoOutroImage');
|
|
1595
|
-
}
|
|
1596
|
-
if (rawAddOutroFocusArea === true && rawAddOutroAnimation !== true) {
|
|
1597
|
-
throw new Error('add_outro_focus_area requires add_outro_animation to be true for addExternalVideoOutroImage');
|
|
1598
|
-
}
|
|
1599
|
-
if (rawAddOutroFocusArea === true) {
|
|
1600
|
-
if (!rawOutroFocusArea || typeof rawOutroFocusArea !== 'object' || Array.isArray(rawOutroFocusArea)) {
|
|
1601
|
-
throw new Error('outro_focust_area must be an object with x, y, width, height for addExternalVideoOutroImage');
|
|
1602
|
-
}
|
|
1603
|
-
const { x, y, width, height } = rawOutroFocusArea;
|
|
1604
|
-
const isInvalid = [x, y, width, height].some((value) => typeof value !== 'number' || !Number.isFinite(value));
|
|
1605
|
-
if (isInvalid) {
|
|
1606
|
-
throw new Error('outro_focust_area x, y, width, height must be valid numbers for addExternalVideoOutroImage');
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1588
|
+
const normalizedInput = normalizeUpdateVideoOutroImageInput(input, 'addExternalVideoOutroImage');
|
|
1609
1589
|
const body = {
|
|
1610
1590
|
external_user: normalizeExternalUserIdentity(externalUser),
|
|
1611
|
-
input:
|
|
1612
|
-
...input,
|
|
1613
|
-
videoSessionId: String(videoSessionId),
|
|
1614
|
-
outro_image_url: String(outroImageUrl),
|
|
1615
|
-
...(rawAddOutroAnimation !== undefined ? { add_outro_animation: rawAddOutroAnimation === true } : {}),
|
|
1616
|
-
...(rawAddOutroFocusArea !== undefined ? { add_outro_focus_area: rawAddOutroFocusArea === true } : {}),
|
|
1617
|
-
...(rawOutroFocusArea !== undefined ? { outro_focust_area: rawOutroFocusArea } : {}),
|
|
1618
|
-
},
|
|
1591
|
+
input: normalizedInput,
|
|
1619
1592
|
webhookUrl: options?.webhookUrl,
|
|
1620
1593
|
};
|
|
1621
1594
|
return this.post('external_users/add_outro_image', body, options);
|