@skyphusion-labs/vivijure-core 1.24.0 → 1.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/beat-analyze.d.ts +5 -1
- package/dist/beat-analyze.d.ts.map +1 -1
- package/dist/beat-analyze.js +56 -15
- package/dist/beat-analyze.js.map +1 -1
- package/dist/clip-content-validate.d.ts +39 -3
- package/dist/clip-content-validate.d.ts.map +1 -1
- package/dist/clip-content-validate.js +96 -9
- package/dist/clip-content-validate.js.map +1 -1
- package/dist/clip-job-model.d.ts +18 -0
- package/dist/clip-job-model.d.ts.map +1 -1
- package/dist/clip-job-model.js.map +1 -1
- package/dist/clip-validate.d.ts +19 -0
- package/dist/clip-validate.d.ts.map +1 -1
- package/dist/clip-validate.js +112 -14
- package/dist/clip-validate.js.map +1 -1
- package/dist/film-model.d.ts +79 -3
- package/dist/film-model.d.ts.map +1 -1
- package/dist/film-model.js +88 -2
- package/dist/film-model.js.map +1 -1
- package/dist/film-orchestrator.d.ts +20 -1
- package/dist/film-orchestrator.d.ts.map +1 -1
- package/dist/film-orchestrator.js +262 -88
- package/dist/film-orchestrator.js.map +1 -1
- package/dist/film-output-key.d.ts +26 -1
- package/dist/film-output-key.d.ts.map +1 -1
- package/dist/film-output-key.js +33 -6
- package/dist/film-output-key.js.map +1 -1
- package/dist/modules/types.d.ts +8 -6
- package/dist/modules/types.d.ts.map +1 -1
- package/dist/render-orchestrator.d.ts +2 -1
- package/dist/render-orchestrator.d.ts.map +1 -1
- package/dist/render-orchestrator.js +21 -3
- package/dist/render-orchestrator.js.map +1 -1
- package/dist/render-output-payload.d.ts.map +1 -1
- package/dist/render-output-payload.js +31 -7
- package/dist/render-output-payload.js.map +1 -1
- package/dist/runpod-job-log.d.ts.map +1 -1
- package/dist/runpod-job-log.js +26 -2
- package/dist/runpod-job-log.js.map +1 -1
- package/dist/scatter-orchestrator-types.d.ts +0 -1
- package/dist/scatter-orchestrator-types.d.ts.map +1 -1
- package/dist/scatter-orchestrator.js +2 -2
- package/dist/scatter-orchestrator.js.map +1 -1
- package/dist/video-finish-assemble.d.ts +9 -5
- package/dist/video-finish-assemble.d.ts.map +1 -1
- package/dist/video-finish-assemble.js +43 -26
- package/dist/video-finish-assemble.js.map +1 -1
- package/package.json +4 -3
package/dist/beat-analyze.d.ts
CHANGED
|
@@ -16,7 +16,11 @@ export type BeatAnalyzeResult = {
|
|
|
16
16
|
} | {
|
|
17
17
|
ok: false;
|
|
18
18
|
error: string;
|
|
19
|
+
transient: boolean;
|
|
19
20
|
};
|
|
20
|
-
export declare function analyzeAudioBeats(env: Env, req: AudioAnalyzeRequest, moduleName?: string, preModules?: RegisteredModule[]
|
|
21
|
+
export declare function analyzeAudioBeats(env: Env, req: AudioAnalyzeRequest, moduleName?: string, preModules?: RegisteredModule[], context?: {
|
|
22
|
+
job_id: string;
|
|
23
|
+
project: string;
|
|
24
|
+
}): Promise<BeatAnalyzeResult>;
|
|
21
25
|
export {};
|
|
22
26
|
//# sourceMappingURL=beat-analyze.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beat-analyze.d.ts","sourceRoot":"","sources":["../src/beat-analyze.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oCAAoC,CAAC;AAS9D,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAC;AAM5B,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAIpF;AAgBD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,GAAG,IAAI,CAI9G;
|
|
1
|
+
{"version":3,"file":"beat-analyze.d.ts","sourceRoot":"","sources":["../src/beat-analyze.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oCAAoC,CAAC;AAS9D,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAEnB,MAAM,oBAAoB,CAAC;AAM5B,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAIpF;AAgBD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,GAAG,IAAI,CAI9G;AAqED,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAErD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,mBAAmB,EACxB,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,gBAAgB,EAAE,EAC/B,OAAO,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAAC,iBAAiB,CAAC,CA2D5B"}
|
package/dist/beat-analyze.js
CHANGED
|
@@ -42,6 +42,18 @@ function userConfigFromRequest(req) {
|
|
|
42
42
|
out.force_shots = req.forceShots;
|
|
43
43
|
return out;
|
|
44
44
|
}
|
|
45
|
+
/** Transport outcome first, content second.
|
|
46
|
+
*
|
|
47
|
+
* The caller (failIfSongBeatsUnread) FAILS a paid film on a permanent miss, so this door has to
|
|
48
|
+
* say which kind of miss it had. A door that is unset, or set with no bearer, is host
|
|
49
|
+
* configuration and never improves by retrying: permanent. A non-2xx status, a body that will not
|
|
50
|
+
* parse, and a fetch that rejects are all the container being down, restarting, overloaded or
|
|
51
|
+
* behind an edge error page: transient. Only a 200 whose body parses and is not a plan is the
|
|
52
|
+
* analyzer ANSWERING with something unusable, which is permanent (the #245/#249 distinction).
|
|
53
|
+
*
|
|
54
|
+
* The two shapes this corrects: a 502 carrying a JSON body read as an unrecognized plan, and a
|
|
55
|
+
* 502 carrying an HTML body THREW out of resp.json() and past the caller attempt counter
|
|
56
|
+
* entirely, so the cap never engaged on that shape at all. Both retry now. */
|
|
45
57
|
async function analyzeViaUrl(env, audioUrl, req) {
|
|
46
58
|
let resp;
|
|
47
59
|
try {
|
|
@@ -61,59 +73,88 @@ async function analyzeViaUrl(env, audioUrl, req) {
|
|
|
61
73
|
}
|
|
62
74
|
catch (e) {
|
|
63
75
|
if (isMediaFinishAuthError(e))
|
|
64
|
-
return { ok: false, error: e.message };
|
|
65
|
-
|
|
76
|
+
return { ok: false, error: e.message, transient: false };
|
|
77
|
+
// A rejected fetch is the dead-origin shape (NXDOMAIN, connection reset). It is REPORTED, not
|
|
78
|
+
// rethrown: the caller counts attempts off the return value, and a throw skips that counter.
|
|
79
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
80
|
+
return { ok: false, error: "beat-sync door unreachable: " + msg.slice(0, 200), transient: true };
|
|
66
81
|
}
|
|
67
82
|
if (!resp)
|
|
68
|
-
return { ok: false, error: "AUDIO_BEAT_SYNC_URL unset" };
|
|
69
|
-
|
|
83
|
+
return { ok: false, error: "AUDIO_BEAT_SYNC_URL unset", transient: false };
|
|
84
|
+
if (!resp.ok)
|
|
85
|
+
return { ok: false, error: `beat-sync container returned HTTP ${resp.status}`, transient: true };
|
|
86
|
+
let body;
|
|
87
|
+
try {
|
|
88
|
+
body = await resp.json();
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
92
|
+
return {
|
|
93
|
+
ok: false,
|
|
94
|
+
error: "beat-sync container returned an unreadable body: " + msg.slice(0, 200),
|
|
95
|
+
transient: true,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const plan = parseAudioBeatPlan(body);
|
|
70
99
|
if (!plan)
|
|
71
|
-
return { ok: false, error: "beat-sync container returned an unrecognized plan" };
|
|
100
|
+
return { ok: false, error: "beat-sync container returned an unrecognized plan", transient: false };
|
|
72
101
|
return { ok: true, plan };
|
|
73
102
|
}
|
|
74
|
-
export async function analyzeAudioBeats(env, req, moduleName, preModules) {
|
|
103
|
+
export async function analyzeAudioBeats(env, req, moduleName, preModules, context) {
|
|
75
104
|
const audioKey = req.audioKey?.trim();
|
|
76
105
|
if (!audioKey)
|
|
77
|
-
return { ok: false, error: "audioKey required" };
|
|
106
|
+
return { ok: false, error: "audioKey required", transient: false };
|
|
78
107
|
let audioUrl;
|
|
79
108
|
try {
|
|
80
109
|
audioUrl = await presignR2Get(env, audioKey, 300);
|
|
81
110
|
}
|
|
82
111
|
catch (e) {
|
|
83
112
|
const msg = e instanceof Error ? e.message : String(e);
|
|
84
|
-
return { ok: false, error: "could not presign audio: " + msg.slice(0, 200) };
|
|
113
|
+
return { ok: false, error: "could not presign audio: " + msg.slice(0, 200), transient: true };
|
|
85
114
|
}
|
|
86
115
|
const modules = preModules ?? await discoverModules(env);
|
|
87
116
|
const mod = resolveBeatSyncModule(modules, moduleName?.trim() || undefined);
|
|
88
117
|
if (mod) {
|
|
89
118
|
const fetcher = fetcherForModule(env, mod);
|
|
90
119
|
if (!fetcher) {
|
|
91
|
-
return {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
error: `beat-sync module "${mod.name}" binding ${mod.binding} is not reachable`,
|
|
123
|
+
transient: false,
|
|
124
|
+
};
|
|
92
125
|
}
|
|
93
126
|
const config = {
|
|
94
127
|
...validateConfig(mod.config_schema, userConfigFromRequest(req)),
|
|
95
128
|
audio_url: audioUrl,
|
|
96
129
|
audio_key: audioKey,
|
|
97
130
|
};
|
|
131
|
+
// A film passes its own ids. The planner sentinel stays only when no film context is given,
|
|
132
|
+
// so a film's beat read is not accounted as a planner job.
|
|
133
|
+
const accounted = context
|
|
134
|
+
? { job_id: context.job_id, project: context.project }
|
|
135
|
+
: { job_id: crypto.randomUUID(), project: "planner" };
|
|
136
|
+
const filmKey = context ? `beat-analyze/${context.job_id}` : "beat-analyze/planner";
|
|
98
137
|
const r = await invokeModule(fetcher, {
|
|
99
138
|
hook: "score",
|
|
100
|
-
input: { film_key:
|
|
139
|
+
input: { film_key: filmKey, seconds: 0 },
|
|
101
140
|
config,
|
|
102
|
-
context:
|
|
141
|
+
context: accounted,
|
|
103
142
|
});
|
|
143
|
+
// transient is the invoke result, not a substring of r.error. A module error string
|
|
144
|
+
// does not have to contain "invoke failed".
|
|
104
145
|
if (!r.ok)
|
|
105
|
-
return { ok: false, error: r.error || `${mod.name} invoke failed
|
|
146
|
+
return { ok: false, error: r.error || `${mod.name} invoke failed`, transient: true };
|
|
106
147
|
if (!("output" in r)) {
|
|
107
|
-
return { ok: false, error: `${mod.name} returned async poll (beat analysis is synchronous)
|
|
148
|
+
return { ok: false, error: `${mod.name} returned async poll (beat analysis is synchronous)`, transient: false };
|
|
108
149
|
}
|
|
109
150
|
const plan = beatPlanFromModuleOutput(r.output);
|
|
110
151
|
if (!plan)
|
|
111
|
-
return { ok: false, error: `${mod.name} finished but returned no beat plan
|
|
152
|
+
return { ok: false, error: `${mod.name} finished but returned no beat plan`, transient: false };
|
|
112
153
|
return { ok: true, plan, module: mod.name };
|
|
113
154
|
}
|
|
114
155
|
const direct = await analyzeViaUrl(env, audioUrl, req);
|
|
115
156
|
if (!direct.ok)
|
|
116
|
-
return direct;
|
|
157
|
+
return { ok: false, error: direct.error, transient: direct.transient };
|
|
117
158
|
return { ok: true, plan: direct.plan, module: "core-url" };
|
|
118
159
|
}
|
|
119
160
|
//# sourceMappingURL=beat-analyze.js.map
|
package/dist/beat-analyze.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beat-analyze.js","sourceRoot":"","sources":["../src/beat-analyze.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"beat-analyze.js","sourceRoot":"","sources":["../src/beat-analyze.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,17 +15,38 @@ export interface InspectResult {
|
|
|
15
15
|
error?: string;
|
|
16
16
|
}
|
|
17
17
|
/** Call the video-finish container's POST /inspect, retrying the transient gateway statuses (503/504) the
|
|
18
|
-
* way callVideoFinish does for /finish. backoffMs is injectable so tests do not wait.
|
|
19
|
-
*
|
|
18
|
+
* way callVideoFinish does for /finish. backoffMs is injectable so tests do not wait.
|
|
19
|
+
*
|
|
20
|
+
* Returns the parsed result, or an UNREACHABLE marker the caller can act on (core#321). The
|
|
21
|
+
* distinction is not cosmetic: contentValidateDoneClips walks shots SEQUENTIALLY, so a container
|
|
22
|
+
* that is down costs its whole retry budget once per shot.
|
|
23
|
+
*
|
|
24
|
+
* A THROWN fetch (NXDOMAIN, connection refused, a container that died before binding 8000, which is
|
|
25
|
+
* cf#851's exact signature) is NOT the gateway-busy condition the backoff was written for, and one
|
|
26
|
+
* attempt establishes it. It used to retry anyway, because the loop's break tested
|
|
27
|
+
* `resp && resp.status !== 503 ...` and a throw leaves resp null, which is falsy, which is not a
|
|
28
|
+
* break. Three attempts at 1500ms, per shot, sequentially: about 3s a shot, roughly 51s of a finish
|
|
29
|
+
* pass on a 17-shot film, re-paid on later ticks because core#30 says not to persist the skip.
|
|
30
|
+
*
|
|
31
|
+
* The 503/504 retry is UNCHANGED and deliberately so: that one is the container saying "busy, come
|
|
32
|
+
* back", and cutting it would trade this latency problem for a coverage problem, i.e. more false
|
|
33
|
+
* `unmeasured` records, which is the state cf#856 exists to make visible. */
|
|
20
34
|
export declare function callVideoFinishInspect(env: Env, payload: {
|
|
21
35
|
clipUrl: string;
|
|
22
36
|
keyframeUrl?: string;
|
|
23
37
|
}, opts?: {
|
|
24
38
|
retries?: number;
|
|
25
39
|
backoffMs?: number;
|
|
26
|
-
}): Promise<InspectResult |
|
|
40
|
+
}): Promise<InspectResult | {
|
|
41
|
+
unreachable: true;
|
|
42
|
+
} | null>;
|
|
27
43
|
export interface ContentVerdict {
|
|
28
44
|
verdict: "ok" | "suspect" | "corrupt" | "skip";
|
|
45
|
+
/** core#321: this skip means "the container is not serving", not "this one clip could not be
|
|
46
|
+
* inspected". The per-pass breaker trips on THIS FIELD, never on a reason string: a string match
|
|
47
|
+
* is not a relationship, and a reason is prose that someone will reword without thinking about a
|
|
48
|
+
* breaker. */
|
|
49
|
+
unreachable?: true;
|
|
29
50
|
reason?: string;
|
|
30
51
|
metrics?: InspectResult["metrics"];
|
|
31
52
|
keyframe_similarity?: number | null;
|
|
@@ -40,4 +61,19 @@ export declare function contentValidateClip(env: Env, clipKey: string, keyframeK
|
|
|
40
61
|
* `clip.content_validate` structured event per shot. Returns true iff it changed any shot; the CALLER owns
|
|
41
62
|
* the job-doc write. A no-op (returns false immediately) when the video-finish tier is not installed. */
|
|
42
63
|
export declare function contentValidateDoneClips(env: Env, job: ClipJob, inspect?: (env: Env, clipKey: string, keyframeKey?: string) => Promise<ContentVerdict>): Promise<boolean>;
|
|
64
|
+
/** cf#856: what Layer 2 actually MEASURED on this clip job, for the render record.
|
|
65
|
+
*
|
|
66
|
+
* THE LADDER, the same three states cf#836 established for the per-stage degrades, because the
|
|
67
|
+
* failure they both prevent is the same one (two states reported as one):
|
|
68
|
+
* undefined -> Layer 2 never ran on this job at all. NOT MEASURED. (Self-host with no
|
|
69
|
+
* VIDEO_FINISH_URL is exactly this, and it is honest: the tier is not installed.)
|
|
70
|
+
* unmeasured 0 -> it ran on every done clip and every one got a verdict.
|
|
71
|
+
* unmeasured n -> it could not measure n of them, and `reasons` says why, verbatim.
|
|
72
|
+
*
|
|
73
|
+
* Counts the population Layer 2 covers: DONE shots that produced a clip. */
|
|
74
|
+
export declare function contentValidationView(job: ClipJob): {
|
|
75
|
+
checked: number;
|
|
76
|
+
unmeasured: number;
|
|
77
|
+
reasons: string[];
|
|
78
|
+
} | undefined;
|
|
43
79
|
//# sourceMappingURL=clip-content-validate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clip-content-validate.d.ts","sourceRoot":"","sources":["../src/clip-content-validate.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oCAAoC,CAAC;AAE9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD,8GAA8G;AAC9G,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,sBAAsB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACtG,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"clip-content-validate.d.ts","sourceRoot":"","sources":["../src/clip-content-validate.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oCAAoC,CAAC;AAE9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD,8GAA8G;AAC9G,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,sBAAsB,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACtG,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;8EAgB8E;AAC9E,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,GAAG,EACR,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EAClD,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAClD,OAAO,CAAC,aAAa,GAAG;IAAE,WAAW,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAAC,CAsCvD;AAOD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC/C;;;mBAGe;IACf,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACnC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;kFACkF;AAClF,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAgBlH;AAED;;;;;0GAK0G;AAC1G,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAuB,GAC1G,OAAO,CAAC,OAAO,CAAC,CAuDlB;AAED;;;;;;;;;6EAS6E;AAC7E,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,GACX;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAgBxE"}
|
|
@@ -22,8 +22,22 @@ import { presignR2Get } from "./presign.js";
|
|
|
22
22
|
import { emitStructuredEvent } from "./structured-events.js";
|
|
23
23
|
const INSPECT_TTL_SECONDS = 1800;
|
|
24
24
|
/** Call the video-finish container's POST /inspect, retrying the transient gateway statuses (503/504) the
|
|
25
|
-
* way callVideoFinish does for /finish. backoffMs is injectable so tests do not wait.
|
|
26
|
-
*
|
|
25
|
+
* way callVideoFinish does for /finish. backoffMs is injectable so tests do not wait.
|
|
26
|
+
*
|
|
27
|
+
* Returns the parsed result, or an UNREACHABLE marker the caller can act on (core#321). The
|
|
28
|
+
* distinction is not cosmetic: contentValidateDoneClips walks shots SEQUENTIALLY, so a container
|
|
29
|
+
* that is down costs its whole retry budget once per shot.
|
|
30
|
+
*
|
|
31
|
+
* A THROWN fetch (NXDOMAIN, connection refused, a container that died before binding 8000, which is
|
|
32
|
+
* cf#851's exact signature) is NOT the gateway-busy condition the backoff was written for, and one
|
|
33
|
+
* attempt establishes it. It used to retry anyway, because the loop's break tested
|
|
34
|
+
* `resp && resp.status !== 503 ...` and a throw leaves resp null, which is falsy, which is not a
|
|
35
|
+
* break. Three attempts at 1500ms, per shot, sequentially: about 3s a shot, roughly 51s of a finish
|
|
36
|
+
* pass on a 17-shot film, re-paid on later ticks because core#30 says not to persist the skip.
|
|
37
|
+
*
|
|
38
|
+
* The 503/504 retry is UNCHANGED and deliberately so: that one is the container saying "busy, come
|
|
39
|
+
* back", and cutting it would trade this latency problem for a coverage problem, i.e. more false
|
|
40
|
+
* `unmeasured` records, which is the state cf#856 exists to make visible. */
|
|
27
41
|
export async function callVideoFinishInspect(env, payload, opts = {}) {
|
|
28
42
|
if (!videoFinishReachable(env))
|
|
29
43
|
return null;
|
|
@@ -34,30 +48,47 @@ export async function callVideoFinishInspect(env, payload, opts = {}) {
|
|
|
34
48
|
headers: await mediaFinishHeaders(env),
|
|
35
49
|
body: JSON.stringify(payload),
|
|
36
50
|
};
|
|
37
|
-
let
|
|
51
|
+
let last;
|
|
38
52
|
for (let attempt = 0; attempt < retries; attempt++) {
|
|
53
|
+
let resp;
|
|
39
54
|
try {
|
|
40
55
|
resp = await videoFinishFetch(env, "/inspect", init);
|
|
41
56
|
}
|
|
42
57
|
catch (e) {
|
|
43
58
|
if (isMediaFinishAuthError(e))
|
|
44
59
|
throw e;
|
|
45
|
-
|
|
60
|
+
// The transport itself failed. No amount of waiting makes a name resolve or a dead process
|
|
61
|
+
// bind, so stop here instead of sleeping twice to ask the same question.
|
|
62
|
+
return { unreachable: true };
|
|
46
63
|
}
|
|
47
|
-
|
|
64
|
+
// videoFinishFetch RESOLVES to null when the door is unset or could not be reached at all.
|
|
65
|
+
// Same class as a throw, equally unhelped by waiting, and it used to sit in the retry loop too
|
|
66
|
+
// because the old break condition (`resp && ...`) read null as "keep trying".
|
|
67
|
+
if (!resp)
|
|
68
|
+
return { unreachable: true };
|
|
69
|
+
last = resp;
|
|
70
|
+
if (resp.status !== 503 && resp.status !== 504)
|
|
48
71
|
break;
|
|
49
72
|
if (attempt < retries - 1)
|
|
50
73
|
await new Promise((r) => setTimeout(r, backoffMs));
|
|
51
74
|
}
|
|
52
|
-
|
|
53
|
-
|
|
75
|
+
// Exhausted the 503/504 budget, or a non-2xx answer: the tier is up but not serving this call.
|
|
76
|
+
if (!last || !last.ok)
|
|
77
|
+
return { unreachable: true };
|
|
54
78
|
try {
|
|
55
|
-
return (await
|
|
79
|
+
return (await last.json());
|
|
56
80
|
}
|
|
57
81
|
catch {
|
|
82
|
+
// It answered 2xx with a body that will not parse. That is the container misbehaving on THIS
|
|
83
|
+
// clip, not the tier being down, so it is not an unreachable marker and must not trip the
|
|
84
|
+
// per-pass breaker.
|
|
58
85
|
return null;
|
|
59
86
|
}
|
|
60
87
|
}
|
|
88
|
+
/** True when the inspect call could not reach a serving container at all (core#321). */
|
|
89
|
+
function isUnreachable(r) {
|
|
90
|
+
return r !== null && r.unreachable === true;
|
|
91
|
+
}
|
|
61
92
|
/** Presign the clip (and its keyframe, when known) and ask the container for a content verdict. Skips
|
|
62
93
|
* honestly (never throws, never fails a render) when the tier is unavailable. */
|
|
63
94
|
export async function contentValidateClip(env, clipKey, keyframeKey) {
|
|
@@ -74,6 +105,9 @@ export async function contentValidateClip(env, clipKey, keyframeKey) {
|
|
|
74
105
|
return { verdict: "skip", reason: `presign failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
75
106
|
}
|
|
76
107
|
const r = await callVideoFinishInspect(env, { clipUrl, keyframeUrl });
|
|
108
|
+
if (isUnreachable(r)) {
|
|
109
|
+
return { verdict: "skip", reason: "video-finish /inspect unreachable or errored", unreachable: true };
|
|
110
|
+
}
|
|
77
111
|
if (!r || !r.ok || !r.verdict)
|
|
78
112
|
return { verdict: "skip", reason: "video-finish /inspect unreachable or errored" };
|
|
79
113
|
return { verdict: r.verdict, reason: r.reason, metrics: r.metrics, keyframe_similarity: r.keyframe_similarity };
|
|
@@ -88,6 +122,12 @@ export async function contentValidateDoneClips(env, job, inspect = contentValida
|
|
|
88
122
|
if (!videoFinishReachable(env))
|
|
89
123
|
return false;
|
|
90
124
|
let changed = false;
|
|
125
|
+
// core#321: once ONE shot has established that the container is not serving, the remaining shots
|
|
126
|
+
// in this pass do not re-probe it. They still get the cf#856 unmeasured record, because the film
|
|
127
|
+
// is equally unvouched-for either way and a record that depended on probe ORDER would be a worse
|
|
128
|
+
// lie than no record at all. O(shots) transport failures become O(1) per pass, and nothing is
|
|
129
|
+
// latched beyond this pass: the next tick starts clean and tries again.
|
|
130
|
+
let tierDown;
|
|
91
131
|
for (const shot of job.shots) {
|
|
92
132
|
// #30: "skip" (a transient /inspect outage or the tier being unavailable) is NOT a validation result, so
|
|
93
133
|
// it must not short-circuit re-inspection -- only a terminal verdict (ok / suspect / corrupt) counts as
|
|
@@ -95,10 +135,30 @@ export async function contentValidateDoneClips(env, job, inspect = contentValida
|
|
|
95
135
|
// (the pixel/noise gate) for the whole pass and the clip ships ungated.
|
|
96
136
|
if (shot.status !== "done" || !shot.clip_key || (shot.content_validated && shot.content_validated !== "skip"))
|
|
97
137
|
continue;
|
|
98
|
-
const v =
|
|
138
|
+
const v = tierDown
|
|
139
|
+
? { verdict: "skip", reason: tierDown, unreachable: true }
|
|
140
|
+
: await inspect(env, shot.clip_key, shot.keyframe_key);
|
|
141
|
+
if (v.unreachable && !tierDown)
|
|
142
|
+
tierDown = v.reason ?? "video-finish /inspect unreachable";
|
|
99
143
|
// Don't persist "skip" as a verdict: leave it unset so a later tick re-inspects.
|
|
100
144
|
if (v.verdict !== "skip")
|
|
101
145
|
shot.content_validated = v.verdict;
|
|
146
|
+
// cf#856: but DO say that it could not run. Measured on a live film while the container was
|
|
147
|
+
// crashing: 5 skips, 0 passes, and the film advanced with nothing anywhere recording that the
|
|
148
|
+
// pixel gate never looked at a single clip. A skip left only in a log line is indistinguishable
|
|
149
|
+
// from a pass to every reader except one who happened to have `wrangler tail` attached.
|
|
150
|
+
// SEPARATE from content_validated on purpose (see #30 above): the verdict stays unset so
|
|
151
|
+
// re-inspection still happens, and this carries the reason meanwhile. Written only when it
|
|
152
|
+
// CHANGES, so a down inspector does not rewrite the doc every tick, and cleared the moment a
|
|
153
|
+
// terminal verdict lands, so it cannot go stale.
|
|
154
|
+
const unmeasured = v.verdict === "skip" ? (v.reason ?? "content validation could not run") : undefined;
|
|
155
|
+
if (shot.content_unmeasured !== unmeasured) {
|
|
156
|
+
if (unmeasured)
|
|
157
|
+
shot.content_unmeasured = unmeasured;
|
|
158
|
+
else
|
|
159
|
+
delete shot.content_unmeasured;
|
|
160
|
+
changed = true;
|
|
161
|
+
}
|
|
102
162
|
emitStructuredEvent({
|
|
103
163
|
ev: "clip.content_validate",
|
|
104
164
|
job_id: job.job_id,
|
|
@@ -121,4 +181,31 @@ export async function contentValidateDoneClips(env, job, inspect = contentValida
|
|
|
121
181
|
}
|
|
122
182
|
return changed;
|
|
123
183
|
}
|
|
184
|
+
/** cf#856: what Layer 2 actually MEASURED on this clip job, for the render record.
|
|
185
|
+
*
|
|
186
|
+
* THE LADDER, the same three states cf#836 established for the per-stage degrades, because the
|
|
187
|
+
* failure they both prevent is the same one (two states reported as one):
|
|
188
|
+
* undefined -> Layer 2 never ran on this job at all. NOT MEASURED. (Self-host with no
|
|
189
|
+
* VIDEO_FINISH_URL is exactly this, and it is honest: the tier is not installed.)
|
|
190
|
+
* unmeasured 0 -> it ran on every done clip and every one got a verdict.
|
|
191
|
+
* unmeasured n -> it could not measure n of them, and `reasons` says why, verbatim.
|
|
192
|
+
*
|
|
193
|
+
* Counts the population Layer 2 covers: DONE shots that produced a clip. */
|
|
194
|
+
export function contentValidationView(job) {
|
|
195
|
+
const covered = job.shots.filter((s) => s.status === "done" && s.clip_key);
|
|
196
|
+
const checked = covered.filter((s) => s.content_validated && s.content_validated !== "skip").length;
|
|
197
|
+
const blocked = covered.filter((s) => typeof s.content_unmeasured === "string" && s.content_unmeasured.length > 0);
|
|
198
|
+
if (checked === 0 && blocked.length === 0)
|
|
199
|
+
return undefined;
|
|
200
|
+
const seen = new Set();
|
|
201
|
+
const reasons = [];
|
|
202
|
+
for (const s of blocked) {
|
|
203
|
+
const r = s.content_unmeasured;
|
|
204
|
+
if (seen.has(r))
|
|
205
|
+
continue;
|
|
206
|
+
seen.add(r);
|
|
207
|
+
reasons.push(r);
|
|
208
|
+
}
|
|
209
|
+
return { checked, unmeasured: blocked.length, reasons };
|
|
210
|
+
}
|
|
124
211
|
//# sourceMappingURL=clip-content-validate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clip-content-validate.js","sourceRoot":"","sources":["../src/clip-content-validate.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,wGAAwG;AACxG,uGAAuG;AACvG,qGAAqG;AACrG,qGAAqG;AACrG,yGAAyG;AACzG,8CAA8C;AAC9C,EAAE;AACF,0GAA0G;AAC1G,uGAAuG;AACvG,uGAAuG;AACvG,qGAAqG;AACrG,0FAA0F;AAC1F,0GAA0G;AAC1G,gFAAgF;AAChF,EAAE;AACF,sGAAsG;AACtG,oEAAoE;AAGpE,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE5H,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAYjC
|
|
1
|
+
{"version":3,"file":"clip-content-validate.js","sourceRoot":"","sources":["../src/clip-content-validate.ts"],"names":[],"mappings":"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"}
|
package/dist/clip-job-model.d.ts
CHANGED
|
@@ -21,8 +21,26 @@ export interface ClipShot extends ClipShotInput {
|
|
|
21
21
|
runpod_job_id?: string;
|
|
22
22
|
cancel_sent?: boolean;
|
|
23
23
|
validated?: "pass" | "fail" | "skip";
|
|
24
|
+
/** core#310: why Layer 1 COULD NOT RUN on this shot, when it could not.
|
|
25
|
+
*
|
|
26
|
+
* The same split core#30 made for Layer 2 and cf#856 gave a word to, applied one layer down:
|
|
27
|
+
* `validated` holds a VERDICT and stays unset on a skip so the next tick re-validates, while
|
|
28
|
+
* this carries the honest reason meanwhile. Before this, a skip was written into `validated`,
|
|
29
|
+
* where it is truthy, so the idempotence guard short-circuited and a shot whose artifact was
|
|
30
|
+
* momentarily unreadable was never structurally checked again. Cleared the moment a verdict
|
|
31
|
+
* lands. */
|
|
32
|
+
validated_unmeasured?: string;
|
|
24
33
|
content_validated?: "ok" | "suspect" | "corrupt" | "skip";
|
|
25
34
|
content_degraded?: string;
|
|
35
|
+
/** cf#856: why Layer 2 COULD NOT RUN on this shot, when it could not.
|
|
36
|
+
*
|
|
37
|
+
* Deliberately NOT `content_validated = "skip"`. #30 established that a skip must not be
|
|
38
|
+
* persisted as a verdict, because a truthy value there short-circuits re-inspection and one
|
|
39
|
+
* inspector blip disables the pixel gate for the whole pass. So the two facts are separate
|
|
40
|
+
* fields: `content_validated` stays UNSET so the next tick re-inspects, and this says out loud
|
|
41
|
+
* that the last attempt could not measure anything. Cleared the moment a terminal verdict lands,
|
|
42
|
+
* so it can never be stale. */
|
|
43
|
+
content_unmeasured?: string;
|
|
26
44
|
delivered_fps?: number;
|
|
27
45
|
delivered_frames?: number;
|
|
28
46
|
/** cf#507b: the clip's ACTUAL pixel dimensions, as probed from its mp4 `tkhd` box.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clip-job-model.d.ts","sourceRoot":"","sources":["../src/clip-job-model.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAS,SAAQ,aAAa;IAC7C,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC,iBAAiB,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;uFAQmF;IACnF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sEAAsE;IACtE,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAGtC,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,eAAe,CAAC,EAAE,MAAM,CAAC;IAIzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAKrD"}
|
|
1
|
+
{"version":3,"file":"clip-job-model.d.ts","sourceRoot":"","sources":["../src/clip-job-model.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAS,SAAQ,aAAa;IAC7C,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC;;;;;;;iBAOa;IACb,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;oCAOgC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;uFAQmF;IACnF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sEAAsE;IACtE,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAGtC,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,eAAe,CAAC,EAAE,MAAM,CAAC;IAIzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAKrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clip-job-model.js","sourceRoot":"","sources":["../src/clip-job-model.ts"],"names":[],"mappings":"AAAA,iFAAiF;
|
|
1
|
+
{"version":3,"file":"clip-job-model.js","sourceRoot":"","sources":["../src/clip-job-model.ts"],"names":[],"mappings":"AAAA,iFAAiF;AA8FjF,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;IAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACjE,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IACrE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,IAAI,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,GAAG,MAAM,KAAK,KAAK,EAAE,CAAC;AACpG,CAAC"}
|
package/dist/clip-validate.d.ts
CHANGED
|
@@ -30,4 +30,23 @@ export interface MoovInfo {
|
|
|
30
30
|
export declare function parseMoov(buf: Uint8Array, start?: number, end?: number): MoovInfo;
|
|
31
31
|
export declare function judgeClip(checks: ClipValidateChecks): ClipValidateResult;
|
|
32
32
|
export declare function validateClipArtifact(env: Env, key: string, expectedSeconds: number): Promise<ClipValidateResult>;
|
|
33
|
+
export declare const FILM_MIN_BYTES = 2048;
|
|
34
|
+
export declare const FILM_MIN_DURATION_S = 0.15;
|
|
35
|
+
/** PURE: the film verdict over the same checks. Fails ONLY on positive evidence, like judgeClip.
|
|
36
|
+
*
|
|
37
|
+
* HONEST LIMIT, stated so nobody reads this as more than it is: the floor is structural. A film
|
|
38
|
+
* that concatenated 3 of its 12 shots is a structurally perfect mp4 and passes here. Shot-count
|
|
39
|
+
* honesty is the #697 duration gate's job, upstream, on the container's per-clip report. */
|
|
40
|
+
export declare function judgeFilm(checks: ClipValidateChecks): ClipValidateResult;
|
|
41
|
+
/** Is the assembled film at `key` a deliverable film? Three outcomes, and the difference between
|
|
42
|
+
* the last two is the whole point:
|
|
43
|
+
* - "fail": positive evidence it is NOT a film (absent, under the byte floor, not an mp4, no
|
|
44
|
+
* video track, zero frames). The render fails loud rather than shipping it as complete.
|
|
45
|
+
* - "skip": the object IS there and over the floor, but its bytes could not be read this tick.
|
|
46
|
+
* That is an R2 condition, not a verdict on the artifact, and a fully rendered film must not
|
|
47
|
+
* die on a read blip. The caller ships it and says so.
|
|
48
|
+
* - "pass": parsed and sane.
|
|
49
|
+
*
|
|
50
|
+
* NEVER throws. */
|
|
51
|
+
export declare function validateFilmArtifact(env: Env, key: string): Promise<ClipValidateResult>;
|
|
33
52
|
//# sourceMappingURL=clip-validate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clip-validate.d.ts","sourceRoot":"","sources":["../src/clip-validate.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oCAAoC,CAAC;AAM9D,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,cAAc,OAAO,CAAC;AACnC,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAIxC,eAAO,MAAM,cAAc,QAAkB,CAAC;AAI9C,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAmCD,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAMD,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,SAAI,EAAE,GAAG,GAAE,MAAmB,GAAG,QAAQ,CAIxF;AAyED,wBAAgB,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAqBxE;
|
|
1
|
+
{"version":3,"file":"clip-validate.d.ts","sourceRoot":"","sources":["../src/clip-validate.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oCAAoC,CAAC;AAM9D,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,cAAc,OAAO,CAAC;AACnC,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAIxC,eAAO,MAAM,cAAc,QAAkB,CAAC;AAI9C,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAmCD,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAMD,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,SAAI,EAAE,GAAG,GAAE,MAAmB,GAAG,QAAQ,CAIxF;AAyED,wBAAgB,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAqBxE;AAyFD,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAqBtH;AAYD,eAAO,MAAM,cAAc,OAAO,CAAC;AACnC,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAIxC;;;;6FAI6F;AAC7F,wBAAgB,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAiBxE;AAED;;;;;;;;;oBASoB;AACpB,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoB7F"}
|