blitzreels 0.1.7 → 0.1.9
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/LICENSE +25 -0
- package/README.md +73 -5
- package/dist/cli-errors.d.ts.map +1 -1
- package/dist/cli-runtime.d.ts +1 -1
- package/dist/cli-runtime.d.ts.map +1 -1
- package/dist/cli-runtime.js +1 -1
- package/dist/cli-runtime.js.map +1 -1
- package/dist/command-metadata.d.ts.map +1 -1
- package/dist/command-metadata.js +2 -0
- package/dist/command-metadata.js.map +1 -1
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +2 -0
- package/dist/command-registry.js.map +1 -1
- package/dist/commands/auth-runtime.js +1 -1
- package/dist/commands/auth-runtime.js.map +1 -1
- package/dist/commands/bulk-delete-runtime.d.ts +12 -0
- package/dist/commands/bulk-delete-runtime.d.ts.map +1 -0
- package/dist/commands/bulk-delete-runtime.js +21 -0
- package/dist/commands/bulk-delete-runtime.js.map +1 -0
- package/dist/commands/caption-dry-run.d.ts +1 -0
- package/dist/commands/caption-dry-run.d.ts.map +1 -1
- package/dist/commands/caption-dry-run.js +32 -0
- package/dist/commands/caption-dry-run.js.map +1 -1
- package/dist/commands/caption-overrides.d.ts +13 -1
- package/dist/commands/caption-overrides.d.ts.map +1 -1
- package/dist/commands/caption-overrides.js +35 -2
- package/dist/commands/caption-overrides.js.map +1 -1
- package/dist/commands/caption-style-commands.d.ts.map +1 -1
- package/dist/commands/caption-style-commands.js +13 -3
- package/dist/commands/caption-style-commands.js.map +1 -1
- package/dist/commands/captions-specs.d.ts.map +1 -1
- package/dist/commands/captions-specs.js +18 -2
- package/dist/commands/captions-specs.js.map +1 -1
- package/dist/commands/captions.js +32 -0
- package/dist/commands/captions.js.map +1 -1
- package/dist/commands/clips.d.ts +4 -0
- package/dist/commands/clips.d.ts.map +1 -1
- package/dist/commands/clips.js +775 -7
- package/dist/commands/clips.js.map +1 -1
- package/dist/commands/command-operation.d.ts +2 -2
- package/dist/commands/command-operation.d.ts.map +1 -1
- package/dist/commands/command-operation.js +1 -1
- package/dist/commands/command-operation.js.map +1 -1
- package/dist/commands/editing-workflows.d.ts.map +1 -1
- package/dist/commands/editing-workflows.js +24 -6
- package/dist/commands/editing-workflows.js.map +1 -1
- package/dist/commands/faceless.d.ts.map +1 -1
- package/dist/commands/faceless.js +1 -0
- package/dist/commands/faceless.js.map +1 -1
- package/dist/commands/jobs.d.ts.map +1 -1
- package/dist/commands/jobs.js +2 -0
- package/dist/commands/jobs.js.map +1 -1
- package/dist/commands/media-assets.d.ts +5 -7
- package/dist/commands/media-assets.d.ts.map +1 -1
- package/dist/commands/media-assets.js +481 -21
- package/dist/commands/media-assets.js.map +1 -1
- package/dist/commands/media-overlays.d.ts.map +1 -1
- package/dist/commands/media-overlays.js +20 -2
- package/dist/commands/media-overlays.js.map +1 -1
- package/dist/commands/media-runtime.d.ts +4 -7
- package/dist/commands/media-runtime.d.ts.map +1 -1
- package/dist/commands/media-runtime.js +39 -7
- package/dist/commands/media-runtime.js.map +1 -1
- package/dist/commands/project-read.d.ts +30 -0
- package/dist/commands/project-read.d.ts.map +1 -1
- package/dist/commands/project-read.js +183 -6
- package/dist/commands/project-read.js.map +1 -1
- package/dist/commands/projects.d.ts.map +1 -1
- package/dist/commands/projects.js +125 -2
- package/dist/commands/projects.js.map +1 -1
- package/dist/commands/recording-sets.d.ts +44 -0
- package/dist/commands/recording-sets.d.ts.map +1 -0
- package/dist/commands/recording-sets.js +385 -0
- package/dist/commands/recording-sets.js.map +1 -0
- package/dist/commands/system.js +1 -1
- package/dist/commands/system.js.map +1 -1
- package/dist/commands/text-overlay-spec.js +62 -2
- package/dist/commands/text-overlay-spec.js.map +1 -1
- package/dist/commands/timeline-runtime.d.ts +30 -0
- package/dist/commands/timeline-runtime.d.ts.map +1 -1
- package/dist/commands/timeline-runtime.js +181 -42
- package/dist/commands/timeline-runtime.js.map +1 -1
- package/dist/commands/timeline.d.ts.map +1 -1
- package/dist/commands/timeline.js +158 -3
- package/dist/commands/timeline.js.map +1 -1
- package/dist/index.js +17 -3
- package/dist/index.js.map +1 -1
- package/dist/preview-first-edit.d.ts.map +1 -1
- package/dist/update-notifier.d.ts.map +1 -1
- package/dist/update-notifier.js +7 -3
- package/dist/update-notifier.js.map +1 -1
- package/package.json +6 -3
package/dist/commands/clips.js
CHANGED
|
@@ -1,7 +1,85 @@
|
|
|
1
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
+
import { CliOperationError, CliUsageError } from "../cli-errors.js";
|
|
3
4
|
import { commandSpec } from "../command-metadata.js";
|
|
4
5
|
export const CLIPS_COMMAND_SPECS = [
|
|
6
|
+
commandSpec({
|
|
7
|
+
command: ["clip-share-pages", "get"],
|
|
8
|
+
usage: "blitzreels clip-share-pages get --asset-id ID [--json]",
|
|
9
|
+
flags: ["asset-id"],
|
|
10
|
+
description: "Inspect the public clip share page and its hidden clip ids.",
|
|
11
|
+
}),
|
|
12
|
+
commandSpec({
|
|
13
|
+
command: ["clip-share-pages", "publish"],
|
|
14
|
+
usage: "blitzreels clip-share-pages publish --asset-id ID --idempotency-key KEY [--dry-run] [--json]",
|
|
15
|
+
flags: ["asset-id", { name: "idempotency-key", required: true }],
|
|
16
|
+
description: "Publish the clip share page for a source asset.",
|
|
17
|
+
mutates: true,
|
|
18
|
+
dryRunSupported: true,
|
|
19
|
+
}),
|
|
20
|
+
commandSpec({
|
|
21
|
+
command: ["clip-share-pages", "unpublish"],
|
|
22
|
+
usage: "blitzreels clip-share-pages unpublish --asset-id ID --idempotency-key KEY [--dry-run] [--json]",
|
|
23
|
+
flags: ["asset-id", { name: "idempotency-key", required: true }],
|
|
24
|
+
description: "Disable the public clip share page for a source asset.",
|
|
25
|
+
mutates: true,
|
|
26
|
+
dryRunSupported: true,
|
|
27
|
+
}),
|
|
28
|
+
commandSpec({
|
|
29
|
+
command: ["clip-share-pages", "set-clip-visibility"],
|
|
30
|
+
usage: "blitzreels clip-share-pages set-clip-visibility --asset-id ID --clip-id ID --visibility visible|hidden --idempotency-key KEY [--dry-run] [--json]",
|
|
31
|
+
flags: [
|
|
32
|
+
"asset-id",
|
|
33
|
+
"clip-id",
|
|
34
|
+
{ name: "visibility", enum: ["visible", "hidden"], required: true },
|
|
35
|
+
{ name: "idempotency-key", required: true },
|
|
36
|
+
],
|
|
37
|
+
description: "Show or hide one clip on its source asset share page.",
|
|
38
|
+
mutates: true,
|
|
39
|
+
dryRunSupported: true,
|
|
40
|
+
}),
|
|
41
|
+
commandSpec({
|
|
42
|
+
command: ["clip-batches", "get"],
|
|
43
|
+
usage: "blitzreels clip-batches get --batch-id ID [--json]",
|
|
44
|
+
flags: ["batch-id"],
|
|
45
|
+
description: "Inspect clip batch progress, Studio Sound status, and terminal errors.",
|
|
46
|
+
}),
|
|
47
|
+
commandSpec({
|
|
48
|
+
command: ["clip-batches", "wait"],
|
|
49
|
+
usage: "blitzreels clip-batches wait --batch-id ID [--interval-ms 3000] [--timeout-ms 1200000] [--json]",
|
|
50
|
+
flags: ["batch-id", "interval-ms", "timeout-ms"],
|
|
51
|
+
description: "Wait for a clip batch to complete or fail, including asynchronous Studio Sound.",
|
|
52
|
+
}),
|
|
53
|
+
commandSpec({
|
|
54
|
+
command: ["clip-batches", "recover"],
|
|
55
|
+
usage: "blitzreels clip-batches recover --batch-id ID [--target-count 10] --idempotency-key KEY [--dry-run] [--json]",
|
|
56
|
+
flags: [
|
|
57
|
+
"batch-id",
|
|
58
|
+
{ name: "target-count", type: "number" },
|
|
59
|
+
{ name: "idempotency-key", required: true },
|
|
60
|
+
],
|
|
61
|
+
description: "Preserve accepted clips and refill a terminal batch in its existing project folder.",
|
|
62
|
+
mutates: true,
|
|
63
|
+
dryRunSupported: true,
|
|
64
|
+
}),
|
|
65
|
+
commandSpec({
|
|
66
|
+
command: ["clip-batches", "delete"],
|
|
67
|
+
usage: "blitzreels clip-batches delete --batch-id ID --retention retain_projects_and_exports|delete_projects_and_exports --idempotency-key KEY --confirm-delete [--dry-run] [--json]",
|
|
68
|
+
flags: [
|
|
69
|
+
"batch-id",
|
|
70
|
+
{
|
|
71
|
+
name: "retention",
|
|
72
|
+
enum: ["retain_projects_and_exports", "delete_projects_and_exports"],
|
|
73
|
+
default: "retain_projects_and_exports",
|
|
74
|
+
},
|
|
75
|
+
"idempotency-key",
|
|
76
|
+
"confirm-delete",
|
|
77
|
+
],
|
|
78
|
+
description: "Delete a terminal clip batch with an explicit project/export retention policy.",
|
|
79
|
+
mutates: true,
|
|
80
|
+
destructive: true,
|
|
81
|
+
dryRunSupported: true,
|
|
82
|
+
}),
|
|
5
83
|
commandSpec({
|
|
6
84
|
command: ["clips", "list"],
|
|
7
85
|
usage: "blitzreels clips list [--asset-id ID] [--project-id ID] [--status ready|exported|failed|needs_repair] [--limit 20] [--offset 0] [--json]",
|
|
@@ -29,9 +107,37 @@ export const CLIPS_COMMAND_SPECS = [
|
|
|
29
107
|
],
|
|
30
108
|
description: "List managed clip runs with bounded output.",
|
|
31
109
|
}),
|
|
110
|
+
commandSpec({
|
|
111
|
+
command: ["clips", "attach-export"],
|
|
112
|
+
usage: "blitzreels clips attach-export --asset-id ID --project-id ID --export-id ID --confirm-visual-qa --idempotency-key KEY [--dry-run] [--json]",
|
|
113
|
+
flags: [
|
|
114
|
+
"asset-id",
|
|
115
|
+
"project-id",
|
|
116
|
+
"export-id",
|
|
117
|
+
{ name: "confirm-visual-qa", required: true },
|
|
118
|
+
{ name: "idempotency-key", required: true },
|
|
119
|
+
],
|
|
120
|
+
description: "Attach one visually accepted completed project export to managed clips.",
|
|
121
|
+
mutates: true,
|
|
122
|
+
destructive: true,
|
|
123
|
+
dryRunSupported: true,
|
|
124
|
+
}),
|
|
125
|
+
commandSpec({
|
|
126
|
+
command: ["clips", "promote-export"],
|
|
127
|
+
usage: "blitzreels clips promote-export --clip-id ID --export-id ID --confirm-visual-qa --idempotency-key KEY [--dry-run] [--json]",
|
|
128
|
+
flags: [
|
|
129
|
+
"clip-id",
|
|
130
|
+
"export-id",
|
|
131
|
+
{ name: "confirm-visual-qa", required: true },
|
|
132
|
+
{ name: "idempotency-key", required: true },
|
|
133
|
+
],
|
|
134
|
+
description: "Promote one visually accepted completed export as the managed clip delivery.",
|
|
135
|
+
mutates: true,
|
|
136
|
+
dryRunSupported: true,
|
|
137
|
+
}),
|
|
32
138
|
commandSpec({
|
|
33
139
|
command: ["clips", "create"],
|
|
34
|
-
usage: "blitzreels clips create [--asset-id ID|--youtube-url URL] [--output ./clips] [--count 5] [--idempotency-key KEY]",
|
|
140
|
+
usage: "blitzreels clips create [--asset-id ID|--youtube-url URL] [--output ./clips] [--count 5] [--layout-mode people_first] [--content-type-hint podcast] [--idempotency-key KEY]",
|
|
35
141
|
flags: [
|
|
36
142
|
{ name: "asset-id", enum: [] },
|
|
37
143
|
"youtube-url",
|
|
@@ -44,7 +150,7 @@ export const CLIPS_COMMAND_SPECS = [
|
|
|
44
150
|
name: "count",
|
|
45
151
|
type: "number",
|
|
46
152
|
default: 5,
|
|
47
|
-
description: "Maximum
|
|
153
|
+
description: "Maximum clips created by the batch.",
|
|
48
154
|
},
|
|
49
155
|
{
|
|
50
156
|
name: "preset",
|
|
@@ -61,6 +167,23 @@ export const CLIPS_COMMAND_SPECS = [
|
|
|
61
167
|
hidden: false,
|
|
62
168
|
},
|
|
63
169
|
{ name: "caption-theme-id" },
|
|
170
|
+
{
|
|
171
|
+
name: "layout-mode",
|
|
172
|
+
enum: [
|
|
173
|
+
"auto",
|
|
174
|
+
"people_first",
|
|
175
|
+
"screen_first",
|
|
176
|
+
"preserve_full_source",
|
|
177
|
+
"prefer_split",
|
|
178
|
+
"prefer_focus",
|
|
179
|
+
"prefer_tutorial",
|
|
180
|
+
"prefer_demo",
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "content-type-hint",
|
|
185
|
+
enum: ["auto", "podcast", "tutorial", "demo", "generic"],
|
|
186
|
+
},
|
|
64
187
|
{
|
|
65
188
|
name: "idempotency-key",
|
|
66
189
|
description: "Stable retry key; reuse only with identical inputs.",
|
|
@@ -72,6 +195,7 @@ export const CLIPS_COMMAND_SPECS = [
|
|
|
72
195
|
examples: [
|
|
73
196
|
"blitzreels clips create --asset-id ID --output ./clips",
|
|
74
197
|
"blitzreels clips create --asset-id ID --logo-asset-id LOGO_ID --output ./clips --count 5",
|
|
198
|
+
"blitzreels clips create --asset-id ID --layout-mode people_first --content-type-hint podcast",
|
|
75
199
|
"blitzreels clips create --youtube-url https://youtube.com/watch?v=...",
|
|
76
200
|
],
|
|
77
201
|
}),
|
|
@@ -89,7 +213,7 @@ export const CLIPS_COMMAND_SPECS = [
|
|
|
89
213
|
}),
|
|
90
214
|
commandSpec({
|
|
91
215
|
command: ["clips", "reselect"],
|
|
92
|
-
usage: "blitzreels clips reselect --clip-id ID [--suggestion-id ID | --start-seconds 52 --end-seconds 64]",
|
|
216
|
+
usage: "blitzreels clips reselect --clip-id ID [--suggestion-id ID | --start-seconds 52 --end-seconds 64] [--layout-mode people_first] [--content-type-hint podcast] [--caption-style-id cinematic-film] [--caption-word-reveal-animation fade] [--caption-max-lines 2] [--caption-words-per-line 8] [--caption-page-combine-ms 3000]",
|
|
93
217
|
flags: [
|
|
94
218
|
"clip-id",
|
|
95
219
|
"suggestion-id",
|
|
@@ -102,8 +226,54 @@ export const CLIPS_COMMAND_SPECS = [
|
|
|
102
226
|
},
|
|
103
227
|
{ name: "min-duration", hidden: true },
|
|
104
228
|
{ name: "max-duration", hidden: true },
|
|
229
|
+
{
|
|
230
|
+
name: "layout-mode",
|
|
231
|
+
enum: [
|
|
232
|
+
"auto",
|
|
233
|
+
"people_first",
|
|
234
|
+
"screen_first",
|
|
235
|
+
"preserve_full_source",
|
|
236
|
+
"prefer_split",
|
|
237
|
+
"prefer_focus",
|
|
238
|
+
"prefer_tutorial",
|
|
239
|
+
"prefer_demo",
|
|
240
|
+
],
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: "content-type-hint",
|
|
244
|
+
enum: ["auto", "podcast", "tutorial", "demo", "generic"],
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: "tutorial-stack-ratio",
|
|
248
|
+
enum: ["screen_70_face_30", "screen_50_face_50"],
|
|
249
|
+
hidden: true,
|
|
250
|
+
},
|
|
251
|
+
"captions-enabled",
|
|
252
|
+
"caption-style-id",
|
|
253
|
+
{
|
|
254
|
+
name: "caption-word-reveal-animation",
|
|
255
|
+
enum: [
|
|
256
|
+
"none",
|
|
257
|
+
"fade",
|
|
258
|
+
"scale",
|
|
259
|
+
"slide-up",
|
|
260
|
+
"slide-left",
|
|
261
|
+
"slide-mix",
|
|
262
|
+
"pop",
|
|
263
|
+
"drop",
|
|
264
|
+
"slam",
|
|
265
|
+
"typewriter",
|
|
266
|
+
"glitch",
|
|
267
|
+
"mask-reveal",
|
|
268
|
+
"bounce-up",
|
|
269
|
+
"split-reveal",
|
|
270
|
+
],
|
|
271
|
+
},
|
|
272
|
+
"caption-max-lines",
|
|
273
|
+
"caption-words-per-line",
|
|
274
|
+
"caption-page-combine-ms",
|
|
105
275
|
],
|
|
106
|
-
description: "
|
|
276
|
+
description: "Regenerate a clip from a suggestion or time range with optional layout and caption settings.",
|
|
107
277
|
mutates: true,
|
|
108
278
|
}),
|
|
109
279
|
commandSpec({
|
|
@@ -145,10 +315,101 @@ export const CLIPS_COMMAND_SPECS = [
|
|
|
145
315
|
mutates: true,
|
|
146
316
|
}),
|
|
147
317
|
];
|
|
318
|
+
function parseClipShareVisibility({ value, }) {
|
|
319
|
+
if (value === "visible" || value === "hidden") {
|
|
320
|
+
return value;
|
|
321
|
+
}
|
|
322
|
+
throw new CliUsageError({
|
|
323
|
+
code: "invalid_flag_value",
|
|
324
|
+
message: "--visibility must be visible or hidden.",
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
function printClipBatchResult({ context, result, helpers, }) {
|
|
328
|
+
helpers.printResult({
|
|
329
|
+
json: context.json,
|
|
330
|
+
value: result,
|
|
331
|
+
human: [
|
|
332
|
+
`Batch ${result.batch.batch_id}: ${result.batch.status}`,
|
|
333
|
+
`Studio Sound: ${result.batch.studio_sound.status}`,
|
|
334
|
+
`Accepted: ${result.batch.rendered_count}/${result.batch.estimated_clip_count}`,
|
|
335
|
+
...(result.batch.last_error_message === null
|
|
336
|
+
? []
|
|
337
|
+
: [`Error: ${result.batch.last_error_message}`]),
|
|
338
|
+
],
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
async function waitForClipBatch({ context, helpers, }) {
|
|
342
|
+
const batchId = helpers.requireStringFlag({
|
|
343
|
+
flags: context.args.flags,
|
|
344
|
+
name: "batch-id",
|
|
345
|
+
});
|
|
346
|
+
const intervalMs = helpers.getNumberFlag({
|
|
347
|
+
flags: context.args.flags,
|
|
348
|
+
name: "interval-ms",
|
|
349
|
+
}) ?? 3000;
|
|
350
|
+
const timeoutMs = helpers.getNumberFlag({
|
|
351
|
+
flags: context.args.flags,
|
|
352
|
+
name: "timeout-ms",
|
|
353
|
+
}) ?? 20 * 60 * 1000;
|
|
354
|
+
const startedAt = Date.now();
|
|
355
|
+
while (true) {
|
|
356
|
+
const result = await context.client.clipBatches.get({ batchId });
|
|
357
|
+
if (result.batch.studio_sound.status === "failed") {
|
|
358
|
+
throw new CliOperationError({
|
|
359
|
+
code: "studio_sound_failed",
|
|
360
|
+
exitCode: 5,
|
|
361
|
+
message: `Clip batch ${batchId} failed Studio Sound: ${result.batch.studio_sound.error_message ?? result.batch.last_error_message ?? "treatment was not applied"}`,
|
|
362
|
+
retryable: false,
|
|
363
|
+
suggestions: [
|
|
364
|
+
`blitzreels clip-batches recover --batch-id ${batchId} --idempotency-key NEW_KEY --json`,
|
|
365
|
+
],
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
if (result.batch.status === "failed") {
|
|
369
|
+
throw new CliOperationError({
|
|
370
|
+
code: "clip_batch_failed",
|
|
371
|
+
exitCode: 5,
|
|
372
|
+
message: `Clip batch ${batchId} failed: ${result.batch.last_error_message ?? result.batch.studio_sound.error_message ?? "clip processing failed"}`,
|
|
373
|
+
retryable: false,
|
|
374
|
+
suggestions: [
|
|
375
|
+
`blitzreels clip-batches recover --batch-id ${batchId} --idempotency-key NEW_KEY --json`,
|
|
376
|
+
],
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
if (result.batch.status === "completed_with_errors") {
|
|
380
|
+
throw new CliOperationError({
|
|
381
|
+
code: "clip_batch_incomplete",
|
|
382
|
+
exitCode: 5,
|
|
383
|
+
message: `Clip batch ${batchId} completed with ${result.batch.failed_count + result.batch.review_count} clips needing recovery.`,
|
|
384
|
+
retryable: false,
|
|
385
|
+
suggestions: [
|
|
386
|
+
`blitzreels clip-batches recover --batch-id ${batchId} --idempotency-key NEW_KEY --json`,
|
|
387
|
+
],
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
if (result.batch.status === "completed") {
|
|
391
|
+
return result;
|
|
392
|
+
}
|
|
393
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
394
|
+
throw new CliOperationError({
|
|
395
|
+
code: "clip_batch_wait_timeout",
|
|
396
|
+
exitCode: 7,
|
|
397
|
+
message: `Timed out waiting for clip batch ${batchId}.`,
|
|
398
|
+
retryable: true,
|
|
399
|
+
suggestions: [
|
|
400
|
+
`blitzreels clip-batches get --batch-id ${batchId} --json`,
|
|
401
|
+
],
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
await helpers.sleep({ ms: intervalMs });
|
|
405
|
+
}
|
|
406
|
+
}
|
|
148
407
|
export function createClipsCommandOperation({ helpers, }) {
|
|
149
408
|
return {
|
|
150
409
|
name: "clips",
|
|
151
|
-
matches: ({ command }) => command[0] === "clips"
|
|
410
|
+
matches: ({ command }) => command[0] === "clips" ||
|
|
411
|
+
command[0] === "clip-batches" ||
|
|
412
|
+
command[0] === "clip-share-pages",
|
|
152
413
|
handle: ({ context }) => handleClipsCommand({ context, helpers }),
|
|
153
414
|
buildDryRun: ({ context, spec }) => buildClipsDryRun({ context, spec, helpers }),
|
|
154
415
|
};
|
|
@@ -156,6 +417,139 @@ export function createClipsCommandOperation({ helpers, }) {
|
|
|
156
417
|
async function handleClipsCommand({ context, helpers, }) {
|
|
157
418
|
const action = context.args.command[1];
|
|
158
419
|
const flags = context.args.flags;
|
|
420
|
+
if (context.args.command[0] === "clip-share-pages") {
|
|
421
|
+
const assetId = helpers.requireStringFlag({ flags, name: "asset-id" });
|
|
422
|
+
if (action === "get") {
|
|
423
|
+
const result = await context.client.clipSharePages.get({ assetId });
|
|
424
|
+
helpers.printResult({
|
|
425
|
+
json: context.json,
|
|
426
|
+
value: result,
|
|
427
|
+
human: [
|
|
428
|
+
result.enabled
|
|
429
|
+
? `Published: ${result.share_url}`
|
|
430
|
+
: "Share page is not published.",
|
|
431
|
+
`Hidden clips: ${result.hidden_clip_ids.length}`,
|
|
432
|
+
],
|
|
433
|
+
});
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
if (action === "publish" || action === "unpublish") {
|
|
437
|
+
const result = await context.client.clipSharePages.setEnabled({
|
|
438
|
+
assetId,
|
|
439
|
+
enabled: action === "publish",
|
|
440
|
+
idempotencyKey: helpers.requireStringFlag({
|
|
441
|
+
flags,
|
|
442
|
+
name: "idempotency-key",
|
|
443
|
+
}),
|
|
444
|
+
});
|
|
445
|
+
helpers.printResult({
|
|
446
|
+
json: context.json,
|
|
447
|
+
value: result,
|
|
448
|
+
human: [
|
|
449
|
+
result.enabled
|
|
450
|
+
? `Published: ${result.share_url}`
|
|
451
|
+
: "Share page unpublished.",
|
|
452
|
+
],
|
|
453
|
+
});
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
if (action === "set-clip-visibility") {
|
|
457
|
+
const visibility = parseClipShareVisibility({
|
|
458
|
+
value: helpers.requireStringFlag({
|
|
459
|
+
flags,
|
|
460
|
+
name: "visibility",
|
|
461
|
+
}),
|
|
462
|
+
});
|
|
463
|
+
const result = await context.client.clipSharePages.setClipVisibility({
|
|
464
|
+
assetId,
|
|
465
|
+
clipId: helpers.requireStringFlag({ flags, name: "clip-id" }),
|
|
466
|
+
visibility,
|
|
467
|
+
idempotencyKey: helpers.requireStringFlag({
|
|
468
|
+
flags,
|
|
469
|
+
name: "idempotency-key",
|
|
470
|
+
}),
|
|
471
|
+
});
|
|
472
|
+
helpers.printResult({
|
|
473
|
+
json: context.json,
|
|
474
|
+
value: result,
|
|
475
|
+
human: [`Clip ${result.clip_id}: ${result.visibility}`],
|
|
476
|
+
});
|
|
477
|
+
return true;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (context.args.command[0] === "clip-batches" && action === "get") {
|
|
481
|
+
const result = await context.client.clipBatches.get({
|
|
482
|
+
batchId: helpers.requireStringFlag({ flags, name: "batch-id" }),
|
|
483
|
+
});
|
|
484
|
+
printClipBatchResult({ context, result, helpers });
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
if (context.args.command[0] === "clip-batches" && action === "wait") {
|
|
488
|
+
const result = await waitForClipBatch({ context, helpers });
|
|
489
|
+
printClipBatchResult({ context, result, helpers });
|
|
490
|
+
return true;
|
|
491
|
+
}
|
|
492
|
+
if (context.args.command[0] === "clip-batches" && action === "recover") {
|
|
493
|
+
const result = await context.client.clipBatches.recover({
|
|
494
|
+
batchId: helpers.requireStringFlag({ flags, name: "batch-id" }),
|
|
495
|
+
targetClipCount: helpers.getNumberFlag({ flags, name: "target-count" }) ?? null,
|
|
496
|
+
idempotencyKey: helpers.requireStringFlag({
|
|
497
|
+
flags,
|
|
498
|
+
name: "idempotency-key",
|
|
499
|
+
}),
|
|
500
|
+
});
|
|
501
|
+
if (result.status === "failed") {
|
|
502
|
+
throw new CliOperationError({
|
|
503
|
+
code: "clip_batch_recovery_failed",
|
|
504
|
+
exitCode: 5,
|
|
505
|
+
message: `Recovery batch ${result.recovery_batch_id ?? result.source_batch_id} failed: ${result.queue_reason ?? "clip recovery failed"}`,
|
|
506
|
+
retryable: false,
|
|
507
|
+
suggestions: [
|
|
508
|
+
'blitzreels agent-context --command "clip-batches recover" --json',
|
|
509
|
+
],
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
const statusLine = result.status === "satisfied"
|
|
513
|
+
? `Batch ${result.source_batch_id} already has ${result.retained_clip_count}/${result.target_clip_count} accepted clips.`
|
|
514
|
+
: result.status === "queued"
|
|
515
|
+
? `Recovery batch ${result.recovery_batch_id} queued for ${result.refill_clip_count} missing clips.`
|
|
516
|
+
: `Recovery batch ${result.recovery_batch_id} created; waiting: ${result.queue_reason ?? "not ready to queue"}.`;
|
|
517
|
+
helpers.printResult({
|
|
518
|
+
json: context.json,
|
|
519
|
+
value: result,
|
|
520
|
+
human: [
|
|
521
|
+
statusLine,
|
|
522
|
+
`Folder: ${result.project_folder_id}`,
|
|
523
|
+
"Duration policy: quality first; suggestion boundaries preserved.",
|
|
524
|
+
],
|
|
525
|
+
});
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
if (context.args.command[0] === "clip-batches" && action === "delete") {
|
|
529
|
+
if (helpers.getOptionalBooleanFlag({ flags, name: "confirm-delete" }) !== true) {
|
|
530
|
+
throw new Error("Pass --confirm-delete to delete a clip batch.");
|
|
531
|
+
}
|
|
532
|
+
const result = await context.client.clipBatches.delete({
|
|
533
|
+
batchId: helpers.requireStringFlag({ flags, name: "batch-id" }),
|
|
534
|
+
retention: parseClipBatchDeleteRetention({
|
|
535
|
+
value: helpers.getStringFlag({ flags, name: "retention" }),
|
|
536
|
+
}),
|
|
537
|
+
dryRun: false,
|
|
538
|
+
confirmDelete: true,
|
|
539
|
+
idempotencyKey: helpers.requireStringFlag({
|
|
540
|
+
flags,
|
|
541
|
+
name: "idempotency-key",
|
|
542
|
+
}),
|
|
543
|
+
});
|
|
544
|
+
helpers.printResult({
|
|
545
|
+
json: context.json,
|
|
546
|
+
value: result,
|
|
547
|
+
human: [
|
|
548
|
+
`Deleted batch ${result.batch_id}: ${result.deleted_clip_count} clips, ${result.deleted_project_count} projects, ${result.deleted_export_count} exports.`,
|
|
549
|
+
],
|
|
550
|
+
});
|
|
551
|
+
return true;
|
|
552
|
+
}
|
|
159
553
|
if (action === "create") {
|
|
160
554
|
const result = await createClipWorkflow({ context, helpers });
|
|
161
555
|
helpers.printResult({
|
|
@@ -173,6 +567,66 @@ async function handleClipsCommand({ context, helpers, }) {
|
|
|
173
567
|
});
|
|
174
568
|
return true;
|
|
175
569
|
}
|
|
570
|
+
if (action === "attach-export") {
|
|
571
|
+
if (helpers.getOptionalBooleanFlag({
|
|
572
|
+
flags,
|
|
573
|
+
name: "confirm-visual-qa",
|
|
574
|
+
}) !== true) {
|
|
575
|
+
throw new CliUsageError({
|
|
576
|
+
code: "missing_visual_qa_confirmation",
|
|
577
|
+
message: "Pass --confirm-visual-qa only after reviewing the completed MP4.",
|
|
578
|
+
usage: "blitzreels clips attach-export --asset-id ID --project-id ID --export-id ID --confirm-visual-qa --idempotency-key KEY",
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
const result = await context.client.clips.attachExport({
|
|
582
|
+
assetId: helpers.requireStringFlag({ flags, name: "asset-id" }),
|
|
583
|
+
projectId: helpers.requireStringFlag({ flags, name: "project-id" }),
|
|
584
|
+
exportId: helpers.requireStringFlag({ flags, name: "export-id" }),
|
|
585
|
+
confirmVisualQa: true,
|
|
586
|
+
idempotencyKey: helpers.requireStringFlag({
|
|
587
|
+
flags,
|
|
588
|
+
name: "idempotency-key",
|
|
589
|
+
}),
|
|
590
|
+
});
|
|
591
|
+
helpers.printResult({
|
|
592
|
+
json: context.json,
|
|
593
|
+
value: result,
|
|
594
|
+
human: [
|
|
595
|
+
`Attached export ${result.export_id} to managed clip ${result.clip_id}.`,
|
|
596
|
+
],
|
|
597
|
+
});
|
|
598
|
+
return true;
|
|
599
|
+
}
|
|
600
|
+
if (action === "promote-export") {
|
|
601
|
+
if (helpers.getOptionalBooleanFlag({
|
|
602
|
+
flags,
|
|
603
|
+
name: "confirm-visual-qa",
|
|
604
|
+
}) !== true) {
|
|
605
|
+
throw new CliUsageError({
|
|
606
|
+
code: "missing_visual_qa_confirmation",
|
|
607
|
+
message: "Pass --confirm-visual-qa only after reviewing the completed MP4.",
|
|
608
|
+
usage: "blitzreels clips promote-export --clip-id ID --export-id ID --confirm-visual-qa --idempotency-key KEY",
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
const result = await context.client.clips.promoteExport({
|
|
612
|
+
clipId: helpers.requireStringFlag({ flags, name: "clip-id" }),
|
|
613
|
+
exportId: helpers.requireStringFlag({ flags, name: "export-id" }),
|
|
614
|
+
confirmVisualQa: true,
|
|
615
|
+
idempotencyKey: helpers.requireStringFlag({
|
|
616
|
+
flags,
|
|
617
|
+
name: "idempotency-key",
|
|
618
|
+
}),
|
|
619
|
+
});
|
|
620
|
+
helpers.printResult({
|
|
621
|
+
json: context.json,
|
|
622
|
+
value: result,
|
|
623
|
+
human: [
|
|
624
|
+
`Promoted export ${result.export_id} for managed clip ${result.clip_id}.`,
|
|
625
|
+
`Previous export retained: ${result.previous_export_id}.`,
|
|
626
|
+
],
|
|
627
|
+
});
|
|
628
|
+
return true;
|
|
629
|
+
}
|
|
176
630
|
if (action === "list") {
|
|
177
631
|
const result = await context.client.clips.list({
|
|
178
632
|
assetId: helpers.getStringFlag({ flags, name: "asset-id" }),
|
|
@@ -216,6 +670,8 @@ async function handleClipsCommand({ context, helpers, }) {
|
|
|
216
670
|
flags,
|
|
217
671
|
name: "selection-mode",
|
|
218
672
|
});
|
|
673
|
+
const layout = buildReselectLayout({ flags, helpers });
|
|
674
|
+
const captions = buildReselectCaptions({ flags, helpers });
|
|
219
675
|
const result = await context.client.clips.reselect({
|
|
220
676
|
clipId,
|
|
221
677
|
...(selectionMode === undefined
|
|
@@ -224,10 +680,14 @@ async function handleClipsCommand({ context, helpers, }) {
|
|
|
224
680
|
startSeconds: selection.startSeconds,
|
|
225
681
|
endSeconds: selection.endSeconds,
|
|
226
682
|
target,
|
|
683
|
+
layout,
|
|
684
|
+
captions,
|
|
227
685
|
}
|
|
228
686
|
: {
|
|
229
687
|
selection,
|
|
230
688
|
target,
|
|
689
|
+
layout,
|
|
690
|
+
captions,
|
|
231
691
|
}),
|
|
232
692
|
});
|
|
233
693
|
helpers.printClipResult({ context, result });
|
|
@@ -299,6 +759,143 @@ function formatClipListLine({ clip }) {
|
|
|
299
759
|
function buildClipsDryRun({ context, spec, helpers, }) {
|
|
300
760
|
const action = context.args.command[1];
|
|
301
761
|
const flags = context.args.flags;
|
|
762
|
+
if (context.args.command[0] === "clips" && action === "attach-export") {
|
|
763
|
+
if (helpers.getOptionalBooleanFlag({
|
|
764
|
+
flags,
|
|
765
|
+
name: "confirm-visual-qa",
|
|
766
|
+
}) !== true) {
|
|
767
|
+
throw new CliUsageError({
|
|
768
|
+
code: "missing_visual_qa_confirmation",
|
|
769
|
+
message: "Pass --confirm-visual-qa only after reviewing the completed MP4.",
|
|
770
|
+
usage: "blitzreels clips attach-export --asset-id ID --project-id ID --export-id ID --confirm-visual-qa --idempotency-key KEY",
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
return helpers.dryRunRequest({
|
|
774
|
+
spec,
|
|
775
|
+
method: "POST",
|
|
776
|
+
path: "/clips/attach-export",
|
|
777
|
+
headers: {
|
|
778
|
+
"Idempotency-Key": helpers.requireStringFlag({
|
|
779
|
+
flags,
|
|
780
|
+
name: "idempotency-key",
|
|
781
|
+
}),
|
|
782
|
+
},
|
|
783
|
+
body: {
|
|
784
|
+
asset_id: helpers.requireStringFlag({ flags, name: "asset-id" }),
|
|
785
|
+
project_id: helpers.requireStringFlag({ flags, name: "project-id" }),
|
|
786
|
+
export_id: helpers.requireStringFlag({ flags, name: "export-id" }),
|
|
787
|
+
confirm_visual_qa: true,
|
|
788
|
+
},
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
if (context.args.command[0] === "clips" && action === "promote-export") {
|
|
792
|
+
if (helpers.getOptionalBooleanFlag({
|
|
793
|
+
flags,
|
|
794
|
+
name: "confirm-visual-qa",
|
|
795
|
+
}) !== true) {
|
|
796
|
+
throw new CliUsageError({
|
|
797
|
+
code: "missing_visual_qa_confirmation",
|
|
798
|
+
message: "Pass --confirm-visual-qa only after reviewing the completed MP4.",
|
|
799
|
+
usage: "blitzreels clips promote-export --clip-id ID --export-id ID --confirm-visual-qa --idempotency-key KEY",
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
const clipId = helpers.requireStringFlag({ flags, name: "clip-id" });
|
|
803
|
+
return helpers.dryRunRequest({
|
|
804
|
+
spec,
|
|
805
|
+
method: "POST",
|
|
806
|
+
path: `/clips/${encodeURIComponent(clipId)}/promote-export`,
|
|
807
|
+
headers: {
|
|
808
|
+
"Idempotency-Key": helpers.requireStringFlag({
|
|
809
|
+
flags,
|
|
810
|
+
name: "idempotency-key",
|
|
811
|
+
}),
|
|
812
|
+
},
|
|
813
|
+
body: {
|
|
814
|
+
export_id: helpers.requireStringFlag({ flags, name: "export-id" }),
|
|
815
|
+
confirm_visual_qa: true,
|
|
816
|
+
},
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
if (context.args.command[0] === "clip-share-pages") {
|
|
820
|
+
const assetId = helpers.requireStringFlag({ flags, name: "asset-id" });
|
|
821
|
+
if (action === "publish" || action === "unpublish") {
|
|
822
|
+
return helpers.dryRunRequest({
|
|
823
|
+
spec,
|
|
824
|
+
method: "POST",
|
|
825
|
+
path: `/clip-share-pages/${encodeURIComponent(assetId)}`,
|
|
826
|
+
headers: {
|
|
827
|
+
"Idempotency-Key": helpers.requireStringFlag({
|
|
828
|
+
flags,
|
|
829
|
+
name: "idempotency-key",
|
|
830
|
+
}),
|
|
831
|
+
},
|
|
832
|
+
body: { enabled: action === "publish" },
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
if (action === "set-clip-visibility") {
|
|
836
|
+
const clipId = helpers.requireStringFlag({ flags, name: "clip-id" });
|
|
837
|
+
return helpers.dryRunRequest({
|
|
838
|
+
spec,
|
|
839
|
+
method: "POST",
|
|
840
|
+
path: `/clip-share-pages/${encodeURIComponent(assetId)}/clips/${encodeURIComponent(clipId)}/visibility`,
|
|
841
|
+
headers: {
|
|
842
|
+
"Idempotency-Key": helpers.requireStringFlag({
|
|
843
|
+
flags,
|
|
844
|
+
name: "idempotency-key",
|
|
845
|
+
}),
|
|
846
|
+
},
|
|
847
|
+
body: {
|
|
848
|
+
visibility: parseClipShareVisibility({
|
|
849
|
+
value: helpers.requireStringFlag({
|
|
850
|
+
flags,
|
|
851
|
+
name: "visibility",
|
|
852
|
+
}),
|
|
853
|
+
}),
|
|
854
|
+
},
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
if (context.args.command[0] === "clip-batches" && action === "recover") {
|
|
859
|
+
return helpers.dryRunRequest({
|
|
860
|
+
spec,
|
|
861
|
+
method: "POST",
|
|
862
|
+
path: `/clip-batches/${encodeURIComponent(helpers.requireStringFlag({ flags, name: "batch-id" }))}/recover`,
|
|
863
|
+
headers: {
|
|
864
|
+
"Idempotency-Key": helpers.requireStringFlag({
|
|
865
|
+
flags,
|
|
866
|
+
name: "idempotency-key",
|
|
867
|
+
}),
|
|
868
|
+
},
|
|
869
|
+
body: {
|
|
870
|
+
target_clip_count: helpers.getNumberFlag({ flags, name: "target-count" }) ?? null,
|
|
871
|
+
},
|
|
872
|
+
notes: [
|
|
873
|
+
"Accepted exports remain linked; only the missing accepted count is refilled.",
|
|
874
|
+
"Suggestion boundaries are preserved even when a coherent clip exceeds the target duration.",
|
|
875
|
+
],
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
if (context.args.command[0] === "clip-batches" && action === "delete") {
|
|
879
|
+
return helpers.dryRunRequest({
|
|
880
|
+
spec,
|
|
881
|
+
method: "DELETE",
|
|
882
|
+
path: `/clip-batches/${encodeURIComponent(helpers.requireStringFlag({ flags, name: "batch-id" }))}`,
|
|
883
|
+
query: {
|
|
884
|
+
retention: parseClipBatchDeleteRetention({
|
|
885
|
+
value: helpers.getStringFlag({ flags, name: "retention" }),
|
|
886
|
+
}),
|
|
887
|
+
dry_run: true,
|
|
888
|
+
confirm_delete: false,
|
|
889
|
+
},
|
|
890
|
+
headers: {
|
|
891
|
+
"Idempotency-Key": helpers.requireStringFlag({
|
|
892
|
+
flags,
|
|
893
|
+
name: "idempotency-key",
|
|
894
|
+
}),
|
|
895
|
+
},
|
|
896
|
+
body: undefined,
|
|
897
|
+
});
|
|
898
|
+
}
|
|
302
899
|
if (action === "list") {
|
|
303
900
|
return helpers.dryRunRequest({
|
|
304
901
|
spec,
|
|
@@ -328,8 +925,9 @@ function buildClipsDryRun({ context, spec, helpers, }) {
|
|
|
328
925
|
quality: null,
|
|
329
926
|
},
|
|
330
927
|
clip_preset_id: options.clipPresetId,
|
|
928
|
+
max_clip_count: options.count,
|
|
331
929
|
caption_theme_id: options.captionThemeId,
|
|
332
|
-
create_flow_options: {},
|
|
930
|
+
create_flow_options: buildClipWorkflowCreateFlowOptions({ options }),
|
|
333
931
|
branding_options: buildClipWorkflowBrandingOptions({
|
|
334
932
|
logoAssetId: options.logoAssetId,
|
|
335
933
|
}),
|
|
@@ -362,6 +960,8 @@ function buildClipsDryRun({ context, spec, helpers, }) {
|
|
|
362
960
|
flags,
|
|
363
961
|
name: "selection-mode",
|
|
364
962
|
});
|
|
963
|
+
const layout = buildReselectLayout({ flags, helpers });
|
|
964
|
+
const captions = buildReselectCaptions({ flags, helpers });
|
|
365
965
|
return helpers.dryRunRequest({
|
|
366
966
|
spec,
|
|
367
967
|
method: "POST",
|
|
@@ -385,6 +985,12 @@ function buildClipsDryRun({ context, spec, helpers, }) {
|
|
|
385
985
|
max_duration_seconds: target.maxDurationSeconds,
|
|
386
986
|
},
|
|
387
987
|
}),
|
|
988
|
+
...(layout === null
|
|
989
|
+
? {}
|
|
990
|
+
: { layout: toApiClipLayout({ layout }) }),
|
|
991
|
+
...(captions === null
|
|
992
|
+
? {}
|
|
993
|
+
: { captions: toApiClipCaptions({ captions }) }),
|
|
388
994
|
}
|
|
389
995
|
: {
|
|
390
996
|
selection: toApiClipSelection({ selection }),
|
|
@@ -394,6 +1000,8 @@ function buildClipsDryRun({ context, spec, helpers, }) {
|
|
|
394
1000
|
min_duration_seconds: target.minDurationSeconds,
|
|
395
1001
|
max_duration_seconds: target.maxDurationSeconds,
|
|
396
1002
|
},
|
|
1003
|
+
layout: layout === null ? null : toApiClipLayout({ layout }),
|
|
1004
|
+
captions: captions === null ? null : toApiClipCaptions({ captions }),
|
|
397
1005
|
},
|
|
398
1006
|
});
|
|
399
1007
|
}
|
|
@@ -428,6 +1036,25 @@ function buildClipsDryRun({ context, spec, helpers, }) {
|
|
|
428
1036
|
}
|
|
429
1037
|
return undefined;
|
|
430
1038
|
}
|
|
1039
|
+
function parseClipBatchDeleteRetention({ value, }) {
|
|
1040
|
+
if (value === undefined || value === "retain_projects_and_exports") {
|
|
1041
|
+
return "retain_projects_and_exports";
|
|
1042
|
+
}
|
|
1043
|
+
if (value === "delete_projects_and_exports") {
|
|
1044
|
+
return value;
|
|
1045
|
+
}
|
|
1046
|
+
throw new Error("--retention must be retain_projects_and_exports or delete_projects_and_exports.");
|
|
1047
|
+
}
|
|
1048
|
+
function buildClipWorkflowCreateFlowOptions({ options, }) {
|
|
1049
|
+
return {
|
|
1050
|
+
...(options.layoutMode === undefined
|
|
1051
|
+
? {}
|
|
1052
|
+
: { reframeLayoutMode: options.layoutMode }),
|
|
1053
|
+
...(options.contentTypeHint === undefined
|
|
1054
|
+
? {}
|
|
1055
|
+
: { reframeContentTypeHint: options.contentTypeHint }),
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
431
1058
|
function parseClipWorkflowOptions({ flags, helpers, }) {
|
|
432
1059
|
const count = helpers.getNumberFlag({ flags, name: "count" }) ?? 5;
|
|
433
1060
|
if (!Number.isInteger(count) || count < 1 || count > 10) {
|
|
@@ -467,6 +1094,12 @@ function parseClipWorkflowOptions({ flags, helpers, }) {
|
|
|
467
1094
|
captionThemeId: parseNullableWorkflowString({
|
|
468
1095
|
value: helpers.getStringFlag({ flags, name: "caption-theme-id" }),
|
|
469
1096
|
}),
|
|
1097
|
+
layoutMode: parseClipLayoutMode({
|
|
1098
|
+
value: helpers.getStringFlag({ flags, name: "layout-mode" }),
|
|
1099
|
+
}),
|
|
1100
|
+
contentTypeHint: parseClipContentTypeHint({
|
|
1101
|
+
value: helpers.getStringFlag({ flags, name: "content-type-hint" }),
|
|
1102
|
+
}),
|
|
470
1103
|
idempotencyKey: helpers.getStringFlag({ flags, name: "idempotency-key" }) ?? null,
|
|
471
1104
|
};
|
|
472
1105
|
}
|
|
@@ -501,8 +1134,9 @@ async function createClipWorkflow({ context, helpers, }) {
|
|
|
501
1134
|
quality: null,
|
|
502
1135
|
},
|
|
503
1136
|
clipPresetId: options.clipPresetId,
|
|
1137
|
+
maxClipCount: options.count,
|
|
504
1138
|
captionThemeId: options.captionThemeId,
|
|
505
|
-
createFlowOptions: {},
|
|
1139
|
+
createFlowOptions: buildClipWorkflowCreateFlowOptions({ options }),
|
|
506
1140
|
brandingOptions: buildClipWorkflowBrandingOptions({
|
|
507
1141
|
logoAssetId: options.logoAssetId,
|
|
508
1142
|
}),
|
|
@@ -622,4 +1256,138 @@ function toApiClipSelection({ selection, }) {
|
|
|
622
1256
|
end_seconds: selection.endSeconds,
|
|
623
1257
|
};
|
|
624
1258
|
}
|
|
1259
|
+
function parseClipLayoutMode({ value, }) {
|
|
1260
|
+
if (value === undefined ||
|
|
1261
|
+
value === "auto" ||
|
|
1262
|
+
value === "people_first" ||
|
|
1263
|
+
value === "screen_first" ||
|
|
1264
|
+
value === "preserve_full_source" ||
|
|
1265
|
+
value === "prefer_split" ||
|
|
1266
|
+
value === "prefer_focus" ||
|
|
1267
|
+
value === "prefer_tutorial" ||
|
|
1268
|
+
value === "prefer_demo") {
|
|
1269
|
+
return value;
|
|
1270
|
+
}
|
|
1271
|
+
throw new Error(`Unsupported clip layout mode: ${value}`);
|
|
1272
|
+
}
|
|
1273
|
+
function parseClipContentTypeHint({ value, }) {
|
|
1274
|
+
if (value === undefined ||
|
|
1275
|
+
value === "auto" ||
|
|
1276
|
+
value === "podcast" ||
|
|
1277
|
+
value === "tutorial" ||
|
|
1278
|
+
value === "demo" ||
|
|
1279
|
+
value === "generic") {
|
|
1280
|
+
return value;
|
|
1281
|
+
}
|
|
1282
|
+
throw new Error(`Unsupported clip content type hint: ${value}`);
|
|
1283
|
+
}
|
|
1284
|
+
function parseTutorialStackRatio({ value, }) {
|
|
1285
|
+
if (value === undefined ||
|
|
1286
|
+
value === "screen_70_face_30" ||
|
|
1287
|
+
value === "screen_50_face_50") {
|
|
1288
|
+
return value;
|
|
1289
|
+
}
|
|
1290
|
+
throw new Error(`Unsupported tutorial stack ratio: ${value}`);
|
|
1291
|
+
}
|
|
1292
|
+
function buildReselectLayout({ flags, helpers, }) {
|
|
1293
|
+
const mode = parseClipLayoutMode({
|
|
1294
|
+
value: helpers.getStringFlag({ flags, name: "layout-mode" }),
|
|
1295
|
+
});
|
|
1296
|
+
const contentTypeHint = parseClipContentTypeHint({
|
|
1297
|
+
value: helpers.getStringFlag({ flags, name: "content-type-hint" }),
|
|
1298
|
+
});
|
|
1299
|
+
const tutorialStackRatio = parseTutorialStackRatio({
|
|
1300
|
+
value: helpers.getStringFlag({ flags, name: "tutorial-stack-ratio" }),
|
|
1301
|
+
});
|
|
1302
|
+
if (mode === undefined &&
|
|
1303
|
+
contentTypeHint === undefined &&
|
|
1304
|
+
tutorialStackRatio === undefined) {
|
|
1305
|
+
return null;
|
|
1306
|
+
}
|
|
1307
|
+
return { mode, contentTypeHint, tutorialStackRatio };
|
|
1308
|
+
}
|
|
1309
|
+
function buildReselectCaptions({ flags, helpers, }) {
|
|
1310
|
+
const enabled = helpers.getOptionalBooleanFlag({
|
|
1311
|
+
flags,
|
|
1312
|
+
name: "captions-enabled",
|
|
1313
|
+
});
|
|
1314
|
+
const styleId = helpers.getStringFlag({
|
|
1315
|
+
flags,
|
|
1316
|
+
name: "caption-style-id",
|
|
1317
|
+
});
|
|
1318
|
+
const wordRevealAnimation = parseCaptionWordRevealAnimation({
|
|
1319
|
+
value: helpers.getStringFlag({
|
|
1320
|
+
flags,
|
|
1321
|
+
name: "caption-word-reveal-animation",
|
|
1322
|
+
}),
|
|
1323
|
+
});
|
|
1324
|
+
const maxLinesPerCaption = helpers.getNumberFlag({
|
|
1325
|
+
flags,
|
|
1326
|
+
name: "caption-max-lines",
|
|
1327
|
+
});
|
|
1328
|
+
const wordsPerLineLimit = helpers.getNumberFlag({
|
|
1329
|
+
flags,
|
|
1330
|
+
name: "caption-words-per-line",
|
|
1331
|
+
});
|
|
1332
|
+
const pageCombineMs = helpers.getNumberFlag({
|
|
1333
|
+
flags,
|
|
1334
|
+
name: "caption-page-combine-ms",
|
|
1335
|
+
});
|
|
1336
|
+
if (enabled === undefined &&
|
|
1337
|
+
styleId === undefined &&
|
|
1338
|
+
wordRevealAnimation === undefined &&
|
|
1339
|
+
maxLinesPerCaption === undefined &&
|
|
1340
|
+
wordsPerLineLimit === undefined &&
|
|
1341
|
+
pageCombineMs === undefined) {
|
|
1342
|
+
return null;
|
|
1343
|
+
}
|
|
1344
|
+
return {
|
|
1345
|
+
enabled,
|
|
1346
|
+
styleId,
|
|
1347
|
+
wordRevealAnimation,
|
|
1348
|
+
maxLinesPerCaption,
|
|
1349
|
+
wordsPerLineLimit,
|
|
1350
|
+
pageCombineMs,
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
function parseCaptionWordRevealAnimation({ value, }) {
|
|
1354
|
+
const supported = [
|
|
1355
|
+
"none",
|
|
1356
|
+
"fade",
|
|
1357
|
+
"scale",
|
|
1358
|
+
"slide-up",
|
|
1359
|
+
"slide-left",
|
|
1360
|
+
"slide-mix",
|
|
1361
|
+
"pop",
|
|
1362
|
+
"drop",
|
|
1363
|
+
"slam",
|
|
1364
|
+
"typewriter",
|
|
1365
|
+
"glitch",
|
|
1366
|
+
"mask-reveal",
|
|
1367
|
+
"bounce-up",
|
|
1368
|
+
"split-reveal",
|
|
1369
|
+
];
|
|
1370
|
+
if (value === undefined ||
|
|
1371
|
+
supported.some((candidate) => candidate === value)) {
|
|
1372
|
+
return value;
|
|
1373
|
+
}
|
|
1374
|
+
throw new Error(`Unsupported caption word reveal animation: ${value}`);
|
|
1375
|
+
}
|
|
1376
|
+
function toApiClipLayout({ layout }) {
|
|
1377
|
+
return {
|
|
1378
|
+
layout_mode: layout.mode,
|
|
1379
|
+
content_type_hint: layout.contentTypeHint,
|
|
1380
|
+
tutorial_stack_ratio: layout.tutorialStackRatio,
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
function toApiClipCaptions({ captions }) {
|
|
1384
|
+
return {
|
|
1385
|
+
enabled: captions.enabled,
|
|
1386
|
+
style_id: captions.styleId,
|
|
1387
|
+
word_reveal_animation: captions.wordRevealAnimation,
|
|
1388
|
+
max_lines_per_caption: captions.maxLinesPerCaption,
|
|
1389
|
+
words_per_line_limit: captions.wordsPerLineLimit,
|
|
1390
|
+
page_combine_ms: captions.pageCombineMs,
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
625
1393
|
//# sourceMappingURL=clips.js.map
|