samsar-js 0.48.23 → 0.48.25
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 +40 -4
- package/dist/index.d.ts +68 -5
- package/dist/index.js +182 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -131,13 +131,31 @@ await samsar.updateVideoOutroImage(
|
|
|
131
131
|
{ webhookUrl: 'https://example.com/webhook' },
|
|
132
132
|
);
|
|
133
133
|
|
|
134
|
+
// Update the footer CTA on an existing video session
|
|
135
|
+
await samsar.updateVideoFooterImage(
|
|
136
|
+
{
|
|
137
|
+
videoSessionId: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
|
|
138
|
+
cta_text: 'Scan to book',
|
|
139
|
+
cta_logo: 'https://cdn.example.com/logo-white.png',
|
|
140
|
+
cta_url: 'https://example.com/book',
|
|
141
|
+
},
|
|
142
|
+
{ webhookUrl: 'https://example.com/webhook' },
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Remove the footer from a cloned rerender
|
|
146
|
+
await samsar.updateVideoFooterImage({
|
|
147
|
+
videoSessionId: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
|
|
148
|
+
remove_footer: true,
|
|
149
|
+
});
|
|
150
|
+
|
|
134
151
|
// Translate an existing video session into another language
|
|
135
152
|
const translated = await samsar.translateVideo(
|
|
136
153
|
{
|
|
137
154
|
videoSessionId: videoFromImages.data.session_id ?? videoFromImages.data.request_id!,
|
|
138
155
|
language: 'es',
|
|
139
|
-
|
|
140
|
-
|
|
156
|
+
enable_subtitles: false,
|
|
157
|
+
translate_outro: true,
|
|
158
|
+
translate_footer: true,
|
|
141
159
|
},
|
|
142
160
|
{ webhookUrl: 'https://example.com/webhook' },
|
|
143
161
|
);
|
|
@@ -445,6 +463,15 @@ const externalOutroUpdate = await platform.updateExternalVideoOutroImage(externa
|
|
|
445
463
|
});
|
|
446
464
|
console.log(externalOutroUpdate.data.request_id);
|
|
447
465
|
|
|
466
|
+
// Update or remove an external user's existing footer CTA.
|
|
467
|
+
const externalFooterUpdate = await platform.updateExternalVideoFooterImage(externalUser, {
|
|
468
|
+
request_id: externalRender.data.request_id,
|
|
469
|
+
cta_text: 'Scan to shop',
|
|
470
|
+
cta_logo: 'https://cdn.example.com/logo-white.png',
|
|
471
|
+
cta_url: 'https://example.com/shop',
|
|
472
|
+
});
|
|
473
|
+
console.log(externalFooterUpdate.data.request_id);
|
|
474
|
+
|
|
448
475
|
// Repeated video routes accept the returned extreq_ id or the normalized external id.
|
|
449
476
|
// The API resolves ownership through external request mappings and GlobalSession records.
|
|
450
477
|
|
|
@@ -516,14 +543,15 @@ Video model support notes:
|
|
|
516
543
|
- `createVideoFromImageList` accepts either a provided outro (`outro_image_url`) or server-generated QR outro (`generate_outro_image: true` with `cta_url`). Do not combine the two modes in a single request.
|
|
517
544
|
- `createVideoFromImageList` can render per-scene footer QR cards by setting `add_footer_animation: true` and providing one `footer_metadata` item per image scene.
|
|
518
545
|
- `updateVideoOutroImage` accepts either a replacement outro image URL (`outro_image_url`, `outroImageUrl`, `new_outro_image_url`) or a generated QR CTA outro (`generate_outro_image: true` with `cta_url`, or just `cta_url` when no outro image URL is supplied). Generated outro updates reuse the existing session image layers for tiling and only queue frame/video regeneration.
|
|
519
|
-
-
|
|
546
|
+
- `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.
|
|
547
|
+
- 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.
|
|
520
548
|
- Completed video status, latest-version, and completed-session list responses expose `has_subtitles` and `result_language` when the session metadata is available.
|
|
521
549
|
- `publishPublication`, `editPublication`, and `revokePublication` manage public feed publications for completed sessions through free `/publications/*` endpoints. They work with account API keys, customer sub-account API keys, and client auth tokens when the session belongs to the authenticated actor.
|
|
522
550
|
- Image-list video pricing is per rendered second: `VEO3.1I2V` and `SEEDANCEI2V` are 75 credits/sec, `KLING3.0` is 50 credits/sec, and `RUNWAYML` is 25 credits/sec.
|
|
523
551
|
|
|
524
552
|
Upcoming `/v2` omni route adapters:
|
|
525
553
|
- `/v2` is additive; `/v1` is not deprecated.
|
|
526
|
-
- `createV2VideoFromText`, `createV2VideoFromImageList`, `updateV2VideoOutroImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
|
|
554
|
+
- `createV2VideoFromText`, `createV2VideoFromImageList`, `translateV2Video`, `updateV2VideoOutroImage`, `updateV2VideoFooterImage`, `addV2VideoOutroImage`, `getV2Status`, `getV2Credits`, `listV2Requests`, and `createV2Session` call the new omni route surface.
|
|
527
555
|
- Programmatic user billing helpers include `createV2UserRechargeCredits`, `refreshV2UserToken`, `createV2UserAppKey`, `refreshV2UserAppKey`, `getV2UserCredits`, `getV2UserUsageLogs`, and `getV2UserPaymentStatus`.
|
|
528
556
|
- Omit `externalUser` for internal account billing, pass `externalUser` to scope an external user with the account API key, or authenticate the client directly with an external-user auth token/API key.
|
|
529
557
|
|
|
@@ -544,6 +572,14 @@ const v2ExternalVideo = await platform.createV2VideoFromImageList(
|
|
|
544
572
|
{ externalUser },
|
|
545
573
|
);
|
|
546
574
|
|
|
575
|
+
const v2Translated = await platform.translateV2Video({
|
|
576
|
+
videoSessionId: v2Video.data.request_id!,
|
|
577
|
+
language: 'es',
|
|
578
|
+
enable_subtitles: false,
|
|
579
|
+
translate_outro: true,
|
|
580
|
+
translate_footer: true,
|
|
581
|
+
});
|
|
582
|
+
|
|
547
583
|
const v2Status = await platform.getV2Status(v2Video.data.request_id!);
|
|
548
584
|
console.log(v2Status.data.status);
|
|
549
585
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -95,8 +95,18 @@ export interface OutroFocusArea {
|
|
|
95
95
|
height: number;
|
|
96
96
|
}
|
|
97
97
|
export interface FooterMetadataItem {
|
|
98
|
-
url
|
|
98
|
+
url?: string;
|
|
99
|
+
cta_url?: string;
|
|
100
|
+
ctaUrl?: string;
|
|
99
101
|
title?: string;
|
|
102
|
+
text?: string;
|
|
103
|
+
cta_text?: string;
|
|
104
|
+
ctaText?: string;
|
|
105
|
+
cta_logo?: string;
|
|
106
|
+
ctaLogo?: string;
|
|
107
|
+
logoUrl?: string;
|
|
108
|
+
logoImagePath?: string;
|
|
109
|
+
footerLogoImagePath?: string;
|
|
100
110
|
}
|
|
101
111
|
export type ImageListToVideoAspectRatio = '16:9' | '9:16';
|
|
102
112
|
export type ImageListToVideoModel = 'VEO3.1I2V' | 'SEEDANCEI2V' | 'KLING3.0' | 'KLINGIMGTOVID3PRO' | 'RUNWAYML';
|
|
@@ -209,10 +219,14 @@ export interface TranslateVideoInput {
|
|
|
209
219
|
langauge?: string;
|
|
210
220
|
langauge_code?: string;
|
|
211
221
|
langaugeCode?: string;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
222
|
+
enable_subtitles?: boolean;
|
|
223
|
+
enableSubtitles?: boolean;
|
|
224
|
+
add_subtitles?: boolean;
|
|
225
|
+
addSubtitles?: boolean;
|
|
226
|
+
translate_outro?: boolean;
|
|
227
|
+
translateOutro?: boolean;
|
|
228
|
+
translate_footer?: boolean;
|
|
229
|
+
translateFooter?: boolean;
|
|
216
230
|
[key: string]: unknown;
|
|
217
231
|
}
|
|
218
232
|
export interface TranslateVideoResponse {
|
|
@@ -270,6 +284,39 @@ export interface UpdateVideoOutroImageResponse {
|
|
|
270
284
|
remainingCredits?: number | null;
|
|
271
285
|
[key: string]: unknown;
|
|
272
286
|
}
|
|
287
|
+
export interface UpdateVideoFooterImageInput {
|
|
288
|
+
videoSessionId?: string;
|
|
289
|
+
video_session_id?: string;
|
|
290
|
+
videoSessionID?: string;
|
|
291
|
+
session_id?: string;
|
|
292
|
+
sessionId?: string;
|
|
293
|
+
sessionID?: string;
|
|
294
|
+
request_id?: string;
|
|
295
|
+
requestId?: string;
|
|
296
|
+
source_request_id?: string;
|
|
297
|
+
sourceRequestId?: string;
|
|
298
|
+
external_request_id?: string;
|
|
299
|
+
externalRequestId?: string;
|
|
300
|
+
external_session_id?: string;
|
|
301
|
+
externalSessionId?: string;
|
|
302
|
+
remove_footer?: boolean;
|
|
303
|
+
removeFooter?: boolean;
|
|
304
|
+
cta_text?: string;
|
|
305
|
+
ctaText?: string;
|
|
306
|
+
cta_logo?: string;
|
|
307
|
+
ctaLogo?: string;
|
|
308
|
+
cta_url?: string;
|
|
309
|
+
ctaUrl?: string;
|
|
310
|
+
[key: string]: unknown;
|
|
311
|
+
}
|
|
312
|
+
export interface UpdateVideoFooterImageResponse {
|
|
313
|
+
request_id?: string;
|
|
314
|
+
session_id?: string;
|
|
315
|
+
sessionID?: string;
|
|
316
|
+
creditsCharged?: number;
|
|
317
|
+
remainingCredits?: number | null;
|
|
318
|
+
[key: string]: unknown;
|
|
319
|
+
}
|
|
273
320
|
export interface AddVideoOutroImageInput {
|
|
274
321
|
videoSessionId?: string;
|
|
275
322
|
video_session_id?: string;
|
|
@@ -1674,10 +1721,12 @@ export declare class SamsarClient {
|
|
|
1674
1721
|
}): Promise<SamsarResult<CreateLoginTokenResponse | ExternalCreateLoginTokenResponse>>;
|
|
1675
1722
|
createV2VideoFromText(input: CreateVideoFromTextInput, options?: V2RequestOptions): Promise<SamsarResult<CreateVideoResponse | ExternalRequestResponse>>;
|
|
1676
1723
|
createV2VideoFromImageList(input: CreateVideoFromImageListInput, options?: V2RequestOptions): Promise<SamsarResult<CreateVideoFromImageListResponse | ExternalRequestResponse>>;
|
|
1724
|
+
translateV2Video(input: TranslateVideoInput, options?: V2RequestOptions): Promise<SamsarResult<TranslateVideoResponse | ExternalRequestResponse>>;
|
|
1677
1725
|
uploadV2ImageData(imageData: string[], options?: V2RequestOptions): Promise<SamsarResult<{
|
|
1678
1726
|
image_urls: string[];
|
|
1679
1727
|
}>>;
|
|
1680
1728
|
updateV2VideoOutroImage(input: UpdateVideoOutroImageInput, options?: V2RequestOptions): Promise<SamsarResult<UpdateVideoOutroImageResponse | ExternalRequestResponse>>;
|
|
1729
|
+
updateV2VideoFooterImage(input: UpdateVideoFooterImageInput, options?: V2RequestOptions): Promise<SamsarResult<UpdateVideoFooterImageResponse | ExternalRequestResponse>>;
|
|
1681
1730
|
addV2VideoOutroImage(input: AddVideoOutroImageInput, options?: V2RequestOptions): Promise<SamsarResult<AddVideoOutroImageResponse | ExternalRequestResponse>>;
|
|
1682
1731
|
getV2Status(requestId: string, options?: V2RequestOptions & {
|
|
1683
1732
|
queryParams?: QueryParams;
|
|
@@ -1797,6 +1846,20 @@ export declare class SamsarClient {
|
|
|
1797
1846
|
updateExternalVideoOutroImage(externalUser: ExternalUserIdentity, input: UpdateVideoOutroImageInput, options?: {
|
|
1798
1847
|
webhookUrl?: string;
|
|
1799
1848
|
} & SamsarRequestOptions): Promise<SamsarResult<ExternalRequestResponse>>;
|
|
1849
|
+
/**
|
|
1850
|
+
* Update or remove the footer for an existing video session by cloning it into a new session and
|
|
1851
|
+
* re-running frame/video generation.
|
|
1852
|
+
*/
|
|
1853
|
+
updateVideoFooterImage(input: UpdateVideoFooterImageInput, options?: {
|
|
1854
|
+
webhookUrl?: string;
|
|
1855
|
+
} & SamsarRequestOptions): Promise<SamsarResult<UpdateVideoFooterImageResponse>>;
|
|
1856
|
+
/**
|
|
1857
|
+
* Update or remove the footer for an external-user video request through
|
|
1858
|
+
* /external_users/update_footer_image.
|
|
1859
|
+
*/
|
|
1860
|
+
updateExternalVideoFooterImage(externalUser: ExternalUserIdentity, input: UpdateVideoFooterImageInput, options?: {
|
|
1861
|
+
webhookUrl?: string;
|
|
1862
|
+
} & SamsarRequestOptions): Promise<SamsarResult<ExternalRequestResponse>>;
|
|
1800
1863
|
/**
|
|
1801
1864
|
* Add or replace the outro image for an existing video session by cloning it into a new session and
|
|
1802
1865
|
* re-running frame/video generation.
|
package/dist/index.js
CHANGED
|
@@ -126,6 +126,50 @@ function normalizeCreateVideoFromImageListInput(input) {
|
|
|
126
126
|
}
|
|
127
127
|
return normalized;
|
|
128
128
|
}
|
|
129
|
+
function normalizeTranslateVideoInput(input, context = 'translateVideo') {
|
|
130
|
+
const raw = input;
|
|
131
|
+
const videoSessionId = raw.videoSessionId ??
|
|
132
|
+
raw.video_session_id ??
|
|
133
|
+
raw.videoSessionID ??
|
|
134
|
+
raw.session_id ??
|
|
135
|
+
raw.sessionId ??
|
|
136
|
+
raw.sessionID ??
|
|
137
|
+
raw.request_id ??
|
|
138
|
+
raw.requestId;
|
|
139
|
+
const language = raw.language ??
|
|
140
|
+
raw.language_code ??
|
|
141
|
+
raw.languageCode ??
|
|
142
|
+
raw.langauge ??
|
|
143
|
+
raw.langauge_code ??
|
|
144
|
+
raw.langaugeCode ??
|
|
145
|
+
raw.languageString;
|
|
146
|
+
const enableSubtitles = resolveAliasedInputValue(raw, ['enable_subtitles', 'enableSubtitles', 'add_subtitles', 'addSubtitles'], 'enable_subtitles') ?? false;
|
|
147
|
+
const translateOutro = resolveAliasedInputValue(raw, ['translate_outro', 'translateOutro'], 'translate_outro') ?? true;
|
|
148
|
+
const translateFooter = resolveAliasedInputValue(raw, ['translate_footer', 'translateFooter'], 'translate_footer') ?? true;
|
|
149
|
+
if (!videoSessionId) {
|
|
150
|
+
throw new Error(`videoSessionId is required for ${context}`);
|
|
151
|
+
}
|
|
152
|
+
if (!language) {
|
|
153
|
+
throw new Error(`language is required for ${context}`);
|
|
154
|
+
}
|
|
155
|
+
assertOptionalBoolean(enableSubtitles, 'enable_subtitles', context);
|
|
156
|
+
assertOptionalBoolean(translateOutro, 'translate_outro', context);
|
|
157
|
+
assertOptionalBoolean(translateFooter, 'translate_footer', context);
|
|
158
|
+
const normalizedInput = { ...input };
|
|
159
|
+
delete normalizedInput.outro_image_url;
|
|
160
|
+
delete normalizedInput.outroImageUrl;
|
|
161
|
+
delete normalizedInput.outroImageURL;
|
|
162
|
+
delete normalizedInput.new_outro_image_url;
|
|
163
|
+
delete normalizedInput.newOutroImageUrl;
|
|
164
|
+
return {
|
|
165
|
+
...normalizedInput,
|
|
166
|
+
videoSessionId: String(videoSessionId),
|
|
167
|
+
language: String(language),
|
|
168
|
+
enable_subtitles: enableSubtitles,
|
|
169
|
+
translate_outro: translateOutro,
|
|
170
|
+
translate_footer: translateFooter,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
129
173
|
function normalizeUpdateVideoOutroImageInput(input, context = 'updateVideoOutroImage') {
|
|
130
174
|
const raw = input;
|
|
131
175
|
const videoSessionId = raw.videoSessionId ??
|
|
@@ -216,6 +260,61 @@ function normalizeUpdateVideoOutroImageInput(input, context = 'updateVideoOutroI
|
|
|
216
260
|
...(rawOutroFocusArea !== undefined ? { outro_focust_area: rawOutroFocusArea } : {}),
|
|
217
261
|
};
|
|
218
262
|
}
|
|
263
|
+
function normalizeUpdateVideoFooterImageInput(input, context = 'updateVideoFooterImage') {
|
|
264
|
+
const raw = input;
|
|
265
|
+
const videoSessionId = raw.videoSessionId ??
|
|
266
|
+
raw.video_session_id ??
|
|
267
|
+
raw.videoSessionID ??
|
|
268
|
+
raw.session_id ??
|
|
269
|
+
raw.sessionId ??
|
|
270
|
+
raw.sessionID ??
|
|
271
|
+
raw.request_id ??
|
|
272
|
+
raw.requestId ??
|
|
273
|
+
raw.source_request_id ??
|
|
274
|
+
raw.sourceRequestId ??
|
|
275
|
+
raw.external_request_id ??
|
|
276
|
+
raw.externalRequestId ??
|
|
277
|
+
raw.external_session_id ??
|
|
278
|
+
raw.externalSessionId;
|
|
279
|
+
const rawRemoveFooter = raw.remove_footer ??
|
|
280
|
+
raw.removeFooter;
|
|
281
|
+
const ctaText = raw.cta_text ??
|
|
282
|
+
raw.ctaText;
|
|
283
|
+
const ctaLogo = raw.cta_logo ??
|
|
284
|
+
raw.ctaLogo;
|
|
285
|
+
const ctaUrl = raw.cta_url ??
|
|
286
|
+
raw.ctaUrl;
|
|
287
|
+
const removeFooter = rawRemoveFooter === true;
|
|
288
|
+
if (!videoSessionId) {
|
|
289
|
+
throw new Error(`videoSessionId is required for ${context}`);
|
|
290
|
+
}
|
|
291
|
+
if (rawRemoveFooter !== undefined && typeof rawRemoveFooter !== 'boolean') {
|
|
292
|
+
throw new Error(`remove_footer must be a boolean for ${context}`);
|
|
293
|
+
}
|
|
294
|
+
if (ctaText !== undefined && typeof ctaText !== 'string') {
|
|
295
|
+
throw new Error(`cta_text must be a string for ${context}`);
|
|
296
|
+
}
|
|
297
|
+
if (ctaLogo !== undefined && typeof ctaLogo !== 'string') {
|
|
298
|
+
throw new Error(`cta_logo must be a string for ${context}`);
|
|
299
|
+
}
|
|
300
|
+
if (ctaUrl !== undefined && typeof ctaUrl !== 'string') {
|
|
301
|
+
throw new Error(`cta_url must be a string for ${context}`);
|
|
302
|
+
}
|
|
303
|
+
const normalizedCtaText = typeof ctaText === 'string' ? ctaText.trim() : '';
|
|
304
|
+
const normalizedCtaLogo = typeof ctaLogo === 'string' ? ctaLogo.trim() : '';
|
|
305
|
+
const normalizedCtaUrl = typeof ctaUrl === 'string' ? ctaUrl.trim() : '';
|
|
306
|
+
if (!removeFooter && !normalizedCtaText && !normalizedCtaLogo && !normalizedCtaUrl) {
|
|
307
|
+
throw new Error(`At least one of cta_text, cta_logo, or cta_url is required for ${context} unless remove_footer is true`);
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
...input,
|
|
311
|
+
videoSessionId: String(videoSessionId),
|
|
312
|
+
remove_footer: removeFooter,
|
|
313
|
+
...(normalizedCtaText ? { cta_text: normalizedCtaText } : {}),
|
|
314
|
+
...(normalizedCtaLogo ? { cta_logo: normalizedCtaLogo } : {}),
|
|
315
|
+
...(normalizedCtaUrl ? { cta_url: normalizedCtaUrl } : {}),
|
|
316
|
+
};
|
|
317
|
+
}
|
|
219
318
|
function normalizeSessionPublicationInput(input, context) {
|
|
220
319
|
if (typeof input !== 'string' && (!input || typeof input !== 'object' || Array.isArray(input))) {
|
|
221
320
|
throw new Error(`input must be a session id or object for ${context}`);
|
|
@@ -435,6 +534,13 @@ export class SamsarClient {
|
|
|
435
534
|
webhookUrl: options?.webhookUrl,
|
|
436
535
|
}, options);
|
|
437
536
|
}
|
|
537
|
+
async translateV2Video(input, options) {
|
|
538
|
+
const normalizedInput = normalizeTranslateVideoInput(input, 'translateV2Video');
|
|
539
|
+
return this.postV2('translate_video', {
|
|
540
|
+
input: normalizedInput,
|
|
541
|
+
webhookUrl: options?.webhookUrl,
|
|
542
|
+
}, options);
|
|
543
|
+
}
|
|
438
544
|
async uploadV2ImageData(imageData, options) {
|
|
439
545
|
if (!Array.isArray(imageData) || imageData.length === 0) {
|
|
440
546
|
throw new Error('imageData must be a non-empty array of data URLs');
|
|
@@ -452,6 +558,13 @@ export class SamsarClient {
|
|
|
452
558
|
webhookUrl: options?.webhookUrl,
|
|
453
559
|
}, options);
|
|
454
560
|
}
|
|
561
|
+
async updateV2VideoFooterImage(input, options) {
|
|
562
|
+
const normalizedInput = normalizeUpdateVideoFooterImageInput(input, 'updateV2VideoFooterImage');
|
|
563
|
+
return this.postV2('update_footer_image', {
|
|
564
|
+
input: normalizedInput,
|
|
565
|
+
webhookUrl: options?.webhookUrl,
|
|
566
|
+
}, options);
|
|
567
|
+
}
|
|
455
568
|
async addV2VideoOutroImage(input, options) {
|
|
456
569
|
return this.postV2('add_outro_image', {
|
|
457
570
|
input,
|
|
@@ -641,33 +754,10 @@ export class SamsarClient {
|
|
|
641
754
|
* Creates a new session_id and queues generation steps for lip sync + transcription + video render.
|
|
642
755
|
*/
|
|
643
756
|
async translateVideo(input, options) {
|
|
644
|
-
const
|
|
645
|
-
const videoSessionId = raw.videoSessionId ??
|
|
646
|
-
raw.video_session_id ??
|
|
647
|
-
raw.videoSessionID ??
|
|
648
|
-
raw.session_id ??
|
|
649
|
-
raw.sessionId ??
|
|
650
|
-
raw.sessionID ??
|
|
651
|
-
raw.request_id ??
|
|
652
|
-
raw.requestId;
|
|
653
|
-
const language = raw.language ??
|
|
654
|
-
raw.language_code ??
|
|
655
|
-
raw.languageCode ??
|
|
656
|
-
raw.langauge ??
|
|
657
|
-
raw.langauge_code ??
|
|
658
|
-
raw.langaugeCode ??
|
|
659
|
-
raw.languageString;
|
|
660
|
-
if (!videoSessionId) {
|
|
661
|
-
throw new Error('videoSessionId is required for translateVideo');
|
|
662
|
-
}
|
|
663
|
-
if (!language) {
|
|
664
|
-
throw new Error('language is required for translateVideo');
|
|
665
|
-
}
|
|
757
|
+
const normalizedInput = normalizeTranslateVideoInput(input, 'translateVideo');
|
|
666
758
|
const body = {
|
|
667
759
|
input: {
|
|
668
|
-
...
|
|
669
|
-
videoSessionId: String(videoSessionId),
|
|
670
|
-
language: String(language),
|
|
760
|
+
...normalizedInput,
|
|
671
761
|
},
|
|
672
762
|
webhookUrl: options?.webhookUrl,
|
|
673
763
|
};
|
|
@@ -923,6 +1013,50 @@ export class SamsarClient {
|
|
|
923
1013
|
};
|
|
924
1014
|
return this.post('external_users/update_outro_image', body, options);
|
|
925
1015
|
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Update or remove the footer for an existing video session by cloning it into a new session and
|
|
1018
|
+
* re-running frame/video generation.
|
|
1019
|
+
*/
|
|
1020
|
+
async updateVideoFooterImage(input, options) {
|
|
1021
|
+
const normalizedInput = normalizeUpdateVideoFooterImageInput(input, 'updateVideoFooterImage');
|
|
1022
|
+
const body = {
|
|
1023
|
+
input: normalizedInput,
|
|
1024
|
+
webhookUrl: options?.webhookUrl,
|
|
1025
|
+
};
|
|
1026
|
+
const response = await this.post('video/update_footer_image', body, options);
|
|
1027
|
+
const data = response.data;
|
|
1028
|
+
if (data && typeof data === 'object') {
|
|
1029
|
+
const sessionId = typeof data.sessionID === 'string'
|
|
1030
|
+
? data.sessionID
|
|
1031
|
+
: typeof data.session_id === 'string'
|
|
1032
|
+
? data.session_id
|
|
1033
|
+
: typeof data.request_id === 'string'
|
|
1034
|
+
? data.request_id
|
|
1035
|
+
: undefined;
|
|
1036
|
+
const normalizedSessionId = sessionId ? String(sessionId) : undefined;
|
|
1037
|
+
const normalizedData = {
|
|
1038
|
+
...data,
|
|
1039
|
+
sessionID: data.sessionID ?? normalizedSessionId ?? '',
|
|
1040
|
+
session_id: data.session_id ?? normalizedSessionId,
|
|
1041
|
+
request_id: data.request_id ?? normalizedSessionId,
|
|
1042
|
+
};
|
|
1043
|
+
return { ...response, data: normalizedData };
|
|
1044
|
+
}
|
|
1045
|
+
return response;
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* Update or remove the footer for an external-user video request through
|
|
1049
|
+
* /external_users/update_footer_image.
|
|
1050
|
+
*/
|
|
1051
|
+
async updateExternalVideoFooterImage(externalUser, input, options) {
|
|
1052
|
+
const normalizedInput = normalizeUpdateVideoFooterImageInput(input, 'updateExternalVideoFooterImage');
|
|
1053
|
+
const body = {
|
|
1054
|
+
external_user: normalizeExternalUserIdentity(externalUser),
|
|
1055
|
+
input: normalizedInput,
|
|
1056
|
+
webhookUrl: options?.webhookUrl,
|
|
1057
|
+
};
|
|
1058
|
+
return this.post('external_users/update_footer_image', body, options);
|
|
1059
|
+
}
|
|
926
1060
|
/**
|
|
927
1061
|
* Add or replace the outro image for an existing video session by cloning it into a new session and
|
|
928
1062
|
* re-running frame/video generation.
|
|
@@ -1755,7 +1889,10 @@ export class SamsarClient {
|
|
|
1755
1889
|
body: parsedBody,
|
|
1756
1890
|
});
|
|
1757
1891
|
}
|
|
1758
|
-
|
|
1892
|
+
const responseMessage = getResponseErrorMessage(parsedBody);
|
|
1893
|
+
throw new SamsarRequestError(responseMessage
|
|
1894
|
+
? `Request to ${url} failed with status ${response.status}: ${responseMessage}`
|
|
1895
|
+
: `Request to ${url} failed with status ${response.status}`, {
|
|
1759
1896
|
status: response.status,
|
|
1760
1897
|
body: parsedBody,
|
|
1761
1898
|
headers: headerRecord,
|
|
@@ -1837,6 +1974,25 @@ function parseMaybeJson(value) {
|
|
|
1837
1974
|
return value;
|
|
1838
1975
|
}
|
|
1839
1976
|
}
|
|
1977
|
+
function getResponseErrorMessage(body) {
|
|
1978
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
1979
|
+
return typeof body === 'string' && body.trim() ? body.trim() : null;
|
|
1980
|
+
}
|
|
1981
|
+
const record = body;
|
|
1982
|
+
for (const key of ['message', 'error', 'detail']) {
|
|
1983
|
+
const value = record[key];
|
|
1984
|
+
if (typeof value === 'string' && value.trim()) {
|
|
1985
|
+
return value.trim();
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
if (record.error && typeof record.error === 'object' && !Array.isArray(record.error)) {
|
|
1989
|
+
const nestedMessage = record.error.message;
|
|
1990
|
+
if (typeof nestedMessage === 'string' && nestedMessage.trim()) {
|
|
1991
|
+
return nestedMessage.trim();
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
return null;
|
|
1995
|
+
}
|
|
1840
1996
|
function headersToObject(headers) {
|
|
1841
1997
|
const result = {};
|
|
1842
1998
|
headers.forEach((value, key) => {
|