@nodaro/shared 2.23.0 → 2.26.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 +225 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +80 -1
- package/dist/index.d.ts +80 -1
- package/dist/index.js +223 -58
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/llm-models.test.ts +122 -3
- package/src/__tests__/studio-transient.test.ts +205 -0
- 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 +7 -0
- package/src/llm-models.ts +138 -4
- package/src/model-catalog.ts +30 -30
- package/src/studio-transient.ts +124 -0
- package/src/video-analysis-pricing.ts +30 -23
package/src/model-catalog.ts
CHANGED
|
@@ -2176,11 +2176,11 @@ const VIDEO_MODELS: Record<string, ModelCatalogEntry> = {
|
|
|
2176
2176
|
description: "Legacy fast-tier analysis model (pre-2026-07). Kept so stored raw-model configs keep running and keep pricing under their own identifier; new fast-tier runs use the current fast model.",
|
|
2177
2177
|
useCases: ["video-analysis", "shot-list", "fast"],
|
|
2178
2178
|
pricing: [
|
|
2179
|
-
{ identifier: "video-analysis:gemini-3-flash", credits:
|
|
2179
|
+
{ identifier: "video-analysis:gemini-3-flash", credits: 849, note: "10-min ceiling (no duration given)" },
|
|
2180
2180
|
{ identifier: "video-analysis:gemini-3-flash:60s", credits: 181 },
|
|
2181
|
-
{ identifier: "video-analysis:gemini-3-flash:180s", credits:
|
|
2182
|
-
{ identifier: "video-analysis:gemini-3-flash:360s", credits:
|
|
2183
|
-
{ identifier: "video-analysis:gemini-3-flash:600s", credits:
|
|
2181
|
+
{ identifier: "video-analysis:gemini-3-flash:180s", credits: 186 },
|
|
2182
|
+
{ identifier: "video-analysis:gemini-3-flash:360s", credits: 516 },
|
|
2183
|
+
{ identifier: "video-analysis:gemini-3-flash:600s", credits: 849, note: "10-min ceiling" },
|
|
2184
2184
|
],
|
|
2185
2185
|
},
|
|
2186
2186
|
"gemini-3.6-flash-video-analysis": {
|
|
@@ -2193,11 +2193,11 @@ const VIDEO_MODELS: Record<string, ModelCatalogEntry> = {
|
|
|
2193
2193
|
description: "Analyze a video into a structured shot list (scenes, camera, audio) — fast, economy tier. Billed per duration bucket.",
|
|
2194
2194
|
useCases: ["video-analysis", "shot-list", "fast"],
|
|
2195
2195
|
pricing: [
|
|
2196
|
-
{ identifier: "video-analysis:gemini-3.6-flash", credits:
|
|
2197
|
-
{ identifier: "video-analysis:gemini-3.6-flash:60s", credits:
|
|
2196
|
+
{ identifier: "video-analysis:gemini-3.6-flash", credits: 995, note: "10-min ceiling (no duration given)" },
|
|
2197
|
+
{ identifier: "video-analysis:gemini-3.6-flash:60s", credits: 205 },
|
|
2198
2198
|
{ identifier: "video-analysis:gemini-3.6-flash:180s", credits: 219 },
|
|
2199
|
-
{ identifier: "video-analysis:gemini-3.6-flash:360s", credits:
|
|
2200
|
-
{ identifier: "video-analysis:gemini-3.6-flash:600s", credits:
|
|
2199
|
+
{ identifier: "video-analysis:gemini-3.6-flash:360s", credits: 603 },
|
|
2200
|
+
{ identifier: "video-analysis:gemini-3.6-flash:600s", credits: 995, note: "10-min ceiling" },
|
|
2201
2201
|
],
|
|
2202
2202
|
},
|
|
2203
2203
|
"gemini-3.1-pro-video-analysis": {
|
|
@@ -2210,11 +2210,11 @@ const VIDEO_MODELS: Record<string, ModelCatalogEntry> = {
|
|
|
2210
2210
|
description: "Analyze a video into a structured shot list (scenes, camera, audio) — higher-fidelity, default tier. Billed per duration bucket.",
|
|
2211
2211
|
useCases: ["video-analysis", "shot-list", "cinematic"],
|
|
2212
2212
|
pricing: [
|
|
2213
|
-
{ identifier: "video-analysis:gemini-3.1-pro", credits:
|
|
2214
|
-
{ identifier: "video-analysis:gemini-3.1-pro:60s", credits:
|
|
2215
|
-
{ identifier: "video-analysis:gemini-3.1-pro:180s", credits:
|
|
2216
|
-
{ identifier: "video-analysis:gemini-3.1-pro:360s", credits:
|
|
2217
|
-
{ identifier: "video-analysis:gemini-3.1-pro:600s", credits:
|
|
2213
|
+
{ identifier: "video-analysis:gemini-3.1-pro", credits: 1059, note: "10-min ceiling (no duration given)" },
|
|
2214
|
+
{ identifier: "video-analysis:gemini-3.1-pro:60s", credits: 217 },
|
|
2215
|
+
{ identifier: "video-analysis:gemini-3.1-pro:180s", credits: 233 },
|
|
2216
|
+
{ identifier: "video-analysis:gemini-3.1-pro:360s", credits: 642 },
|
|
2217
|
+
{ identifier: "video-analysis:gemini-3.1-pro:600s", credits: 1059, note: "10-min ceiling" },
|
|
2218
2218
|
],
|
|
2219
2219
|
},
|
|
2220
2220
|
// Both mixed tiers are variants of the same advanced multi-engine analysis
|
|
@@ -2230,11 +2230,11 @@ const VIDEO_MODELS: Record<string, ModelCatalogEntry> = {
|
|
|
2230
2230
|
description: "Our most advanced analysis tier — multiple analysis engines combined into one result for maximum completeness and accuracy. Billed per duration bucket.",
|
|
2231
2231
|
useCases: ["video-analysis", "shot-list", "premium", "most-complete"],
|
|
2232
2232
|
pricing: [
|
|
2233
|
-
{ identifier: "video-analysis:mixed", credits:
|
|
2233
|
+
{ identifier: "video-analysis:mixed", credits: 1181, note: "10-min ceiling (no duration given)" },
|
|
2234
2234
|
{ identifier: "video-analysis:mixed:60s", credits: 270 },
|
|
2235
|
-
{ identifier: "video-analysis:mixed:180s", credits:
|
|
2236
|
-
{ identifier: "video-analysis:mixed:360s", credits:
|
|
2237
|
-
{ identifier: "video-analysis:mixed:600s", credits:
|
|
2235
|
+
{ identifier: "video-analysis:mixed:180s", credits: 292 },
|
|
2236
|
+
{ identifier: "video-analysis:mixed:360s", credits: 731 },
|
|
2237
|
+
{ identifier: "video-analysis:mixed:600s", credits: 1181, note: "10-min ceiling" },
|
|
2238
2238
|
],
|
|
2239
2239
|
},
|
|
2240
2240
|
// SMART — the accuracy tier. Since the 2026-08-03 hybrid re-plan it is a
|
|
@@ -2252,11 +2252,11 @@ const VIDEO_MODELS: Record<string, ModelCatalogEntry> = {
|
|
|
2252
2252
|
description: "Highest-accuracy analysis — a hybrid pass that blends a native skeleton read with several donor analysis rolls, then always refines the merged result to find shot boundaries and identify the cast by appearance. Best choice when the shot list will drive regeneration. Billed per duration bucket.",
|
|
2253
2253
|
useCases: ["video-analysis", "shot-list", "premium", "most-accurate"],
|
|
2254
2254
|
pricing: [
|
|
2255
|
-
{ identifier: "video-analysis:smart", credits:
|
|
2256
|
-
{ identifier: "video-analysis:smart:60s", credits:
|
|
2257
|
-
{ identifier: "video-analysis:smart:180s", credits:
|
|
2258
|
-
{ identifier: "video-analysis:smart:360s", credits:
|
|
2259
|
-
{ identifier: "video-analysis:smart:600s", credits:
|
|
2255
|
+
{ identifier: "video-analysis:smart", credits: 2081, note: "10-min ceiling (no duration given)" },
|
|
2256
|
+
{ identifier: "video-analysis:smart:60s", credits: 414 },
|
|
2257
|
+
{ identifier: "video-analysis:smart:180s", credits: 504 },
|
|
2258
|
+
{ identifier: "video-analysis:smart:360s", credits: 1270 },
|
|
2259
|
+
{ identifier: "video-analysis:smart:600s", credits: 2081, note: "10-min ceiling" },
|
|
2260
2260
|
],
|
|
2261
2261
|
},
|
|
2262
2262
|
// ── AI Audit (`video-audit`) ── a SEPARATE node from video-analysis (own
|
|
@@ -2280,11 +2280,11 @@ const VIDEO_MODELS: Record<string, ModelCatalogEntry> = {
|
|
|
2280
2280
|
description: "Re-watches a clip against a wired analysis, applies video-verified corrections under guards, and returns a disclosed report of what changed. Billed per duration bucket.",
|
|
2281
2281
|
useCases: ["video-audit", "qa", "shot-list", "verification"],
|
|
2282
2282
|
pricing: [
|
|
2283
|
-
{ identifier: "video-audit", credits:
|
|
2283
|
+
{ identifier: "video-audit", credits: 1075, note: "10-min ceiling (no duration given)" },
|
|
2284
2284
|
{ identifier: "video-audit:60s", credits: 215 },
|
|
2285
|
-
{ identifier: "video-audit:180s", credits:
|
|
2286
|
-
{ identifier: "video-audit:360s", credits:
|
|
2287
|
-
{ identifier: "video-audit:600s", credits:
|
|
2285
|
+
{ identifier: "video-audit:180s", credits: 291 },
|
|
2286
|
+
{ identifier: "video-audit:360s", credits: 664 },
|
|
2287
|
+
{ identifier: "video-audit:600s", credits: 1075, note: "10-min ceiling" },
|
|
2288
2288
|
],
|
|
2289
2289
|
},
|
|
2290
2290
|
"video-audit-auto": {
|
|
@@ -2296,11 +2296,11 @@ const VIDEO_MODELS: Record<string, ModelCatalogEntry> = {
|
|
|
2296
2296
|
description: "Same video-verified audit as AI Audit, but auto-runs a fast analysis first when none is wired in, then applies corrections under guards and returns a disclosed report. Billed per duration bucket.",
|
|
2297
2297
|
useCases: ["video-audit", "qa", "shot-list", "verification", "auto-analysis"],
|
|
2298
2298
|
pricing: [
|
|
2299
|
-
{ identifier: "video-audit:auto", credits:
|
|
2299
|
+
{ identifier: "video-audit:auto", credits: 1924, note: "10-min ceiling (no duration given)" },
|
|
2300
2300
|
{ identifier: "video-audit:auto:60s", credits: 396 },
|
|
2301
|
-
{ identifier: "video-audit:auto:180s", credits:
|
|
2302
|
-
{ identifier: "video-audit:auto:360s", credits:
|
|
2303
|
-
{ identifier: "video-audit:auto:600s", credits:
|
|
2301
|
+
{ identifier: "video-audit:auto:180s", credits: 477 },
|
|
2302
|
+
{ identifier: "video-audit:auto:360s", credits: 1180 },
|
|
2303
|
+
{ identifier: "video-audit:auto:600s", credits: 1924, note: "10-min ceiling" },
|
|
2304
2304
|
],
|
|
2305
2305
|
},
|
|
2306
2306
|
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parts of `settings.studio` that must not leave the owner's account.
|
|
3
|
+
*
|
|
4
|
+
* A shared production is read by anyone with the link. Three things inside the
|
|
5
|
+
* document are the OWNER'S working state and nobody else's business:
|
|
6
|
+
*
|
|
7
|
+
* - `trash` — the recycle bin, which holds every shot, still and clip they
|
|
8
|
+
* deleted, with prompts and urls intact. A share viewer receiving the bin is
|
|
9
|
+
* the sharpest of the three: it hands out work the owner explicitly threw away.
|
|
10
|
+
* - the in-flight job markers — `pendingClips` / `pendingStills` per shot, and
|
|
11
|
+
* `pendingMusic` / `pendingDraft` on the document. A viewer cannot land any
|
|
12
|
+
* of them and does not own them; all they carry across is job ids.
|
|
13
|
+
* - `freecutDraftUrl` — an unsaved editor draft.
|
|
14
|
+
*
|
|
15
|
+
* They do NOT all live at the same level, and that is the whole reason this
|
|
16
|
+
* file exists rather than one array: the writer puts `trash` and
|
|
17
|
+
* `freecutDraftUrl` on `settings.studio` itself, and puts the per-shot markers
|
|
18
|
+
* on the `settings.studio.shots[]` entry. A strip that walked only the top
|
|
19
|
+
* level would pass its own test and still hand a share viewer every marker in
|
|
20
|
+
* the production.
|
|
21
|
+
*
|
|
22
|
+
* It lives in `@nodaro/shared` because two independent readers need the SAME
|
|
23
|
+
* list: the public share read (which is the reason the list exists) and the
|
|
24
|
+
* production writer's own bundle projection. A second copy of a list like this
|
|
25
|
+
* does not stay equal — it goes one key stale and the stale side is the one
|
|
26
|
+
* that publishes.
|
|
27
|
+
*
|
|
28
|
+
* This is a plain JSON walker on purpose. `settings` is a free-form column that
|
|
29
|
+
* a client owns end to end; the projection reads the keys it must drop and
|
|
30
|
+
* nothing else, so it never needs — and must never grow — a dependency on
|
|
31
|
+
* whatever writes the rest of the document.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `settings.studio`'s OWN transient keys.
|
|
36
|
+
*
|
|
37
|
+
* The per-shot pending lists are on this list as well as the shot one on
|
|
38
|
+
* purpose: nothing writes them here today, and a stray one from an older
|
|
39
|
+
* client — or from a client that is not the studio editor at all — still must
|
|
40
|
+
* not ride out to a viewer.
|
|
41
|
+
*/
|
|
42
|
+
export const STUDIO_TRANSIENT_KEYS = [
|
|
43
|
+
"trash",
|
|
44
|
+
"pendingStills",
|
|
45
|
+
"pendingClips",
|
|
46
|
+
// The two markers that genuinely DO live at this level: a soundtrack render
|
|
47
|
+
// and a story-planning run in flight. Same rule as the per-shot pair — they
|
|
48
|
+
// name jobs on the owner's account and nobody else can land them.
|
|
49
|
+
"pendingMusic",
|
|
50
|
+
"pendingDraft",
|
|
51
|
+
"freecutDraftUrl",
|
|
52
|
+
] as const
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* ...and a SHOT entry's, which is where the per-shot markers actually are.
|
|
56
|
+
*
|
|
57
|
+
* `pendingClip` (singular) is the pre-concurrent-markers shape; the editor's
|
|
58
|
+
* reader still migrates it on parse, so a row can still be carrying one and it
|
|
59
|
+
* is still in-flight state.
|
|
60
|
+
*/
|
|
61
|
+
export const STUDIO_SHOT_TRANSIENT_KEYS = ["pendingClips", "pendingClip", "pendingStills"] as const
|
|
62
|
+
|
|
63
|
+
function withoutKeys(
|
|
64
|
+
source: Record<string, unknown>,
|
|
65
|
+
drop: ReadonlyArray<string>,
|
|
66
|
+
): Record<string, unknown> {
|
|
67
|
+
const kept: Record<string, unknown> = {}
|
|
68
|
+
for (const [key, value] of Object.entries(source)) {
|
|
69
|
+
if (drop.includes(key)) continue
|
|
70
|
+
kept[key] = value
|
|
71
|
+
}
|
|
72
|
+
return kept
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* `settings.studio.shots` with every shot's in-flight markers removed.
|
|
77
|
+
*
|
|
78
|
+
* Returns the SAME array when no shot carried one, so an idle production's
|
|
79
|
+
* share read allocates nothing. Anything that is not a shot-shaped object rides
|
|
80
|
+
* through untouched: this runs on whatever is in the column, and a projection
|
|
81
|
+
* that threw on an unexpected row would take the share read down with it.
|
|
82
|
+
*/
|
|
83
|
+
function stripShots(value: unknown): unknown {
|
|
84
|
+
if (!Array.isArray(value)) return value
|
|
85
|
+
let changed = false
|
|
86
|
+
const out = value.map((entry) => {
|
|
87
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry
|
|
88
|
+
const shot = entry as Record<string, unknown>
|
|
89
|
+
if (!STUDIO_SHOT_TRANSIENT_KEYS.some((key) => key in shot)) return entry
|
|
90
|
+
changed = true
|
|
91
|
+
return withoutKeys(shot, STUDIO_SHOT_TRANSIENT_KEYS)
|
|
92
|
+
})
|
|
93
|
+
return changed ? out : value
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* A production's `settings` with the owner's working state removed.
|
|
98
|
+
*
|
|
99
|
+
* Copy-on-write, and structurally: it rebuilds the objects without those keys
|
|
100
|
+
* rather than deleting from the caller's, so the stored row is untouched. A
|
|
101
|
+
* `settings` with no `studio` comes back unchanged — this is a studio concern,
|
|
102
|
+
* and a workflow that is not a production has nothing here to strip.
|
|
103
|
+
*
|
|
104
|
+
* Takes and returns `unknown` because the column is free-form and every caller
|
|
105
|
+
* already holds it as whatever its own layer calls JSON; narrowing here would
|
|
106
|
+
* only move the cast one line up.
|
|
107
|
+
*/
|
|
108
|
+
export function stripStudioTransientSettings(settings: unknown): unknown {
|
|
109
|
+
if (!settings || typeof settings !== "object") return settings
|
|
110
|
+
const studio = (settings as { studio?: unknown }).studio
|
|
111
|
+
if (!studio || typeof studio !== "object" || Array.isArray(studio)) return settings
|
|
112
|
+
|
|
113
|
+
const source = studio as Record<string, unknown>
|
|
114
|
+
const kept = withoutKeys(source, STUDIO_TRANSIENT_KEYS)
|
|
115
|
+
const shots = stripShots(source.shots)
|
|
116
|
+
if (source.shots !== undefined) kept.shots = shots
|
|
117
|
+
|
|
118
|
+
// Nothing to drop at either level — hand back the original object so an
|
|
119
|
+
// ordinary share read allocates nothing.
|
|
120
|
+
if (Object.keys(kept).length === Object.keys(source).length && shots === source.shots) {
|
|
121
|
+
return settings
|
|
122
|
+
}
|
|
123
|
+
return { ...(settings as Record<string, unknown>), studio: kept }
|
|
124
|
+
}
|
|
@@ -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
|
/**
|