@clipwright/core 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +98 -0
- package/dist/api-failure.js +4 -0
- package/dist/api-failure.js.map +1 -1
- package/dist/aspect.d.ts +3 -0
- package/dist/aspect.js.map +1 -1
- package/dist/canvas-fit.d.ts +10 -0
- package/dist/canvas-fit.js +8 -0
- package/dist/canvas-fit.js.map +1 -0
- package/dist/contract-dispositions.d.ts +16 -9
- package/dist/contract-dispositions.js +16 -6
- package/dist/contract-dispositions.js.map +1 -1
- package/dist/contracts/v1/workflow-brief.d.ts +2 -0
- package/dist/contracts/v1/workflow-catalog.d.ts +2 -0
- package/dist/contracts/v1/workflow-client.d.ts +1 -0
- package/dist/contracts/v1/workflow-execution.d.ts +39 -0
- package/dist/contracts/v1/workflow-plan.d.ts +3 -0
- package/dist/contracts/v1/workflow-run-read.d.ts +26 -0
- package/dist/edit-billing.d.ts +1 -0
- package/dist/edit-billing.js +1 -1
- package/dist/edit-billing.js.map +1 -1
- package/dist/edit-long-form.d.ts +48 -0
- package/dist/edit-long-form.js +114 -0
- package/dist/edit-long-form.js.map +1 -0
- package/dist/edit-revision.d.ts +1 -0
- package/dist/edit-rules.d.ts +6 -2
- package/dist/edit-rules.js +8 -3
- package/dist/edit-rules.js.map +1 -1
- package/dist/edit-shots.d.ts +14 -4
- package/dist/edit-shots.js +2 -1
- package/dist/edit-shots.js.map +1 -1
- package/dist/edit-validate.d.ts +1 -1
- package/dist/edit-validate.js +76 -2
- package/dist/edit-validate.js.map +1 -1
- package/dist/edit.d.ts +3 -0
- package/dist/edit.js +5 -1
- package/dist/edit.js.map +1 -1
- package/dist/endpoints.d.ts +2 -0
- package/dist/endpoints.js +42 -35
- package/dist/endpoints.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +8 -1
- package/dist/errors.js.map +1 -1
- package/dist/faceless-media-record.d.ts +6 -0
- package/dist/faceless-media-record.js +3 -1
- package/dist/faceless-media-record.js.map +1 -1
- package/dist/faceless-public.d.ts +2 -0
- package/dist/generations-output.d.ts +19 -0
- package/dist/generations-output.js +16 -0
- package/dist/generations-output.js.map +1 -0
- package/dist/generations.d.ts +262 -0
- package/dist/generations.js +215 -0
- package/dist/generations.js.map +1 -0
- package/dist/idempotency.d.ts +2 -0
- package/dist/idempotency.js +8 -0
- package/dist/idempotency.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/long-form-revision.d.ts +244 -0
- package/dist/long-form-revision.js +104 -0
- package/dist/long-form-revision.js.map +1 -0
- package/dist/media-timebase.d.ts +4 -0
- package/dist/media-timebase.js +24 -0
- package/dist/media-timebase.js.map +1 -1
- package/dist/output-provenance.d.ts +26 -0
- package/dist/output-provenance.js +67 -0
- package/dist/output-provenance.js.map +1 -0
- package/dist/resolved-timeline.d.ts +86 -0
- package/dist/resolved-timeline.js +127 -0
- package/dist/resolved-timeline.js.map +1 -0
- package/dist/run-static-warnings.js +7 -0
- package/dist/run-static-warnings.js.map +1 -1
- package/dist/runs.d.ts +26 -0
- package/dist/runs.js +6 -0
- package/dist/runs.js.map +1 -1
- package/dist/skills.d.ts +5 -1
- package/dist/skills.js +4 -1
- package/dist/skills.js.map +1 -1
- package/dist/ugc-delivery.d.ts +64 -0
- package/dist/ugc-delivery.js +34 -0
- package/dist/ugc-delivery.js.map +1 -0
- package/dist/uploads.d.ts +37 -0
- package/dist/uploads.js +20 -1
- package/dist/uploads.js.map +1 -1
- package/dist/voice-admission.d.ts +1 -0
- package/dist/workflows/index.d.ts +1 -0
- package/dist/workflows/index.js +1 -0
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/methods/faceless-explainer.d.ts +1 -0
- package/dist/workflows/methods/kinetic-launch.d.ts +1 -0
- package/dist/workflows/methods/product-image-story.d.ts +1 -0
- package/dist/workflows/methods/shared.d.ts +1 -0
- package/dist/workflows/methods/ugc-faq-answer.d.ts +1 -0
- package/dist/workflows/methods/ugc-faq-answer.js +2 -2
- package/dist/workflows/methods/ugc-faq-answer.js.map +1 -1
- package/dist/workflows/methods/ugc-product-intro.d.ts +1 -0
- package/dist/workflows/methods/ugc-product-intro.js +2 -2
- package/dist/workflows/methods/ugc-product-intro.js.map +1 -1
- package/dist/workflows/methods/website-proof-demo.d.ts +1 -0
- package/dist/workflows/product-references.d.ts +4 -0
- package/dist/workflows/product-references.js +32 -0
- package/dist/workflows/product-references.js.map +1 -0
- package/dist/workflows/validate.js +2 -0
- package/dist/workflows/validate.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type ResolvedTimeline } from "./resolved-timeline.js";
|
|
3
|
+
/** How a long-form run fills what a picture leaves of the canvas (`makeUgcInput.background`). */
|
|
4
|
+
export declare const LONG_FORM_BACKGROUNDS: readonly ["white", "blur", "contain"];
|
|
5
|
+
export type LongFormBackground = (typeof LONG_FORM_BACKGROUNDS)[number];
|
|
6
|
+
/** A picture's zoom, as `makeUgcInput` takes it. */
|
|
7
|
+
export declare const longFormImageMotion: z.ZodObject<{
|
|
8
|
+
direction: z.ZodEnum<{
|
|
9
|
+
in: "in";
|
|
10
|
+
out: "out";
|
|
11
|
+
}>;
|
|
12
|
+
amount: z.ZodNumber;
|
|
13
|
+
}, z.core.$strict>;
|
|
14
|
+
export type LongFormImageMotion = z.infer<typeof longFormImageMotion>;
|
|
15
|
+
/** What a render needs beyond the timeline, copied from the root's input at admission; a position absent from the motions does not move. */
|
|
16
|
+
export declare const longFormRevisionRender: z.ZodObject<{
|
|
17
|
+
aspect_ratio: z.ZodEnum<{
|
|
18
|
+
"16:9": "16:9";
|
|
19
|
+
"1:1": "1:1";
|
|
20
|
+
"9:16": "9:16";
|
|
21
|
+
}>;
|
|
22
|
+
width: z.ZodNumber;
|
|
23
|
+
height: z.ZodNumber;
|
|
24
|
+
background: z.ZodNullable<z.ZodEnum<{
|
|
25
|
+
blur: "blur";
|
|
26
|
+
contain: "contain";
|
|
27
|
+
white: "white";
|
|
28
|
+
}>>;
|
|
29
|
+
motion_by_position: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
30
|
+
direction: z.ZodEnum<{
|
|
31
|
+
in: "in";
|
|
32
|
+
out: "out";
|
|
33
|
+
}>;
|
|
34
|
+
amount: z.ZodNumber;
|
|
35
|
+
}, z.core.$strict>>;
|
|
36
|
+
}, z.core.$strict>;
|
|
37
|
+
export type LongFormRevisionRender = z.infer<typeof longFormRevisionRender>;
|
|
38
|
+
/** The stored input of a `revise_long_form` run: the request as resolved, and what admission froze about it. */
|
|
39
|
+
export declare const longFormRevisionInput: z.ZodObject<{
|
|
40
|
+
input_mode: z.ZodLiteral<"revision">;
|
|
41
|
+
revision: z.ZodObject<{
|
|
42
|
+
source_run_id: z.ZodString;
|
|
43
|
+
document: z.ZodObject<{
|
|
44
|
+
v: z.ZodLiteral<1>;
|
|
45
|
+
source_run_id: z.ZodString;
|
|
46
|
+
timebase: z.ZodObject<{
|
|
47
|
+
fps: z.ZodNumber;
|
|
48
|
+
}, z.core.$strict>;
|
|
49
|
+
duration_frames: z.ZodNumber;
|
|
50
|
+
shots: z.ZodArray<z.ZodObject<{
|
|
51
|
+
id: z.ZodString;
|
|
52
|
+
track: z.ZodEnum<{
|
|
53
|
+
presenter: "presenter";
|
|
54
|
+
visual: "visual";
|
|
55
|
+
}>;
|
|
56
|
+
kind: z.ZodEnum<{
|
|
57
|
+
clip: "clip";
|
|
58
|
+
picture: "picture";
|
|
59
|
+
presenter: "presenter";
|
|
60
|
+
}>;
|
|
61
|
+
start_frame: z.ZodNumber;
|
|
62
|
+
end_frame: z.ZodNumber;
|
|
63
|
+
media_offset_frames: z.ZodOptional<z.ZodNumber>;
|
|
64
|
+
asset: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
65
|
+
from: z.ZodLiteral<"source">;
|
|
66
|
+
shot_id: z.ZodString;
|
|
67
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
68
|
+
from: z.ZodLiteral<"candidate">;
|
|
69
|
+
run_id: z.ZodString;
|
|
70
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
71
|
+
from: z.ZodLiteral<"upload">;
|
|
72
|
+
upload_id: z.ZodString;
|
|
73
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
74
|
+
from: z.ZodLiteral<"generate">;
|
|
75
|
+
operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
76
|
+
mode: z.ZodLiteral<"retake">;
|
|
77
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
78
|
+
mode: z.ZodLiteral<"new_picture">;
|
|
79
|
+
description: z.ZodString;
|
|
80
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
81
|
+
mode: z.ZodLiteral<"edit_picture">;
|
|
82
|
+
instruction: z.ZodString;
|
|
83
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
84
|
+
mode: z.ZodLiteral<"animate">;
|
|
85
|
+
motion: z.ZodOptional<z.ZodString>;
|
|
86
|
+
}, z.core.$strict>], "mode">;
|
|
87
|
+
}, z.core.$strict>], "from">;
|
|
88
|
+
}, z.core.$strict>>;
|
|
89
|
+
discarded: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
90
|
+
}, z.core.$strict>;
|
|
91
|
+
}, z.core.$strict>;
|
|
92
|
+
resolved_revision: z.ZodObject<{
|
|
93
|
+
root_run_id: z.ZodString;
|
|
94
|
+
summary: z.ZodObject<{
|
|
95
|
+
retimed: z.ZodArray<z.ZodString>;
|
|
96
|
+
deleted: z.ZodArray<z.ZodString>;
|
|
97
|
+
added: z.ZodArray<z.ZodString>;
|
|
98
|
+
replaced: z.ZodArray<z.ZodObject<{
|
|
99
|
+
shot_id: z.ZodString;
|
|
100
|
+
from: z.ZodEnum<{
|
|
101
|
+
candidate: "candidate";
|
|
102
|
+
source: "source";
|
|
103
|
+
upload: "upload";
|
|
104
|
+
}>;
|
|
105
|
+
}, z.core.$strict>>;
|
|
106
|
+
generated: z.ZodArray<z.ZodObject<{
|
|
107
|
+
shot_id: z.ZodString;
|
|
108
|
+
kind: z.ZodEnum<{
|
|
109
|
+
clip: "clip";
|
|
110
|
+
picture: "picture";
|
|
111
|
+
presenter: "presenter";
|
|
112
|
+
}>;
|
|
113
|
+
mode: z.ZodEnum<{
|
|
114
|
+
animate: "animate";
|
|
115
|
+
edit_picture: "edit_picture";
|
|
116
|
+
new_picture: "new_picture";
|
|
117
|
+
retake: "retake";
|
|
118
|
+
}>;
|
|
119
|
+
}, z.core.$strict>>;
|
|
120
|
+
changed: z.ZodBoolean;
|
|
121
|
+
}, z.core.$strict>;
|
|
122
|
+
billing: z.ZodObject<{
|
|
123
|
+
tariff_id: z.ZodString;
|
|
124
|
+
lines: z.ZodArray<z.ZodObject<{
|
|
125
|
+
shot_id: z.ZodString;
|
|
126
|
+
unit: z.ZodEnum<{
|
|
127
|
+
clip: "clip";
|
|
128
|
+
clip_with_new_picture: "clip_with_new_picture";
|
|
129
|
+
kept_clip: "kept_clip";
|
|
130
|
+
kept_picture: "kept_picture";
|
|
131
|
+
picture: "picture";
|
|
132
|
+
}>;
|
|
133
|
+
credits: z.ZodNumber;
|
|
134
|
+
}, z.core.$strict>>;
|
|
135
|
+
render_credits: z.ZodNumber;
|
|
136
|
+
zero_unit: z.ZodNullable<z.ZodEnum<{
|
|
137
|
+
free: "free";
|
|
138
|
+
priced: "priced";
|
|
139
|
+
}>>;
|
|
140
|
+
total_credits: z.ZodNumber;
|
|
141
|
+
}, z.core.$strict>;
|
|
142
|
+
render: z.ZodObject<{
|
|
143
|
+
aspect_ratio: z.ZodEnum<{
|
|
144
|
+
"16:9": "16:9";
|
|
145
|
+
"1:1": "1:1";
|
|
146
|
+
"9:16": "9:16";
|
|
147
|
+
}>;
|
|
148
|
+
width: z.ZodNumber;
|
|
149
|
+
height: z.ZodNumber;
|
|
150
|
+
background: z.ZodNullable<z.ZodEnum<{
|
|
151
|
+
blur: "blur";
|
|
152
|
+
contain: "contain";
|
|
153
|
+
white: "white";
|
|
154
|
+
}>>;
|
|
155
|
+
motion_by_position: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
156
|
+
direction: z.ZodEnum<{
|
|
157
|
+
in: "in";
|
|
158
|
+
out: "out";
|
|
159
|
+
}>;
|
|
160
|
+
amount: z.ZodNumber;
|
|
161
|
+
}, z.core.$strict>>;
|
|
162
|
+
}, z.core.$strict>;
|
|
163
|
+
}, z.core.$strict>;
|
|
164
|
+
}, z.core.$strict>;
|
|
165
|
+
export type LongFormRevisionInput = z.infer<typeof longFormRevisionInput>;
|
|
166
|
+
/** One changed visual shot, drawn above the source tiling over its whole span. A cover has no motion; an insert keeps its slot's. */
|
|
167
|
+
export declare const longFormOverlay: z.ZodObject<{
|
|
168
|
+
shot_id: z.ZodString;
|
|
169
|
+
start_frame: z.ZodNumber;
|
|
170
|
+
end_frame: z.ZodNumber;
|
|
171
|
+
object: z.ZodObject<{
|
|
172
|
+
key: z.ZodString;
|
|
173
|
+
sha256: z.ZodString;
|
|
174
|
+
bytes: z.ZodNumber;
|
|
175
|
+
width: z.ZodNumber;
|
|
176
|
+
height: z.ZodNumber;
|
|
177
|
+
content_type: z.ZodEnum<{
|
|
178
|
+
"image/jpeg": "image/jpeg";
|
|
179
|
+
"image/png": "image/png";
|
|
180
|
+
}>;
|
|
181
|
+
}, z.core.$strict>;
|
|
182
|
+
origin: z.ZodEnum<{
|
|
183
|
+
source: "source";
|
|
184
|
+
upload: "upload";
|
|
185
|
+
}>;
|
|
186
|
+
motion: z.ZodNullable<z.ZodObject<{
|
|
187
|
+
direction: z.ZodEnum<{
|
|
188
|
+
in: "in";
|
|
189
|
+
out: "out";
|
|
190
|
+
}>;
|
|
191
|
+
amount: z.ZodNumber;
|
|
192
|
+
}, z.core.$strict>>;
|
|
193
|
+
}, z.core.$strict>;
|
|
194
|
+
export type LongFormOverlay = z.infer<typeof longFormOverlay>;
|
|
195
|
+
declare const recordShape: z.ZodObject<{
|
|
196
|
+
version: z.ZodLiteral<1>;
|
|
197
|
+
run_id: z.ZodString;
|
|
198
|
+
account_id: z.ZodString;
|
|
199
|
+
source_run_id: z.ZodString;
|
|
200
|
+
root_run_id: z.ZodString;
|
|
201
|
+
base: z.ZodUnknown;
|
|
202
|
+
visual: z.ZodArray<z.ZodObject<{
|
|
203
|
+
shot_id: z.ZodString;
|
|
204
|
+
start_frame: z.ZodNumber;
|
|
205
|
+
end_frame: z.ZodNumber;
|
|
206
|
+
object: z.ZodObject<{
|
|
207
|
+
key: z.ZodString;
|
|
208
|
+
sha256: z.ZodString;
|
|
209
|
+
bytes: z.ZodNumber;
|
|
210
|
+
width: z.ZodNumber;
|
|
211
|
+
height: z.ZodNumber;
|
|
212
|
+
content_type: z.ZodEnum<{
|
|
213
|
+
"image/jpeg": "image/jpeg";
|
|
214
|
+
"image/png": "image/png";
|
|
215
|
+
}>;
|
|
216
|
+
}, z.core.$strict>;
|
|
217
|
+
origin: z.ZodEnum<{
|
|
218
|
+
source: "source";
|
|
219
|
+
upload: "upload";
|
|
220
|
+
}>;
|
|
221
|
+
motion: z.ZodNullable<z.ZodObject<{
|
|
222
|
+
direction: z.ZodEnum<{
|
|
223
|
+
in: "in";
|
|
224
|
+
out: "out";
|
|
225
|
+
}>;
|
|
226
|
+
amount: z.ZodNumber;
|
|
227
|
+
}, z.core.$strict>>;
|
|
228
|
+
}, z.core.$strict>>;
|
|
229
|
+
}, z.core.$strict>;
|
|
230
|
+
/** What a delivered long-form revision rendered: the source tiling rebound to its own run and keys, and its overlays. */
|
|
231
|
+
export type LongFormRevisionRecord = Omit<z.infer<typeof recordShape>, "base"> & {
|
|
232
|
+
base: ResolvedTimeline;
|
|
233
|
+
};
|
|
234
|
+
/** Where a long-form revision's record is stored, and the most bytes it may take there. */
|
|
235
|
+
export declare const longFormRevisionRecordKey: (id: string) => string;
|
|
236
|
+
export declare const LONG_FORM_REVISION_RECORD_MAX_BYTES = 512000;
|
|
237
|
+
/** Whether a key names an object of this run: a plain path under `runs/<runId>/`, with no segment to climb out by. */
|
|
238
|
+
export declare function longFormOwnKey(key: string, id: string): boolean;
|
|
239
|
+
/** The stored record of the run being read, checked against that run and against itself: every key and overlay belong to it. */
|
|
240
|
+
export declare function readLongFormRevisionRecord(stored: string | Uint8Array, expected: {
|
|
241
|
+
runId: string;
|
|
242
|
+
accountId: string;
|
|
243
|
+
}): LongFormRevisionRecord;
|
|
244
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { editSummaryWire, revisionBilling } from "./edit-billing.js";
|
|
3
|
+
import { editDocument } from "./edit-document.js";
|
|
4
|
+
import { longFormSlotShotId } from "./edit-long-form.js";
|
|
5
|
+
import { frame, frameCount, shotId } from "./edit-primitives.js";
|
|
6
|
+
import { EDIT_MAX_SHOTS } from "./edit-rules.js";
|
|
7
|
+
import { readResolvedTimeline } from "./resolved-timeline.js";
|
|
8
|
+
import { runId } from "./runs.js";
|
|
9
|
+
import { ASPECT_RATIOS } from "./skills.js";
|
|
10
|
+
// A revision of a long-form run (#604 S7b): the input its admission stores, and the record its render writes.
|
|
11
|
+
/** How a long-form run fills what a picture leaves of the canvas (`makeUgcInput.background`). */
|
|
12
|
+
export const LONG_FORM_BACKGROUNDS = ["white", "blur", "contain"];
|
|
13
|
+
/** A picture's zoom, as `makeUgcInput` takes it. */
|
|
14
|
+
export const longFormImageMotion = z.strictObject({ direction: z.enum(["in", "out"]), amount: z.number().min(0).lt(1) });
|
|
15
|
+
const RATIO_PARTS = { "16:9": [16, 9], "9:16": [9, 16], "1:1": [1, 1] };
|
|
16
|
+
/** What a render needs beyond the timeline, copied from the root's input at admission; a position absent from the motions does not move. */
|
|
17
|
+
export const longFormRevisionRender = z.strictObject({
|
|
18
|
+
aspect_ratio: z.enum(ASPECT_RATIOS), width: frameCount, height: frameCount,
|
|
19
|
+
background: z.enum(LONG_FORM_BACKGROUNDS).nullable(),
|
|
20
|
+
motion_by_position: z.record(z.string().regex(/^[1-9][0-9]{0,3}$/), longFormImageMotion),
|
|
21
|
+
}).refine((render) => render.width * RATIO_PARTS[render.aspect_ratio][1] === render.height * RATIO_PARTS[render.aspect_ratio][0], { message: "the canvas does not have the shape of its aspect ratio" });
|
|
22
|
+
/** The stored input of a `revise_long_form` run: the request as resolved, and what admission froze about it. */
|
|
23
|
+
export const longFormRevisionInput = z.strictObject({
|
|
24
|
+
input_mode: z.literal("revision"),
|
|
25
|
+
revision: z.strictObject({ source_run_id: runId, document: editDocument }),
|
|
26
|
+
resolved_revision: z.strictObject({ root_run_id: runId, summary: editSummaryWire, billing: revisionBilling, render: longFormRevisionRender }),
|
|
27
|
+
});
|
|
28
|
+
const digest = z.string().regex(/^[a-f0-9]{64}$/);
|
|
29
|
+
/** One changed visual shot, drawn above the source tiling over its whole span. A cover has no motion; an insert keeps its slot's. */
|
|
30
|
+
export const longFormOverlay = z.strictObject({
|
|
31
|
+
shot_id: shotId, start_frame: frame, end_frame: frameCount,
|
|
32
|
+
object: z.strictObject({ key: z.string().min(1).max(1024), sha256: digest, bytes: frameCount, width: frameCount, height: frameCount,
|
|
33
|
+
content_type: z.enum(["image/png", "image/jpeg"]) }),
|
|
34
|
+
origin: z.enum(["upload", "source"]),
|
|
35
|
+
motion: longFormImageMotion.nullable(),
|
|
36
|
+
});
|
|
37
|
+
const recordShape = z.strictObject({
|
|
38
|
+
version: z.literal(1),
|
|
39
|
+
run_id: runId, account_id: z.string().min(1).max(200), source_run_id: runId, root_run_id: runId,
|
|
40
|
+
base: z.unknown(),
|
|
41
|
+
visual: z.array(longFormOverlay).max(EDIT_MAX_SHOTS),
|
|
42
|
+
});
|
|
43
|
+
/** Where a long-form revision's record is stored, and the most bytes it may take there. */
|
|
44
|
+
export const longFormRevisionRecordKey = (id) => `runs/${id}/long-form-revision.v1.json`;
|
|
45
|
+
export const LONG_FORM_REVISION_RECORD_MAX_BYTES = 512_000;
|
|
46
|
+
/** Whether a key names an object of this run: a plain path under `runs/<runId>/`, with no segment to climb out by. */
|
|
47
|
+
export function longFormOwnKey(key, id) {
|
|
48
|
+
const prefix = `runs/${id}/`;
|
|
49
|
+
return key.startsWith(prefix) && /^[\w-]+(?:\/[\w-]+)*(?:\.[a-z0-9]+)+$/.test(key.slice(prefix.length));
|
|
50
|
+
}
|
|
51
|
+
/** The stored record of the run being read, checked against that run and against itself: every key and overlay belong to it. */
|
|
52
|
+
export function readLongFormRevisionRecord(stored, expected) {
|
|
53
|
+
const bytes = typeof stored === "string" ? new TextEncoder().encode(stored) : stored;
|
|
54
|
+
if (bytes.length > LONG_FORM_REVISION_RECORD_MAX_BYTES) {
|
|
55
|
+
throw new Error(`invalid long-form revision record: ${bytes.length} bytes, at most ${LONG_FORM_REVISION_RECORD_MAX_BYTES}`);
|
|
56
|
+
}
|
|
57
|
+
const parsed = recordShape.parse(JSON.parse(new TextDecoder().decode(bytes)));
|
|
58
|
+
const base = readResolvedTimeline(parsed.base);
|
|
59
|
+
const record = { ...parsed, base };
|
|
60
|
+
const failures = [];
|
|
61
|
+
if (record.run_id !== expected.runId || record.account_id !== expected.accountId)
|
|
62
|
+
failures.push("the record belongs to another run or account");
|
|
63
|
+
if (record.run_id === record.source_run_id)
|
|
64
|
+
failures.push("the revision names itself as its source");
|
|
65
|
+
if (base.runId !== record.run_id || base.accountId !== record.account_id)
|
|
66
|
+
failures.push("the timeline names another run or account");
|
|
67
|
+
const keys = [...base.slots.flatMap((slot) => (slot.kind === "media" ? [slot.key] : slot.audio ? [slot.audio.key] : [])),
|
|
68
|
+
...(base.narration ? [base.narration.key] : []), ...record.visual.map((overlay) => overlay.object.key)];
|
|
69
|
+
if (!keys.every((key) => longFormOwnKey(key, record.run_id)))
|
|
70
|
+
failures.push("a key leaves the run's prefix");
|
|
71
|
+
const slots = new Map(base.slots.map((slot) => [longFormSlotShotId(slot), slot]));
|
|
72
|
+
const ids = new Set();
|
|
73
|
+
for (const overlay of record.visual) {
|
|
74
|
+
const slot = slots.get(overlay.shot_id);
|
|
75
|
+
if (ids.has(overlay.shot_id))
|
|
76
|
+
failures.push(`two overlays are ${overlay.shot_id}`);
|
|
77
|
+
ids.add(overlay.shot_id);
|
|
78
|
+
if (overlay.end_frame <= overlay.start_frame || overlay.end_frame > base.outputFrames)
|
|
79
|
+
failures.push(`${overlay.shot_id} lies outside the video`);
|
|
80
|
+
if (slot?.kind === "actor")
|
|
81
|
+
failures.push(`${overlay.shot_id} is a presenter take`);
|
|
82
|
+
if (slot?.kind === "media" && slot.mediaType === "video")
|
|
83
|
+
failures.push(`${overlay.shot_id} is a clip`);
|
|
84
|
+
if (!slot && overlay.motion !== null)
|
|
85
|
+
failures.push(`${overlay.shot_id} is a cover and does not move`);
|
|
86
|
+
// No presenter time was recorded under an insert, so its overlay keeps every frame of its slot.
|
|
87
|
+
if (slot?.kind === "media" && (overlay.start_frame > slot.startFrame || overlay.end_frame < slot.endFrame)) {
|
|
88
|
+
failures.push(`${overlay.shot_id} leaves part of its slot uncovered`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const visual = [...base.slots.flatMap((slot) => (slot.kind === "media" && !ids.has(longFormSlotShotId(slot))
|
|
92
|
+
? [{ start: slot.startFrame, end: slot.endFrame }] : [])),
|
|
93
|
+
...record.visual.map((overlay) => ({ start: overlay.start_frame, end: overlay.end_frame }))].sort((a, b) => a.start - b.start);
|
|
94
|
+
let reach = 0;
|
|
95
|
+
for (const span of visual) {
|
|
96
|
+
if (span.start < reach)
|
|
97
|
+
failures.push("two visual shots overlap");
|
|
98
|
+
reach = Math.max(reach, span.end);
|
|
99
|
+
}
|
|
100
|
+
if (failures.length)
|
|
101
|
+
throw new Error(`invalid long-form revision record: ${failures.join("; ")}`);
|
|
102
|
+
return record;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=long-form-revision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"long-form-revision.js","sourceRoot":"","sources":["../src/long-form-revision.ts"],"names":[],"mappings":"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"}
|
package/dist/media-timebase.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export declare const CANVAS_FPS = 25;
|
|
2
2
|
export declare const NARRATION_SAMPLE_RATE = 48000;
|
|
3
|
+
/** A duration in canvas frames, rounded up: one frame too few cuts the end of a line, one too many shows a still frame. */
|
|
4
|
+
export declare function secondsToFrames(seconds: number, fps: number): number;
|
|
5
|
+
/** Count only complete source frames; allocating a speech/image slot uses secondsToFrames instead. */
|
|
6
|
+
export declare function completeFrames(seconds: number, fps: number): number;
|
package/dist/media-timebase.js
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
1
|
export const CANVAS_FPS = 25;
|
|
2
2
|
export const NARRATION_SAMPLE_RATE = 48_000;
|
|
3
|
+
// The composition keeps its own copy of these two (`apps/web/remotion/timeline.ts`): its bundler resolves no other package.
|
|
4
|
+
// `apps/web/remotion/timeline-parity.test.ts` holds the two copies equal.
|
|
5
|
+
/** A duration in canvas frames, rounded up: one frame too few cuts the end of a line, one too many shows a still frame. */
|
|
6
|
+
export function secondsToFrames(seconds, fps) {
|
|
7
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
8
|
+
throw new Error(`secondsToFrames: seconds must be positive, got ${seconds}`);
|
|
9
|
+
}
|
|
10
|
+
const frames = seconds * fps;
|
|
11
|
+
const whole = Math.round(frames);
|
|
12
|
+
// Floating-point multiplication can turn exactly seven frames into 7.000000000000001.
|
|
13
|
+
return whole > 0 && Math.abs(frames - whole) <= Number.EPSILON * Math.max(1, Math.abs(frames))
|
|
14
|
+
? whole : Math.ceil(frames);
|
|
15
|
+
}
|
|
16
|
+
/** Count only complete source frames; allocating a speech/image slot uses secondsToFrames instead. */
|
|
17
|
+
export function completeFrames(seconds, fps) {
|
|
18
|
+
if (!Number.isFinite(seconds) || seconds <= 0 || !Number.isSafeInteger(fps) || fps <= 0) {
|
|
19
|
+
throw new Error("invalid measured duration or frame rate");
|
|
20
|
+
}
|
|
21
|
+
const raw = seconds * fps;
|
|
22
|
+
const frames = Math.floor(raw + Number.EPSILON * Math.max(1, Math.abs(raw)));
|
|
23
|
+
if (!Number.isSafeInteger(frames) || frames < 1)
|
|
24
|
+
throw new Error("source shorter than one frame");
|
|
25
|
+
return frames;
|
|
26
|
+
}
|
|
3
27
|
//# sourceMappingURL=media-timebase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-timebase.js","sourceRoot":"","sources":["../src/media-timebase.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAC7B,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"media-timebase.js","sourceRoot":"","sources":["../src/media-timebase.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAC7B,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,4HAA4H;AAC5H,0EAA0E;AAE1E,2HAA2H;AAC3H,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,GAAW;IAC1D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,kDAAkD,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,GAAG,GAAG,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC,sFAAsF;IACtF,OAAO,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5F,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,GAAW;IACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,GAAG,GAAG,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAClG,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const OUTPUT_PROVENANCE_VERSION = "clipwright-output-marking-v2";
|
|
3
|
+
export declare const OUTPUT_PROVENANCE_WATERMARK_PROFILE = "trustmark-python-0.9.2-q-bch5-strength1";
|
|
4
|
+
export declare const OUTPUT_PROVENANCE_VIDEO_WATERMARK_PROFILE = "trustmark-python-0.9.2-p-bch5-strength1";
|
|
5
|
+
export declare const OUTPUT_PROVENANCE_VIDEO_DETECTOR = "p2-temporal-presence-v1";
|
|
6
|
+
export declare const OUTPUT_PROVENANCE_VIDEO_QUALITY_CONTRACT = "p2-psnr35-human-reviewed-v1";
|
|
7
|
+
export declare const OUTPUT_PROVENANCE_C2PA_VERSION = "0.28.2";
|
|
8
|
+
export declare const OUTPUT_PROVENANCE_PUBLIC_PAYLOAD = "1011011110011000111111000000011111011111011100000110110110111";
|
|
9
|
+
/** INTERNAL server snapshot, never a client authorization or public request schema. */
|
|
10
|
+
export declare const outputProvenancePolicySchema: z.ZodReadonly<z.ZodObject<{
|
|
11
|
+
policy_version: z.ZodLiteral<"clipwright-output-marking-v2">;
|
|
12
|
+
watermark_profile: z.ZodLiteral<"trustmark-python-0.9.2-q-bch5-strength1">;
|
|
13
|
+
video_watermark_profile: z.ZodLiteral<"trustmark-python-0.9.2-p-bch5-strength1">;
|
|
14
|
+
video_detector: z.ZodLiteral<"p2-temporal-presence-v1">;
|
|
15
|
+
video_quality_contract: z.ZodLiteral<"p2-psnr35-human-reviewed-v1">;
|
|
16
|
+
c2pa_version: z.ZodLiteral<"0.28.2">;
|
|
17
|
+
public_payload: z.ZodLiteral<"1011011110011000111111000000011111011111011100000110110110111">;
|
|
18
|
+
visible_ai_label: z.ZodBoolean;
|
|
19
|
+
}, z.core.$strict>>;
|
|
20
|
+
export type OutputProvenancePolicy = z.infer<typeof outputProvenancePolicySchema>;
|
|
21
|
+
/** make_ugc includes long-form presenter video; only these runs default to a label. */
|
|
22
|
+
export declare function createOutputProvenancePolicy(skill: unknown, visibleAiLabel?: unknown): OutputProvenancePolicy;
|
|
23
|
+
/** Both own columns must be explicitly projected; omitted columns are not legacy SQL NULL. */
|
|
24
|
+
export declare function readStoredOutputProvenance(row: unknown): OutputProvenancePolicy | null;
|
|
25
|
+
/** This checks the public namespace, not AI origin/authorship. Malformed output throws. */
|
|
26
|
+
export declare function matchesPublicOutputMarker(nativeTuple: unknown): boolean;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const OUTPUT_PROVENANCE_VERSION = "clipwright-output-marking-v2";
|
|
3
|
+
export const OUTPUT_PROVENANCE_WATERMARK_PROFILE = "trustmark-python-0.9.2-q-bch5-strength1";
|
|
4
|
+
export const OUTPUT_PROVENANCE_VIDEO_WATERMARK_PROFILE = "trustmark-python-0.9.2-p-bch5-strength1";
|
|
5
|
+
export const OUTPUT_PROVENANCE_VIDEO_DETECTOR = "p2-temporal-presence-v1";
|
|
6
|
+
export const OUTPUT_PROVENANCE_VIDEO_QUALITY_CONTRACT = "p2-psnr35-human-reviewed-v1";
|
|
7
|
+
export const OUTPUT_PROVENANCE_C2PA_VERSION = "0.28.2";
|
|
8
|
+
export const OUTPUT_PROVENANCE_PUBLIC_PAYLOAD = "1011011110011000111111000000011111011111011100000110110110111";
|
|
9
|
+
/** INTERNAL server snapshot, never a client authorization or public request schema. */
|
|
10
|
+
export const outputProvenancePolicySchema = z.object({
|
|
11
|
+
policy_version: z.literal(OUTPUT_PROVENANCE_VERSION),
|
|
12
|
+
watermark_profile: z.literal(OUTPUT_PROVENANCE_WATERMARK_PROFILE),
|
|
13
|
+
video_watermark_profile: z.literal(OUTPUT_PROVENANCE_VIDEO_WATERMARK_PROFILE),
|
|
14
|
+
video_detector: z.literal(OUTPUT_PROVENANCE_VIDEO_DETECTOR),
|
|
15
|
+
video_quality_contract: z.literal(OUTPUT_PROVENANCE_VIDEO_QUALITY_CONTRACT),
|
|
16
|
+
c2pa_version: z.literal(OUTPUT_PROVENANCE_C2PA_VERSION),
|
|
17
|
+
public_payload: z.literal(OUTPUT_PROVENANCE_PUBLIC_PAYLOAD),
|
|
18
|
+
visible_ai_label: z.boolean(),
|
|
19
|
+
}).strict().readonly();
|
|
20
|
+
const supportedSkill = z.enum(["make_ugc", "make_faceless", "edit_shot", "create_actor"]);
|
|
21
|
+
/** make_ugc includes long-form presenter video; only these runs default to a label. */
|
|
22
|
+
export function createOutputProvenancePolicy(skill, visibleAiLabel) {
|
|
23
|
+
const lane = supportedSkill.parse(skill);
|
|
24
|
+
const visible = visibleAiLabel === undefined ? lane === "make_ugc" : z.boolean().parse(visibleAiLabel);
|
|
25
|
+
if (visible && lane !== "make_ugc") {
|
|
26
|
+
throw new Error("Visible AI labeling is only supported for make_ugc presenter video");
|
|
27
|
+
}
|
|
28
|
+
return outputProvenancePolicySchema.parse({
|
|
29
|
+
policy_version: OUTPUT_PROVENANCE_VERSION,
|
|
30
|
+
watermark_profile: OUTPUT_PROVENANCE_WATERMARK_PROFILE,
|
|
31
|
+
video_watermark_profile: OUTPUT_PROVENANCE_VIDEO_WATERMARK_PROFILE,
|
|
32
|
+
video_detector: OUTPUT_PROVENANCE_VIDEO_DETECTOR,
|
|
33
|
+
video_quality_contract: OUTPUT_PROVENANCE_VIDEO_QUALITY_CONTRACT,
|
|
34
|
+
c2pa_version: OUTPUT_PROVENANCE_C2PA_VERSION,
|
|
35
|
+
public_payload: OUTPUT_PROVENANCE_PUBLIC_PAYLOAD,
|
|
36
|
+
visible_ai_label: visible,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Both own columns must be explicitly projected; omitted columns are not legacy SQL NULL. */
|
|
40
|
+
export function readStoredOutputProvenance(row) {
|
|
41
|
+
if (row === null || typeof row !== "object" || Array.isArray(row)) {
|
|
42
|
+
throw new TypeError("Output provenance requires a stored run row");
|
|
43
|
+
}
|
|
44
|
+
const raw = row;
|
|
45
|
+
if (!Object.hasOwn(raw, "output_provenance_version") || !Object.hasOwn(raw, "output_provenance")
|
|
46
|
+
|| raw.output_provenance_version === undefined || raw.output_provenance === undefined) {
|
|
47
|
+
throw new Error("Stored output provenance columns were not loaded");
|
|
48
|
+
}
|
|
49
|
+
if (raw.output_provenance_version === null || raw.output_provenance_version === "legacy") {
|
|
50
|
+
if (raw.output_provenance !== null)
|
|
51
|
+
throw new Error("Legacy output provenance must have SQL NULL policy");
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
if (raw.output_provenance_version !== OUTPUT_PROVENANCE_VERSION) {
|
|
55
|
+
throw new Error("Unsupported stored output provenance version");
|
|
56
|
+
}
|
|
57
|
+
return outputProvenancePolicySchema.parse(raw.output_provenance);
|
|
58
|
+
}
|
|
59
|
+
const nativeMarkerTupleSchema = z.tuple([
|
|
60
|
+
z.string().regex(/^[01]*$/), z.boolean(), z.number().int(),
|
|
61
|
+
]);
|
|
62
|
+
/** This checks the public namespace, not AI origin/authorship. Malformed output throws. */
|
|
63
|
+
export function matchesPublicOutputMarker(nativeTuple) {
|
|
64
|
+
const [decoded, present, schema] = nativeMarkerTupleSchema.parse(nativeTuple);
|
|
65
|
+
return present === true && schema === 1 && decoded === OUTPUT_PROVENANCE_PUBLIC_PAYLOAD;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=output-provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-provenance.js","sourceRoot":"","sources":["../src/output-provenance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const contentSchema: z.ZodObject<{
|
|
3
|
+
version: z.ZodLiteral<1>;
|
|
4
|
+
mode: z.ZodEnum<{
|
|
5
|
+
script_inserts: "script_inserts";
|
|
6
|
+
segments: "segments";
|
|
7
|
+
}>;
|
|
8
|
+
runId: z.ZodString;
|
|
9
|
+
accountId: z.ZodString;
|
|
10
|
+
inputHash: z.ZodString;
|
|
11
|
+
fps: z.ZodLiteral<25>;
|
|
12
|
+
outputFrames: z.ZodNumber;
|
|
13
|
+
fullSpeechDurationSec: z.ZodNumber;
|
|
14
|
+
slots: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
15
|
+
position: z.ZodNumber;
|
|
16
|
+
startFrame: z.ZodNumber;
|
|
17
|
+
endFrame: z.ZodNumber;
|
|
18
|
+
kind: z.ZodLiteral<"actor">;
|
|
19
|
+
requestHash: z.ZodString;
|
|
20
|
+
speechDurationSec: z.ZodNumber;
|
|
21
|
+
audio: z.ZodOptional<z.ZodObject<{
|
|
22
|
+
key: z.ZodString;
|
|
23
|
+
sha256: z.ZodString;
|
|
24
|
+
bytes: z.ZodNumber;
|
|
25
|
+
}, z.core.$strict>>;
|
|
26
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
27
|
+
position: z.ZodNumber;
|
|
28
|
+
startFrame: z.ZodNumber;
|
|
29
|
+
endFrame: z.ZodNumber;
|
|
30
|
+
kind: z.ZodLiteral<"media">;
|
|
31
|
+
key: z.ZodString;
|
|
32
|
+
sha256: z.ZodString;
|
|
33
|
+
bytes: z.ZodNumber;
|
|
34
|
+
width: z.ZodNumber;
|
|
35
|
+
height: z.ZodNumber;
|
|
36
|
+
durationSec: z.ZodNumber;
|
|
37
|
+
mediaType: z.ZodEnum<{
|
|
38
|
+
image: "image";
|
|
39
|
+
video: "video";
|
|
40
|
+
}>;
|
|
41
|
+
contentType: z.ZodEnum<{
|
|
42
|
+
"image/jpeg": "image/jpeg";
|
|
43
|
+
"image/png": "image/png";
|
|
44
|
+
"video/mp4": "video/mp4";
|
|
45
|
+
}>;
|
|
46
|
+
insertId: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.core.$strict>], "kind">>;
|
|
48
|
+
warnings: z.ZodArray<z.ZodString>;
|
|
49
|
+
narration: z.ZodOptional<z.ZodObject<{
|
|
50
|
+
key: z.ZodString;
|
|
51
|
+
sha256: z.ZodString;
|
|
52
|
+
bytes: z.ZodNumber;
|
|
53
|
+
alignmentHash: z.ZodString;
|
|
54
|
+
semanticPlan: z.ZodObject<{
|
|
55
|
+
sourceTokens: z.ZodArray<z.ZodString>;
|
|
56
|
+
inserts: z.ZodArray<z.ZodObject<{
|
|
57
|
+
insertId: z.ZodString;
|
|
58
|
+
mediaId: z.ZodString;
|
|
59
|
+
startWord: z.ZodNumber;
|
|
60
|
+
endWord: z.ZodNumber;
|
|
61
|
+
coverWord: z.ZodOptional<z.ZodNumber>;
|
|
62
|
+
}, z.core.$strict>>;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
}, z.core.$strict>>;
|
|
65
|
+
}, z.core.$strict>;
|
|
66
|
+
export type ResolvedTimelineContent = z.infer<typeof contentSchema>;
|
|
67
|
+
export type ResolvedTimeline = ResolvedTimelineContent & {
|
|
68
|
+
hash: string;
|
|
69
|
+
};
|
|
70
|
+
export declare function timelineDigest(value: unknown): string;
|
|
71
|
+
export declare function freezeResolvedTimeline(value: unknown): ResolvedTimeline;
|
|
72
|
+
export declare function readResolvedTimeline(value: unknown): ResolvedTimeline;
|
|
73
|
+
/** The face-billing units of a timeline: each actor slot is one unit whose face shows over its whole interval. */
|
|
74
|
+
export declare function faceBillingUnitsOf(timeline: ResolvedTimelineContent): {
|
|
75
|
+
unitId: string;
|
|
76
|
+
requestHash: string;
|
|
77
|
+
audioDurationSec: number;
|
|
78
|
+
faceIntervals: {
|
|
79
|
+
startFrame: number;
|
|
80
|
+
endFrame: number;
|
|
81
|
+
}[];
|
|
82
|
+
}[];
|
|
83
|
+
/** Where a run's resolved timeline is stored, and the most bytes it may take there. */
|
|
84
|
+
export declare const resolvedTimelineKey: (runId: string) => string;
|
|
85
|
+
export declare const RESOLVED_TIMELINE_MAX_BYTES = 512000;
|
|
86
|
+
export {};
|