@nodaro/shared 2.23.0 → 2.24.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/dist/index.cjs +175 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +331 -1
- package/dist/index.d.ts +331 -1
- package/dist/index.js +175 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/llm-models.test.ts +122 -3
- package/src/__tests__/video-analysis-catalog-sync.test.ts +1 -1
- package/src/__tests__/video-analysis-pricing.test.ts +6 -6
- package/src/index.ts +9 -0
- package/src/llm-models.ts +138 -4
- package/src/model-catalog.ts +30 -30
- package/src/studio-production-wire.ts +344 -0
- package/src/video-analysis-pricing.ts +30 -23
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire contract of `/v1/studio/productions` — TYPES ONLY.
|
|
3
|
+
*
|
|
4
|
+
* A studio production is a Nodaro workflow whose `settings.studio` holds the
|
|
5
|
+
* shots. Its CODE — the codec that reads and writes that document, the plan
|
|
6
|
+
* format, the catalogs and the reducers — lives in `@nodaro/studio-production`,
|
|
7
|
+
* which is FSL-licensed. What lives here is the ENVELOPE the routes return and
|
|
8
|
+
* the bodies they take, because the SDK is typed against this package and an
|
|
9
|
+
* SDK caller has to know the shape of a reply.
|
|
10
|
+
*
|
|
11
|
+
* The document's own sub-objects (the cast, the looks, the scene plan, the
|
|
12
|
+
* cuts) are therefore named JSON aliases rather than re-declared shapes. That
|
|
13
|
+
* is deliberate on both counts:
|
|
14
|
+
*
|
|
15
|
+
* - **Named**, not one anonymous `unknown`, so a `.d.ts` reader can still see
|
|
16
|
+
* which field is which and the SDK's surface documents itself.
|
|
17
|
+
* - **Not re-declared**, because a second definition of the document is exactly
|
|
18
|
+
* the disagreement this contract exists to end — and publishing the studio's
|
|
19
|
+
* domain types under Apache would be an irrevocable grant of code that was
|
|
20
|
+
* deliberately placed one tier down.
|
|
21
|
+
*
|
|
22
|
+
* `@nodaro/studio-production` narrows every one of them to its real type and
|
|
23
|
+
* pins the narrowed view against this one at build time, so the two cannot
|
|
24
|
+
* drift apart in silence. A consumer that wants the narrow types depends on
|
|
25
|
+
* that package; a consumer that only reads the wire uses these.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* How a result is ADDRESSED: its job id when it has one, its url otherwise.
|
|
30
|
+
*
|
|
31
|
+
* Never a position. An index is meaningless the moment another writer inserts
|
|
32
|
+
* a result — and two writers is the normal case here, since an agent and the
|
|
33
|
+
* editor hold the same production open. Uploaded and hand-attached media have
|
|
34
|
+
* no job, which is why the url is the fallback rather than the key.
|
|
35
|
+
*/
|
|
36
|
+
export type ResultKey = string
|
|
37
|
+
|
|
38
|
+
// ── the document's own vocabulary, as JSON ──────────────────────────────────
|
|
39
|
+
// Each alias names the `@nodaro/studio-production` type that defines it.
|
|
40
|
+
|
|
41
|
+
/** `LookSelectionMap` — cinematic picks by dimension key. */
|
|
42
|
+
export type StudioLookMapJson = Record<string, unknown>
|
|
43
|
+
/** `Cast` — the production's roles, keyed by role slug. */
|
|
44
|
+
export type StudioCastJson = Record<string, unknown>
|
|
45
|
+
/** `CastLookMap` — which view of each actor a scene pins. */
|
|
46
|
+
export type StudioCastLookMapJson = Record<string, unknown>
|
|
47
|
+
/** `ProductionFolder` — a named timeline folder. */
|
|
48
|
+
export type StudioFolderJson = Record<string, unknown>
|
|
49
|
+
/** `StoryboardSettings` — the Storyboard tab's persisted state (`brief` lives here). */
|
|
50
|
+
export type StudioStoryboardJson = Record<string, unknown>
|
|
51
|
+
/** `ProductionMusic` — the rendered soundtrack muxed over the export. */
|
|
52
|
+
export type StudioMusicJson = Record<string, unknown>
|
|
53
|
+
/** `PlanMusic` — the soundtrack PLAN (prompt + pickers), kept beside the track. */
|
|
54
|
+
export type StudioMusicPlanJson = Record<string, unknown>
|
|
55
|
+
/** `ProductionCut` — one exported cut of the film. */
|
|
56
|
+
export type StudioCutJson = Record<string, unknown>
|
|
57
|
+
/** `ScenePlan` — a scene's authored framing / motion / voice, before it renders. */
|
|
58
|
+
export type StudioPlanJson = Record<string, unknown>
|
|
59
|
+
/** `ShotBeat` — one timed motion window inside a scene. */
|
|
60
|
+
export type StudioBeatJson = Record<string, unknown>
|
|
61
|
+
/** `ShotTransition` — how a scene's last frames go out. */
|
|
62
|
+
export type StudioTransitionJson = Record<string, unknown>
|
|
63
|
+
/** `ShotVoice` — the scene's generated voiceover. */
|
|
64
|
+
export type StudioVoiceJson = Record<string, unknown>
|
|
65
|
+
/** `DirectionFields` / `SubjectFields` — platform catalog ids carried on a result. */
|
|
66
|
+
export type StudioIdFieldsJson = Record<string, unknown>
|
|
67
|
+
/** `ConnectedReference` — a bound `@`-entity chip. */
|
|
68
|
+
export type StudioReferenceJson = Record<string, unknown>
|
|
69
|
+
/** `TrashedItem` — one deleted shot, still or clip, restorable by id. */
|
|
70
|
+
export type StudioTrashItemJson = Record<string, unknown>
|
|
71
|
+
|
|
72
|
+
// ── results ────────────────────────────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* One generated STILL, with the context that regenerates it.
|
|
76
|
+
*
|
|
77
|
+
* Result histories ACCUMULATE — a generate appends, it never replaces — so a
|
|
78
|
+
* shot's stills are every framing candidate it has ever had, and each one
|
|
79
|
+
* carries what it was made with. That is what makes "go back to the second
|
|
80
|
+
* one" a read rather than a re-run.
|
|
81
|
+
*/
|
|
82
|
+
export interface StudioResultView {
|
|
83
|
+
key: ResultKey
|
|
84
|
+
url: string
|
|
85
|
+
jobId?: string
|
|
86
|
+
name?: string
|
|
87
|
+
prompt?: string
|
|
88
|
+
negativePrompt?: string
|
|
89
|
+
provider?: string
|
|
90
|
+
referenceImageUrls?: string[]
|
|
91
|
+
references?: StudioReferenceJson[]
|
|
92
|
+
aspectRatio?: string
|
|
93
|
+
resolution?: string
|
|
94
|
+
/** The look layers this generation was sent with — film, scene, then the shot's own. */
|
|
95
|
+
filmLook?: StudioLookMapJson
|
|
96
|
+
sceneLook?: StudioLookMapJson
|
|
97
|
+
look?: StudioLookMapJson
|
|
98
|
+
subject?: StudioIdFieldsJson
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* One generated CLIP, with the frames it was animated from.
|
|
103
|
+
*
|
|
104
|
+
* The frames matter more here than they look: selecting a past clip restores
|
|
105
|
+
* the start and end frames THAT clip was made from, which is why they are
|
|
106
|
+
* stored per result rather than read off the shot.
|
|
107
|
+
*/
|
|
108
|
+
export interface StudioClipResultView {
|
|
109
|
+
key: ResultKey
|
|
110
|
+
url: string
|
|
111
|
+
jobId?: string
|
|
112
|
+
name?: string
|
|
113
|
+
prompt?: string
|
|
114
|
+
provider?: string
|
|
115
|
+
negativePrompt?: string
|
|
116
|
+
duration?: number
|
|
117
|
+
/** The frames THIS clip was animated from — restored with it, never derived. */
|
|
118
|
+
startFrameUrl?: string
|
|
119
|
+
endFrameUrl?: string
|
|
120
|
+
referenceImageUrls?: string[]
|
|
121
|
+
references?: StudioReferenceJson[]
|
|
122
|
+
beats?: StudioBeatJson[]
|
|
123
|
+
scenePrompt?: string
|
|
124
|
+
endTransition?: StudioTransitionJson
|
|
125
|
+
filmLook?: StudioLookMapJson
|
|
126
|
+
sceneLook?: StudioLookMapJson
|
|
127
|
+
look?: StudioLookMapJson
|
|
128
|
+
subject?: StudioIdFieldsJson
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* A framing batch that is STILL RUNNING, with everything needed to land it.
|
|
133
|
+
*
|
|
134
|
+
* A marker rather than a promise: any client — or none — can finish the job,
|
|
135
|
+
* because the context that turns a finished job into a result is written down
|
|
136
|
+
* on the production instead of living in the browser tab that started it.
|
|
137
|
+
*/
|
|
138
|
+
export interface PendingStillView {
|
|
139
|
+
jobId: string
|
|
140
|
+
batchId?: string
|
|
141
|
+
provider?: string
|
|
142
|
+
prompt?: string
|
|
143
|
+
count?: number
|
|
144
|
+
startedAt?: string
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** An animate that is still running. The clip mirror of {@link PendingStillView}. */
|
|
148
|
+
export interface PendingClipView {
|
|
149
|
+
jobId: string
|
|
150
|
+
provider?: string
|
|
151
|
+
prompt?: string
|
|
152
|
+
startedAt?: string
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ── the shot ───────────────────────────────────────────────────────────────
|
|
156
|
+
|
|
157
|
+
/** A shot's framed STILL: the active frame, and (at `detail: "full"`) its history. */
|
|
158
|
+
export interface StudioStillView {
|
|
159
|
+
nodeId: string
|
|
160
|
+
provider: string
|
|
161
|
+
prompt: string
|
|
162
|
+
active: ResultKey | null
|
|
163
|
+
activeUrl: string
|
|
164
|
+
count: number
|
|
165
|
+
/** Cinematic direction as PLATFORM catalog ids — never baked hint text. */
|
|
166
|
+
direction?: StudioIdFieldsJson
|
|
167
|
+
subject?: StudioIdFieldsJson
|
|
168
|
+
/** Present only at `detail: "full"` — a list read returns counts, not histories. */
|
|
169
|
+
results?: StudioResultView[]
|
|
170
|
+
pending: PendingStillView[]
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** A shot's animated CLIP. Independent of the still: deleting one never touches the other. */
|
|
174
|
+
export interface StudioClipView {
|
|
175
|
+
nodeId: string
|
|
176
|
+
provider: string
|
|
177
|
+
prompt: string
|
|
178
|
+
duration?: number
|
|
179
|
+
active: ResultKey | null
|
|
180
|
+
activeUrl: string
|
|
181
|
+
count: number
|
|
182
|
+
direction?: StudioIdFieldsJson
|
|
183
|
+
/** The voice this clip was revoiced into, when it was. */
|
|
184
|
+
revoicedVoiceId?: string
|
|
185
|
+
revoicedVoiceName?: string
|
|
186
|
+
/** Present only at `detail: "full"`. */
|
|
187
|
+
results?: StudioClipResultView[]
|
|
188
|
+
pending: PendingClipView[]
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** One shot, in timeline order. */
|
|
192
|
+
export interface StudioShotView {
|
|
193
|
+
id: string
|
|
194
|
+
index: number
|
|
195
|
+
name?: string
|
|
196
|
+
folderId?: string
|
|
197
|
+
still?: StudioStillView
|
|
198
|
+
clip?: StudioClipView
|
|
199
|
+
/** Explicit and sticky: selecting a still never moves them. */
|
|
200
|
+
startFrame?: string
|
|
201
|
+
endFrame?: string
|
|
202
|
+
directingReferences?: {
|
|
203
|
+
images?: string[]
|
|
204
|
+
videos?: string[]
|
|
205
|
+
audio?: string[]
|
|
206
|
+
}
|
|
207
|
+
plan?: StudioPlanJson
|
|
208
|
+
scenePrompt?: string
|
|
209
|
+
beats?: StudioBeatJson[]
|
|
210
|
+
endTransition?: StudioTransitionJson
|
|
211
|
+
look?: StudioLookMapJson
|
|
212
|
+
castLook?: StudioCastLookMapJson
|
|
213
|
+
voice?: StudioVoiceJson
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ── the production ─────────────────────────────────────────────────────────
|
|
217
|
+
|
|
218
|
+
/** What is in flight, at a glance — the reason a `get` can reconcile before it reads. */
|
|
219
|
+
export interface StudioPendingView {
|
|
220
|
+
stills: number
|
|
221
|
+
clips: number
|
|
222
|
+
music: boolean
|
|
223
|
+
draft: { jobId: string; mode: "replace" | "append" } | null
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** The bin: a count always, the items only at `detail: "full"`. */
|
|
227
|
+
export interface StudioTrashView {
|
|
228
|
+
count: number
|
|
229
|
+
items?: StudioTrashItemJson[]
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** The read shape of every `/v1/studio/productions` route and every studio MCP tool. */
|
|
233
|
+
export interface StudioProductionView {
|
|
234
|
+
id: string
|
|
235
|
+
name: string
|
|
236
|
+
version: number
|
|
237
|
+
updatedAt: string
|
|
238
|
+
thumbnailUrl: string | null
|
|
239
|
+
shared: boolean
|
|
240
|
+
archived: boolean
|
|
241
|
+
film?: StudioLookMapJson
|
|
242
|
+
cast?: StudioCastJson
|
|
243
|
+
folders: StudioFolderJson[]
|
|
244
|
+
storyboard?: StudioStoryboardJson
|
|
245
|
+
music?: StudioMusicJson
|
|
246
|
+
musicPlan?: StudioMusicPlanJson
|
|
247
|
+
cuts: StudioCutJson[]
|
|
248
|
+
trash: StudioTrashView
|
|
249
|
+
pending: StudioPendingView
|
|
250
|
+
/** In timeline order. */
|
|
251
|
+
shots: StudioShotView[]
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** A dashboard row — what a list returns, with no shot bodies at all. */
|
|
255
|
+
export interface StudioProductionSummary {
|
|
256
|
+
id: string
|
|
257
|
+
name: string
|
|
258
|
+
version: number
|
|
259
|
+
updatedAt: string
|
|
260
|
+
thumbnailUrl: string | null
|
|
261
|
+
shared: boolean
|
|
262
|
+
archived: boolean
|
|
263
|
+
shotCount: number
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ── request / response bodies ───────────────────────────────────────────────
|
|
267
|
+
// Phase 0's five routes. The operation, generation and lifecycle bodies land
|
|
268
|
+
// with the routes that take them, so this file never describes a route the
|
|
269
|
+
// platform does not serve.
|
|
270
|
+
|
|
271
|
+
/** `GET …/skill` — the authoring skill, rendered from the package at request time. */
|
|
272
|
+
export interface StudioSkillResponse {
|
|
273
|
+
/** SKILL.md — the authoring guide. */
|
|
274
|
+
skill: string
|
|
275
|
+
/** references/catalog.md — every picker, model and enum, in full. */
|
|
276
|
+
catalog: string
|
|
277
|
+
/** schema.json — the strict JSON Schema a plan is validated against. */
|
|
278
|
+
schema: Record<string, unknown>
|
|
279
|
+
/** The operating guide: the tool map, the loops, the rules. */
|
|
280
|
+
operating: string
|
|
281
|
+
/** The catalog versions the three were rendered from. */
|
|
282
|
+
generatedFrom: { prompts: string; shared: string }
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/** One thing wrong with a plan, addressed at the field that is wrong. */
|
|
286
|
+
export interface StudioPlanIssue {
|
|
287
|
+
path: string
|
|
288
|
+
message: string
|
|
289
|
+
hint?: string
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** `POST …/validate` — free, persists nothing, and resolves against the caller's library. */
|
|
293
|
+
export interface StudioValidatePlanRequest {
|
|
294
|
+
plan: Record<string, unknown>
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export interface StudioValidatePlanResponse {
|
|
298
|
+
valid: boolean
|
|
299
|
+
errors: StudioPlanIssue[]
|
|
300
|
+
warnings: StudioPlanIssue[]
|
|
301
|
+
summary?: {
|
|
302
|
+
name?: string
|
|
303
|
+
scenes: number
|
|
304
|
+
shots: number
|
|
305
|
+
cast: number
|
|
306
|
+
/** Cast entries that matched a row in the caller's library. */
|
|
307
|
+
bound: number
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** `GET …?limit&cursor` — the caller's "Studio" project, archived and hidden filtered. */
|
|
312
|
+
export interface StudioListProductionsResponse {
|
|
313
|
+
data: StudioProductionSummary[]
|
|
314
|
+
nextCursor?: string
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** `POST …` — a new production, optionally landed from a plan in the same call. */
|
|
318
|
+
export interface StudioCreateProductionRequest {
|
|
319
|
+
name?: string
|
|
320
|
+
plan?: Record<string, unknown>
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** `POST …/:id/import` — add a plan's scenes to a production that already exists. */
|
|
324
|
+
export interface StudioImportPlanRequest {
|
|
325
|
+
plan: Record<string, unknown>
|
|
326
|
+
mode?: "append"
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/** What an import did, in the words a receipt would use. */
|
|
330
|
+
export interface StudioImportSummary {
|
|
331
|
+
shotsAdded: number
|
|
332
|
+
castEnrolled: number
|
|
333
|
+
/** Cast entries that resolved to a row in the caller's library. */
|
|
334
|
+
castBound: number
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export interface StudioProductionResponse {
|
|
338
|
+
production: StudioProductionView
|
|
339
|
+
warnings?: StudioPlanIssue[]
|
|
340
|
+
summary?: StudioImportSummary
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/** How much of a production a read returns. */
|
|
344
|
+
export type StudioProductionDetail = "summary" | "full"
|
|
@@ -105,39 +105,46 @@ export const VIDEO_ANALYSIS_WINDOW = { LEN: WINDOW_LEN, STRIDE: WINDOW_STRIDE, O
|
|
|
105
105
|
// analysis rows and 6 of 8 audit rows tick up by 1–5 credits (~0.1–0.6%); unlike
|
|
106
106
|
// the 8_482 → 8_706 round, the legacy `gemini-3-flash` family moves too.
|
|
107
107
|
// Output of the plugin's `scripts/gen-va-buckets.mjs`, pasted verbatim.
|
|
108
|
+
//
|
|
109
|
+
// REGENERATED 2026-09-06 — the zoom-through doctrine round (cloud-plugins
|
|
110
|
+
// 0.221.0 → 0.221.7): the analyser's system prompt grew across the day's
|
|
111
|
+
// releases, moving the plugin's system-prompt token pin 9_082 → 9_434. 17 of
|
|
112
|
+
// 20 analysis rows and 6 of 8 audit rows tick up by 1–5 credits (~0.1–0.5%);
|
|
113
|
+
// the legacy `gemini-3-flash` family moves too.
|
|
114
|
+
// Output of the plugin's `scripts/gen-va-buckets.mjs`, pasted verbatim.
|
|
108
115
|
export const VIDEO_ANALYSIS_BUCKET_CREDITS: Record<string, number> = {
|
|
109
116
|
// Legacy fast-tier model (pre-2026-07) — kept for stored raw-id configs.
|
|
110
117
|
"video-analysis:gemini-3-flash:60s": 181,
|
|
111
|
-
"video-analysis:gemini-3-flash:180s":
|
|
112
|
-
"video-analysis:gemini-3-flash:360s":
|
|
113
|
-
"video-analysis:gemini-3-flash:600s":
|
|
118
|
+
"video-analysis:gemini-3-flash:180s": 186,
|
|
119
|
+
"video-analysis:gemini-3-flash:360s": 516,
|
|
120
|
+
"video-analysis:gemini-3-flash:600s": 849,
|
|
114
121
|
// Current fast tier — regenerated from the private formula for its backing
|
|
115
122
|
// model; higher than the legacy fast schedule but still ≤ pro per bucket.
|
|
116
|
-
"video-analysis:gemini-3.6-flash:60s":
|
|
123
|
+
"video-analysis:gemini-3.6-flash:60s": 205,
|
|
117
124
|
"video-analysis:gemini-3.6-flash:180s": 219,
|
|
118
|
-
"video-analysis:gemini-3.6-flash:360s":
|
|
119
|
-
"video-analysis:gemini-3.6-flash:600s":
|
|
120
|
-
"video-analysis:gemini-3.1-pro:60s":
|
|
121
|
-
"video-analysis:gemini-3.1-pro:180s":
|
|
122
|
-
"video-analysis:gemini-3.1-pro:360s":
|
|
123
|
-
"video-analysis:gemini-3.1-pro:600s":
|
|
125
|
+
"video-analysis:gemini-3.6-flash:360s": 603,
|
|
126
|
+
"video-analysis:gemini-3.6-flash:600s": 995,
|
|
127
|
+
"video-analysis:gemini-3.1-pro:60s": 217,
|
|
128
|
+
"video-analysis:gemini-3.1-pro:180s": 233,
|
|
129
|
+
"video-analysis:gemini-3.1-pro:360s": 642,
|
|
130
|
+
"video-analysis:gemini-3.1-pro:600s": 1059,
|
|
124
131
|
// Mixed tiers (`mixed` + `mixed-fast`) share ONE credit family — they are
|
|
125
132
|
// variants of the same engine plan (plan internals live in the private
|
|
126
133
|
// analysis plugin). Admin-tunable via model_pricing like every other row.
|
|
127
134
|
"video-analysis:mixed:60s": 270,
|
|
128
|
-
"video-analysis:mixed:180s":
|
|
129
|
-
"video-analysis:mixed:360s":
|
|
130
|
-
"video-analysis:mixed:600s":
|
|
135
|
+
"video-analysis:mixed:180s": 292,
|
|
136
|
+
"video-analysis:mixed:360s": 731,
|
|
137
|
+
"video-analysis:mixed:600s": 1181,
|
|
131
138
|
// SMART — the accuracy tier, and since the 2026-08-03 re-plan a multi-roll
|
|
132
139
|
// plan like the others, always refined (`selectionMode` does not apply
|
|
133
140
|
// here — smart always refines; it never offers a cheaper "choose" path).
|
|
134
141
|
// Priced above the economy tiers because it genuinely costs more to run;
|
|
135
142
|
// the only tier whose accuracy is validated against a hand-counted edit
|
|
136
143
|
// list, re-validated at the current plan before this schedule shipped.
|
|
137
|
-
"video-analysis:smart:60s":
|
|
138
|
-
"video-analysis:smart:180s":
|
|
139
|
-
"video-analysis:smart:360s":
|
|
140
|
-
"video-analysis:smart:600s":
|
|
144
|
+
"video-analysis:smart:60s": 414,
|
|
145
|
+
"video-analysis:smart:180s": 504,
|
|
146
|
+
"video-analysis:smart:360s": 1270,
|
|
147
|
+
"video-analysis:smart:600s": 2081,
|
|
141
148
|
}
|
|
142
149
|
|
|
143
150
|
/**
|
|
@@ -208,13 +215,13 @@ export function videoAnalysisNumWindows(bucketSec: number): number {
|
|
|
208
215
|
*/
|
|
209
216
|
export const VIDEO_AUDIT_BUCKET_CREDITS: Record<string, number> = {
|
|
210
217
|
"video-audit:60s": 215,
|
|
211
|
-
"video-audit:180s":
|
|
212
|
-
"video-audit:360s":
|
|
213
|
-
"video-audit:600s":
|
|
218
|
+
"video-audit:180s": 291,
|
|
219
|
+
"video-audit:360s": 664,
|
|
220
|
+
"video-audit:600s": 1075,
|
|
214
221
|
"video-audit:auto:60s": 396,
|
|
215
|
-
"video-audit:auto:180s":
|
|
216
|
-
"video-audit:auto:360s":
|
|
217
|
-
"video-audit:auto:600s":
|
|
222
|
+
"video-audit:auto:180s": 477,
|
|
223
|
+
"video-audit:auto:360s": 1180,
|
|
224
|
+
"video-audit:auto:600s": 1924,
|
|
218
225
|
}
|
|
219
226
|
|
|
220
227
|
/**
|