gooseworks 0.5.9-dev.59.2b371ca1 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/kit/core/assembly-timeline.d.ts +184 -0
- package/dist/kit/core/assembly-timeline.d.ts.map +1 -0
- package/dist/kit/core/assembly-timeline.js +476 -0
- package/dist/kit/core/assembly-timeline.js.map +1 -0
- package/dist/kit/core/device.d.ts.map +1 -1
- package/dist/kit/core/device.js +1 -0
- package/dist/kit/core/device.js.map +1 -1
- package/dist/kit/core/eyes.d.ts +49 -2
- package/dist/kit/core/eyes.d.ts.map +1 -1
- package/dist/kit/core/eyes.js +102 -9
- package/dist/kit/core/eyes.js.map +1 -1
- package/dist/kit/core/final-measure.d.ts +138 -0
- package/dist/kit/core/final-measure.d.ts.map +1 -0
- package/dist/kit/core/final-measure.js +492 -0
- package/dist/kit/core/final-measure.js.map +1 -0
- package/dist/kit/core/outcome.d.ts +5 -1
- package/dist/kit/core/outcome.d.ts.map +1 -1
- package/dist/kit/core/outcome.js +14 -2
- package/dist/kit/core/outcome.js.map +1 -1
- package/dist/kit/core/run.d.ts +7 -0
- package/dist/kit/core/run.d.ts.map +1 -1
- package/dist/kit/core/run.js +304 -8
- package/dist/kit/core/run.js.map +1 -1
- package/dist/kit/core/version.d.ts +3 -1
- package/dist/kit/core/version.d.ts.map +1 -1
- package/dist/kit/core/version.js +4 -2
- package/dist/kit/core/version.js.map +1 -1
- package/dist/kit/line/types.d.ts +2 -0
- package/dist/kit/line/types.d.ts.map +1 -1
- package/dist/kit/maker/inputs.js +1 -1
- package/dist/kit/maker/make.d.ts +8 -0
- package/dist/kit/maker/make.d.ts.map +1 -1
- package/dist/kit/maker/make.js +34 -1
- package/dist/kit/maker/make.js.map +1 -1
- package/dist/kit/maker/parts/html-frames/{1.2.1 → 1.3.1}/part.json +42 -4
- package/dist/kit/maker/parts/html-frames/src/part.d.ts.map +1 -1
- package/dist/kit/maker/parts/html-frames/src/part.js +5 -1
- package/dist/kit/maker/parts/html-frames/src/part.js.map +1 -1
- package/dist/kit/maker/under.d.ts +2 -0
- package/dist/kit/maker/under.d.ts.map +1 -1
- package/dist/kit/maker/under.js +11 -0
- package/dist/kit/maker/under.js.map +1 -1
- package/dist/skills/master-skill.d.ts +2 -2
- package/dist/skills/master-skill.d.ts.map +1 -1
- package/dist/skills/master-skill.js +3 -3
- package/dist/skills/master-skill.js.map +1 -1
- package/dist/skills/server-entry-skills.d.ts +3 -3
- package/dist/skills/server-entry-skills.d.ts.map +1 -1
- package/dist/skills/server-entry-skills.js +34 -35
- package/dist/skills/server-entry-skills.js.map +1 -1
- package/package.json +9 -4
- package/skills/goose-video/SKILL.md +2 -2
- package/skills/make-custom-video/SKILL.md +23 -29
- package/skills/manifest.json +3 -3
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FINAL_MEASURE_CHECKS = exports.FINAL_MEASURE_THRESHOLDS = exports.FINAL_MEASURE_FORMAT = void 0;
|
|
4
|
+
exports.maxFreezeMs = maxFreezeMs;
|
|
5
|
+
exports.maxFrozenShare = maxFrozenShare;
|
|
6
|
+
exports.pastEdges = pastEdges;
|
|
7
|
+
exports.silentByPlan = silentByPlan;
|
|
8
|
+
exports.covered = covered;
|
|
9
|
+
exports.analyseAudio = analyseAudio;
|
|
10
|
+
exports.dHash = dHash;
|
|
11
|
+
exports.hamming = hamming;
|
|
12
|
+
exports.finalMeasureChecks = finalMeasureChecks;
|
|
13
|
+
exports.finalMeasureFailures = finalMeasureFailures;
|
|
14
|
+
exports.measureFinal = measureFinal;
|
|
15
|
+
// gooseworks-final-measure/1 (fix-forward contract section 1): the kit measures the finished
|
|
16
|
+
// bytes before upload, for early feedback. The server runs the same checks on the uploaded bytes
|
|
17
|
+
// and stays the authority; the thresholds below are the shared ones and must not drift from it.
|
|
18
|
+
//
|
|
19
|
+
// Measured here: digital silence, tone-only "music", unplanned silence, planned pause and freeze
|
|
20
|
+
// limits, frozen picture, repeated shots and silence under a speaking face. The two word checks
|
|
21
|
+
// need the server's own transcript of the final, so the kit marks them not_applicable.
|
|
22
|
+
//
|
|
23
|
+
// Calibration (15 Oct, from real reference ads): silence and frozen picture may run up to 1.5 s at
|
|
24
|
+
// the start and 3.0 s at the end, an unplanned mid-video freeze may last 2.0 s, the tone check
|
|
25
|
+
// looks at 80 Hz-8 kHz only, and the still-image share follows the reference when it is known.
|
|
26
|
+
const child_process_1 = require("child_process");
|
|
27
|
+
const toolchain_1 = require("./toolchain");
|
|
28
|
+
exports.FINAL_MEASURE_FORMAT = 'gooseworks-final-measure/1';
|
|
29
|
+
/**
|
|
30
|
+
* The shared thresholds, with the same names and numbers as the harness (goose-studio
|
|
31
|
+
* final_measure.py THRESHOLDS) and the server, so every final_measure record reads alike.
|
|
32
|
+
*/
|
|
33
|
+
exports.FINAL_MEASURE_THRESHOLDS = {
|
|
34
|
+
digital_silence_peak_dbfs: -60,
|
|
35
|
+
digital_zero_run_s: 1.0,
|
|
36
|
+
tone_fft_size: 4096,
|
|
37
|
+
tone_window_s: 0.5,
|
|
38
|
+
tone_peak_halfwidth_bins: 2,
|
|
39
|
+
tone_max_peaks: 3,
|
|
40
|
+
tone_peak_energy_share: 0.8,
|
|
41
|
+
tone_steady_share: 0.5,
|
|
42
|
+
/** Calibration: the tone check analyses this band only, so a steady sub-bass line is not a "tone". */
|
|
43
|
+
tone_min_hz: 80,
|
|
44
|
+
tone_max_hz: 8000,
|
|
45
|
+
quiet_dbfs: -45,
|
|
46
|
+
quiet_window_ms: 100,
|
|
47
|
+
unplanned_silence_s: 1.0,
|
|
48
|
+
/** Calibration: silence or a frozen picture that sits inside the first 1.5 s or the last 3.0 s is allowed. */
|
|
49
|
+
start_allowance_ms: 1500,
|
|
50
|
+
end_allowance_ms: 3000,
|
|
51
|
+
speech_gap_in_sentence_s: 0.6,
|
|
52
|
+
max_pause_ms: 1500,
|
|
53
|
+
max_pause_share: 0.1,
|
|
54
|
+
freeze_noise: 0.003,
|
|
55
|
+
freeze_min_s: 1.0,
|
|
56
|
+
/** Calibration: an unplanned frozen run mid-video fails only past this length. */
|
|
57
|
+
unplanned_freeze_s: 2.0,
|
|
58
|
+
max_frozen_share: 0.4,
|
|
59
|
+
/** Calibration: with a measured reference, the frozen share may reach max(40%, reference share + 15 points). */
|
|
60
|
+
reference_frozen_margin: 0.15,
|
|
61
|
+
max_freeze_ms: 1500,
|
|
62
|
+
/** Amendment: a planned freeze that ends the video (the closing hold) may last this long. */
|
|
63
|
+
max_end_card_freeze_ms: 3000,
|
|
64
|
+
repeated_shot_min_s: 1.0,
|
|
65
|
+
repeated_shot_max_hamming: 6,
|
|
66
|
+
scene_cut_threshold: 0.4,
|
|
67
|
+
edge_words: 3,
|
|
68
|
+
edge_window_s: 4.0,
|
|
69
|
+
silent_face_s: 0.3,
|
|
70
|
+
};
|
|
71
|
+
/** The longest a planned freeze may last: 3.0 s when it holds the last shot to the end, else 1.5 s. */
|
|
72
|
+
function maxFreezeMs(freeze, durationMs) {
|
|
73
|
+
return freeze.end_ms === durationMs ? exports.FINAL_MEASURE_THRESHOLDS.max_end_card_freeze_ms : exports.FINAL_MEASURE_THRESHOLDS.max_freeze_ms;
|
|
74
|
+
}
|
|
75
|
+
/** The share of the video the picture may be frozen: 40%, or the reference's share plus 15 points when that is known. */
|
|
76
|
+
function maxFrozenShare(referenceFrozenShare) {
|
|
77
|
+
const T = exports.FINAL_MEASURE_THRESHOLDS;
|
|
78
|
+
return typeof referenceFrozenShare === 'number' && Number.isFinite(referenceFrozenShare) ? Math.max(T.max_frozen_share, referenceFrozenShare + T.reference_frozen_margin) : T.max_frozen_share;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* How much of a run lies outside the opening 1.5 s and the closing 3.0 s, in ms. Silence or a held
|
|
82
|
+
* picture inside those is allowed, so only this remainder is held to a check's length limit: a 4.4 s
|
|
83
|
+
* closing freeze leaves 1.4 s, while a 7 s silent tail leaves 4 s.
|
|
84
|
+
*/
|
|
85
|
+
function pastEdges([start, end], durationMs) {
|
|
86
|
+
const T = exports.FINAL_MEASURE_THRESHOLDS;
|
|
87
|
+
return Math.max(0, Math.min(end, durationMs - T.end_allowance_ms) - Math.max(start, T.start_allowance_ms));
|
|
88
|
+
}
|
|
89
|
+
/** An approved silent video: no speech and intentional_silence as the only soundtrack. */
|
|
90
|
+
function silentByPlan(timeline) {
|
|
91
|
+
return !!timeline && timeline.speech_mode === 'none' && Array.isArray(timeline.soundtrack_modes) && timeline.soundtrack_modes.length === 1 && timeline.soundtrack_modes[0] === 'intentional_silence';
|
|
92
|
+
}
|
|
93
|
+
exports.FINAL_MEASURE_CHECKS = [
|
|
94
|
+
'digital_silence',
|
|
95
|
+
'tone_only',
|
|
96
|
+
'unplanned_silence',
|
|
97
|
+
'speech_gap_in_sentence',
|
|
98
|
+
'planned_pause_too_long',
|
|
99
|
+
'frozen_picture',
|
|
100
|
+
'planned_freeze_too_long',
|
|
101
|
+
'repeated_shot',
|
|
102
|
+
'first_last_words',
|
|
103
|
+
'speech_over_silent_face',
|
|
104
|
+
];
|
|
105
|
+
const T = exports.FINAL_MEASURE_THRESHOLDS;
|
|
106
|
+
/** The intent prefix that marks a deliberate repeated shot (case-sensitive, as in the harness). */
|
|
107
|
+
const CALLBACK = 'callback:';
|
|
108
|
+
/** At most this many time ranges are kept per check, so the record stays small in the upload manifest. */
|
|
109
|
+
const MAX_INTERVALS = 50;
|
|
110
|
+
const dbfs = (amplitude) => (amplitude > 0 ? 20 * Math.log10(amplitude) : -Infinity);
|
|
111
|
+
/** In-place radix-2 FFT of a power-of-two length. */
|
|
112
|
+
function fft(re, im) {
|
|
113
|
+
const n = re.length;
|
|
114
|
+
for (let i = 1, j = 0; i < n; i++) {
|
|
115
|
+
let bit = n >> 1;
|
|
116
|
+
for (; j & bit; bit >>= 1)
|
|
117
|
+
j ^= bit;
|
|
118
|
+
j ^= bit;
|
|
119
|
+
if (i < j) {
|
|
120
|
+
[re[i], re[j]] = [re[j], re[i]];
|
|
121
|
+
[im[i], im[j]] = [im[j], im[i]];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
for (let len = 2; len <= n; len <<= 1) {
|
|
125
|
+
const angle = (-2 * Math.PI) / len;
|
|
126
|
+
const wr = Math.cos(angle);
|
|
127
|
+
const wi = Math.sin(angle);
|
|
128
|
+
for (let i = 0; i < n; i += len) {
|
|
129
|
+
let cr = 1;
|
|
130
|
+
let ci = 0;
|
|
131
|
+
for (let k = 0; k < len / 2; k++) {
|
|
132
|
+
const a = i + k;
|
|
133
|
+
const b = a + len / 2;
|
|
134
|
+
const tr = re[b] * cr - im[b] * ci;
|
|
135
|
+
const ti = re[b] * ci + im[b] * cr;
|
|
136
|
+
re[b] = re[a] - tr;
|
|
137
|
+
im[b] = im[a] - ti;
|
|
138
|
+
re[a] += tr;
|
|
139
|
+
im[a] += ti;
|
|
140
|
+
const next = cr * wr - ci * wi;
|
|
141
|
+
ci = cr * wi + ci * wr;
|
|
142
|
+
cr = next;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Adjacent or overlapping intervals as one. */
|
|
148
|
+
function merge(intervals) {
|
|
149
|
+
const out = [];
|
|
150
|
+
for (const [start, end] of [...intervals].sort((a, b) => a[0] - b[0])) {
|
|
151
|
+
const last = out[out.length - 1];
|
|
152
|
+
if (last && start <= last[1])
|
|
153
|
+
last[1] = Math.max(last[1], end);
|
|
154
|
+
else
|
|
155
|
+
out.push([start, end]);
|
|
156
|
+
}
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
/** True when the interval sits inside one allowed interval, with 100 ms of slack (the harness's `covered`). */
|
|
160
|
+
function covered([start, end], allowed, slackMs = 100) {
|
|
161
|
+
return allowed.some(([a, b]) => a - slackMs <= start && end <= b + slackMs);
|
|
162
|
+
}
|
|
163
|
+
/** Every run of true flags on a grid of `stepMs` longer than `minimumMs`, in ms. */
|
|
164
|
+
function runs(flags, stepMs, minimumMs) {
|
|
165
|
+
const found = [];
|
|
166
|
+
let opened = -1;
|
|
167
|
+
for (let i = 0; i <= flags.length; i++) {
|
|
168
|
+
const flag = i < flags.length && flags[i];
|
|
169
|
+
if (flag && opened < 0)
|
|
170
|
+
opened = i;
|
|
171
|
+
else if (!flag && opened >= 0) {
|
|
172
|
+
if ((i - opened) * stepMs > minimumMs + 1e-6)
|
|
173
|
+
found.push([opened * stepMs, i * stepMs]);
|
|
174
|
+
opened = -1;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return found;
|
|
178
|
+
}
|
|
179
|
+
/** Peak, exact-zero runs, quiet windows and the steady-tone share of mono samples in -1..1. */
|
|
180
|
+
function analyseAudio(samples, rate) {
|
|
181
|
+
let peak = 0;
|
|
182
|
+
const zero_runs_ms = [];
|
|
183
|
+
let zeroFrom = -1;
|
|
184
|
+
for (let i = 0; i <= samples.length; i++) {
|
|
185
|
+
const v = i < samples.length ? samples[i] : NaN;
|
|
186
|
+
if (Math.abs(v) > peak)
|
|
187
|
+
peak = Math.abs(v);
|
|
188
|
+
if (v === 0) {
|
|
189
|
+
if (zeroFrom < 0)
|
|
190
|
+
zeroFrom = i;
|
|
191
|
+
}
|
|
192
|
+
else if (zeroFrom >= 0) {
|
|
193
|
+
if ((i - zeroFrom) / rate > T.digital_zero_run_s + 1e-9)
|
|
194
|
+
zero_runs_ms.push([Math.round((zeroFrom / rate) * 1000), Math.round((i / rate) * 1000)]);
|
|
195
|
+
zeroFrom = -1;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const quiet = [];
|
|
199
|
+
const windowSamples = Math.max(1, Math.round((rate * T.quiet_window_ms) / 1000));
|
|
200
|
+
for (let start = 0; start < samples.length; start += windowSamples) {
|
|
201
|
+
const end = Math.min(samples.length, start + windowSamples);
|
|
202
|
+
let sum = 0;
|
|
203
|
+
for (let i = start; i < end; i++)
|
|
204
|
+
sum += samples[i] * samples[i];
|
|
205
|
+
quiet.push(dbfs(Math.sqrt(sum / (end - start))) < T.quiet_dbfs);
|
|
206
|
+
}
|
|
207
|
+
// Tone: a Hann FFT of 4096 samples every 0.5 s, 80 Hz-8 kHz only. A window is tonal when its top 3
|
|
208
|
+
// peaks (±2 bins) hold over 80% of that band's energy; the tone is steady when one peak (±2 bins)
|
|
209
|
+
// holds over half the windows.
|
|
210
|
+
const n = T.tone_fft_size;
|
|
211
|
+
const stride = Math.max(1, Math.round(rate * T.tone_window_s));
|
|
212
|
+
const hann = Float64Array.from({ length: n }, (_, i) => 0.5 - 0.5 * Math.cos((2 * Math.PI * i) / (n - 1)));
|
|
213
|
+
const floor = 10 ** ((2 * T.digital_silence_peak_dbfs) / 20) * n;
|
|
214
|
+
const lowBin = Math.max(2, Math.ceil((T.tone_min_hz * n) / rate));
|
|
215
|
+
const highBin = Math.min(n / 2, Math.floor((T.tone_max_hz * n) / rate));
|
|
216
|
+
const windows = [];
|
|
217
|
+
for (let start = 0; start + n <= samples.length; start += stride) {
|
|
218
|
+
const re = new Float64Array(n);
|
|
219
|
+
const im = new Float64Array(n);
|
|
220
|
+
for (let i = 0; i < n; i++)
|
|
221
|
+
re[i] = samples[start + i] * hann[i];
|
|
222
|
+
fft(re, im);
|
|
223
|
+
const power = new Float64Array(n / 2 + 1);
|
|
224
|
+
let total = 0;
|
|
225
|
+
for (let k = lowBin; k <= highBin; k++) {
|
|
226
|
+
power[k] = re[k] * re[k] + im[k] * im[k];
|
|
227
|
+
total += power[k];
|
|
228
|
+
}
|
|
229
|
+
if (total <= floor) {
|
|
230
|
+
windows.push(null);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
let held = 0;
|
|
234
|
+
let dominant = null;
|
|
235
|
+
for (let p = 0; p < T.tone_max_peaks; p++) {
|
|
236
|
+
let top = 0;
|
|
237
|
+
for (let k = 1; k < power.length; k++)
|
|
238
|
+
if (power[k] > power[top])
|
|
239
|
+
top = k;
|
|
240
|
+
if (power[top] <= 0)
|
|
241
|
+
break;
|
|
242
|
+
dominant ??= top;
|
|
243
|
+
for (let k = Math.max(0, top - T.tone_peak_halfwidth_bins); k <= Math.min(power.length - 1, top + T.tone_peak_halfwidth_bins); k++) {
|
|
244
|
+
held += power[k];
|
|
245
|
+
power[k] = 0;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
windows.push(held / total > T.tone_peak_energy_share ? dominant : null);
|
|
249
|
+
}
|
|
250
|
+
const bins = windows.filter((b) => b !== null);
|
|
251
|
+
let tone_share = 0;
|
|
252
|
+
let tone_hz = null;
|
|
253
|
+
if (bins.length) {
|
|
254
|
+
const near = (bin) => bins.filter((other) => Math.abs(bin - other) <= T.tone_peak_halfwidth_bins).length;
|
|
255
|
+
const mode = bins.reduce((best, bin) => (near(bin) > near(best) ? bin : best), bins[0]);
|
|
256
|
+
tone_share = near(mode) / windows.length;
|
|
257
|
+
tone_hz = Math.round((mode * rate) / n);
|
|
258
|
+
}
|
|
259
|
+
return { peak_dbfs: dbfs(peak), zero_runs_ms, quiet, tone_share, tone_hz };
|
|
260
|
+
}
|
|
261
|
+
/** A 64-bit difference hash of a 9×8 grey picture (row by row): 1 where a pixel is brighter than its right neighbour. */
|
|
262
|
+
function dHash(grey) {
|
|
263
|
+
if (grey.length !== 72)
|
|
264
|
+
throw new Error('dHash needs a 9x8 grey picture');
|
|
265
|
+
let hash = 0n;
|
|
266
|
+
for (let row = 0; row < 8; row++)
|
|
267
|
+
for (let col = 0; col < 8; col++)
|
|
268
|
+
hash = (hash << 1n) | (grey[row * 9 + col] > grey[row * 9 + col + 1] ? 1n : 0n);
|
|
269
|
+
return hash;
|
|
270
|
+
}
|
|
271
|
+
function hamming(a, b) {
|
|
272
|
+
let x = a ^ b;
|
|
273
|
+
let count = 0;
|
|
274
|
+
while (x) {
|
|
275
|
+
count += Number(x & 1n);
|
|
276
|
+
x >>= 1n;
|
|
277
|
+
}
|
|
278
|
+
return count;
|
|
279
|
+
}
|
|
280
|
+
const sentence = (parts) => (parts.length ? `${parts.join('; ').replace(/^./, (c) => c.toUpperCase())}.` : '');
|
|
281
|
+
const seconds = (ms) => `${(ms / 1000).toFixed(1)}`;
|
|
282
|
+
const ranges = (intervals) => intervals.slice(0, 6).map(([a, b]) => `${seconds(a)}–${seconds(b)} s`).join(', ') + (intervals.length > 6 ? ` and ${intervals.length - 6} more` : '');
|
|
283
|
+
/**
|
|
284
|
+
* The checks from what was measured, as the harness's final_measure.py decides them, plus the
|
|
285
|
+
* 15 Oct amendments (an approved silent video, the closing hold, no word timings) and the
|
|
286
|
+
* calibration (opening and closing allowance, 2.0 s mid-video freezes, the reference's still-image
|
|
287
|
+
* share). Pure: the measuring itself is `measureFinal`.
|
|
288
|
+
*/
|
|
289
|
+
function finalMeasureChecks(input) {
|
|
290
|
+
const { durationMs: d, audio, timeline } = input;
|
|
291
|
+
const result = (id, failed, detail, intervals = []) => ({ id, result: failed ? 'fail' : 'pass', detail, intervals_ms: intervals.slice(0, MAX_INTERVALS) });
|
|
292
|
+
const na = (id, detail) => ({ id, result: 'not_applicable', detail, intervals_ms: [] });
|
|
293
|
+
const silent = silentByPlan(timeline);
|
|
294
|
+
const pauses = (timeline?.pauses ?? []).map((p) => ({ ...p, span: [p.start_ms, p.end_ms] }));
|
|
295
|
+
const allowedPauses = pauses.filter((p) => p.scope === 'all_audio' && p.end_ms - p.start_ms <= T.max_pause_ms).map((p) => p.span);
|
|
296
|
+
const planned = (timeline?.visual_overrides ?? []).filter((v) => v.kind === 'freeze');
|
|
297
|
+
const allowedFreezes = planned.filter((v) => v.end_ms - v.start_ms <= maxFreezeMs(v, timeline.duration_ms)).map((v) => [v.start_ms, v.end_ms]);
|
|
298
|
+
const step = T.quiet_window_ms;
|
|
299
|
+
const quiet = audio ? audio.quiet : Array.from({ length: Math.max(1, Math.ceil(d / step)) }, () => true);
|
|
300
|
+
const checks = new Map();
|
|
301
|
+
const add = (c) => checks.set(c.id, c);
|
|
302
|
+
/** True when the part of a run outside the opening and closing allowance is longer than `limitMs`. */
|
|
303
|
+
const tooLong = (r, limitMs) => pastEdges(r, d) > limitMs + 1e-6;
|
|
304
|
+
const allowance = `outside the first ${seconds(T.start_allowance_ms)} s and last ${seconds(T.end_allowance_ms)} s`;
|
|
305
|
+
const silentNote = 'The approved plan is a silent video (speech none, intentional_silence).';
|
|
306
|
+
// Sound.
|
|
307
|
+
if (silent)
|
|
308
|
+
add(na('digital_silence', silentNote));
|
|
309
|
+
else if (!audio)
|
|
310
|
+
add(result('digital_silence', true, 'The final has no sound track.', [[0, d]]));
|
|
311
|
+
else if (audio.peak_dbfs < T.digital_silence_peak_dbfs)
|
|
312
|
+
add(result('digital_silence', true, `The whole sound track peaks at ${Number.isFinite(audio.peak_dbfs) ? `${audio.peak_dbfs.toFixed(1)} dBFS` : 'digital silence'}, below ${T.digital_silence_peak_dbfs} dBFS.`, [[0, d]]));
|
|
313
|
+
else if (audio.zero_runs_ms.some((r) => tooLong(r, T.digital_zero_run_s * 1000))) {
|
|
314
|
+
const zeros = audio.zero_runs_ms.filter((r) => tooLong(r, T.digital_zero_run_s * 1000));
|
|
315
|
+
add(result('digital_silence', true, `Digital silence (exact zero samples) longer than ${T.digital_zero_run_s} s ${allowance} at ${ranges(zeros)}.`, zeros));
|
|
316
|
+
}
|
|
317
|
+
else
|
|
318
|
+
add(result('digital_silence', false, `Peak ${audio.peak_dbfs.toFixed(1)} dBFS; no exact-zero run over ${T.digital_zero_run_s} s ${allowance}.`));
|
|
319
|
+
if (!audio)
|
|
320
|
+
add(na('tone_only', 'The final has no sound track.'));
|
|
321
|
+
else if (audio.tone_share > T.tone_steady_share)
|
|
322
|
+
add(result('tone_only', true, `A steady tone near ${audio.tone_hz} Hz holds ${Math.round(audio.tone_share * 100)}% of the sound track; a sine bed or drone is not music.`, [[0, d]]));
|
|
323
|
+
else
|
|
324
|
+
add(result('tone_only', false, `Steady tonal windows ${Math.round(audio.tone_share * 100)}%.`));
|
|
325
|
+
if (silent)
|
|
326
|
+
add(na('unplanned_silence', silentNote));
|
|
327
|
+
else {
|
|
328
|
+
const unplanned = runs(quiet, step, T.unplanned_silence_s * 1000).map(([a, b]) => [a, Math.min(b, d)]).filter((r) => tooLong(r, T.unplanned_silence_s * 1000) && !covered(r, allowedPauses));
|
|
329
|
+
add(unplanned.length
|
|
330
|
+
? result('unplanned_silence', true, `Silence (quieter than ${T.quiet_dbfs} dBFS) longer than ${T.unplanned_silence_s} s ${allowance}, with no planned all-audio pause of ${seconds(T.max_pause_ms)} s or less around it, at ${ranges(unplanned)}.`, unplanned)
|
|
331
|
+
: result('unplanned_silence', false, 'No unplanned silence over the limit.'));
|
|
332
|
+
}
|
|
333
|
+
// Words: the kit has no word timings of these exact bytes; the server transcribes and decides.
|
|
334
|
+
const words = timeline && timeline.speech_mode !== 'none' ? 'No word timings for these exact bytes; GooseWorks measures this from its own transcript of the final.' : 'No speech planned.';
|
|
335
|
+
add(na('speech_gap_in_sentence', words));
|
|
336
|
+
add(na('first_last_words', words));
|
|
337
|
+
// Timeline plans.
|
|
338
|
+
if (!timeline) {
|
|
339
|
+
add(na('planned_pause_too_long', 'No source-linked timeline.'));
|
|
340
|
+
add(na('planned_freeze_too_long', 'No source-linked timeline.'));
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
const long = pauses.filter((p) => p.end_ms - p.start_ms > T.max_pause_ms).map((p) => p.span);
|
|
344
|
+
const total = merge(pauses.map((p) => p.span)).reduce((sum, [a, b]) => sum + (b - a), 0);
|
|
345
|
+
const detail = [...(long.length ? [`a planned pause is longer than ${seconds(T.max_pause_ms)} s at ${ranges(long)}`] : []), ...(total > T.max_pause_share * d ? [`planned pauses add up to ${seconds(total)} s, over ${Math.round(T.max_pause_share * 100)}% of the video`] : [])];
|
|
346
|
+
add(result('planned_pause_too_long', detail.length > 0, detail.length ? sentence(detail) : 'Planned pauses within the caps.', long));
|
|
347
|
+
const longFreezes = planned.filter((v) => v.end_ms - v.start_ms > maxFreezeMs(v, timeline.duration_ms)).map((v) => [v.start_ms, v.end_ms]);
|
|
348
|
+
add(result('planned_freeze_too_long', longFreezes.length > 0, longFreezes.length ? `A planned freeze is longer than ${seconds(T.max_freeze_ms)} s (${seconds(T.max_end_card_freeze_ms)} s for a closing hold) at ${ranges(longFreezes)}.` : 'Planned freezes within the cap.', longFreezes));
|
|
349
|
+
}
|
|
350
|
+
// Picture.
|
|
351
|
+
{
|
|
352
|
+
const unplanned = input.freezes.filter((f) => tooLong(f, T.unplanned_freeze_s * 1000) && !covered(f, allowedFreezes));
|
|
353
|
+
const share = d > 0 ? input.freezes.reduce((sum, [a, b]) => sum + (b - a), 0) / d : 0;
|
|
354
|
+
const maxShare = maxFrozenShare(input.referenceFrozenShare);
|
|
355
|
+
const shareNote = maxShare > T.max_frozen_share ? `, over the ${Math.round(maxShare * 100)}% the reference allows` : '';
|
|
356
|
+
const detail = [...(unplanned.length ? [`the picture is frozen for more than ${T.unplanned_freeze_s} s ${allowance}, with no planned freeze around it, at ${ranges(unplanned)}`] : []), ...(share > maxShare + 1e-9 ? [`the picture is frozen ${Math.round(share * 100)}% of the time${shareNote} (a still-image ad)`] : [])];
|
|
357
|
+
add(result('frozen_picture', detail.length > 0, detail.length ? sentence(detail) : 'No unplanned frozen picture.', unplanned.length ? unplanned : detail.length ? input.freezes : []));
|
|
358
|
+
}
|
|
359
|
+
if (!input.shots)
|
|
360
|
+
add(na('repeated_shot', 'The final has no shots to compare.'));
|
|
361
|
+
else {
|
|
362
|
+
const shots = [...input.shots].sort((a, b) => a.start_ms - b.start_ms);
|
|
363
|
+
const repeats = [];
|
|
364
|
+
const named = [];
|
|
365
|
+
for (let j = 0; j < shots.length; j++)
|
|
366
|
+
for (let i = 0; i < j - 1; i++) {
|
|
367
|
+
const a = shots[i];
|
|
368
|
+
const b = shots[j];
|
|
369
|
+
if (a.hash === null || b.hash === null || hamming(a.hash, b.hash) > T.repeated_shot_max_hamming)
|
|
370
|
+
continue;
|
|
371
|
+
if (typeof b.intent === 'string' && b.intent.startsWith(CALLBACK))
|
|
372
|
+
continue;
|
|
373
|
+
repeats.push([a.start_ms, a.end_ms], [b.start_ms, b.end_ms]);
|
|
374
|
+
named.push(`${b.id} repeats ${a.id}`);
|
|
375
|
+
}
|
|
376
|
+
add(repeats.length
|
|
377
|
+
? result('repeated_shot', true, `A shot is shown again later: ${named.slice(0, 4).join('; ')}${named.length > 4 ? ` and ${named.length - 4} more` : ''} (${ranges(repeats)}). Use new coverage, or mark a deliberate repeat with intent "${CALLBACK} <reason>".`, repeats)
|
|
378
|
+
: result('repeated_shot', false, `No repeated shots (${shots.length} shots).`));
|
|
379
|
+
}
|
|
380
|
+
if (!timeline?.segments.length)
|
|
381
|
+
add(na('speech_over_silent_face', 'No source-linked timeline marks a speaking face.'));
|
|
382
|
+
else {
|
|
383
|
+
const found = [];
|
|
384
|
+
for (const segment of timeline.segments.filter((s) => s.depicts_speech)) {
|
|
385
|
+
const flags = quiet.filter((_, i) => segment.start_ms <= i * step && (i + 1) * step <= segment.end_ms + 1e-6);
|
|
386
|
+
const offset = Math.ceil(segment.start_ms / step - 1e-9) * step;
|
|
387
|
+
found.push(...runs(flags, step, T.silent_face_s * 1000).map(([a, b]) => [offset + a, offset + b]));
|
|
388
|
+
}
|
|
389
|
+
add(found.length ? result('speech_over_silent_face', true, `Silence longer than ${T.silent_face_s} s while a face is shown speaking, at ${ranges(found)}.`, found) : result('speech_over_silent_face', false, 'Speaking faces have sound.'));
|
|
390
|
+
}
|
|
391
|
+
return exports.FINAL_MEASURE_CHECKS.map((id) => checks.get(id));
|
|
392
|
+
}
|
|
393
|
+
/** The failed checks, in plain words with their time ranges; empty when everything passed. */
|
|
394
|
+
function finalMeasureFailures(measure) {
|
|
395
|
+
return measure.checks.filter((c) => c.result === 'fail').map((c) => `${c.id.replace(/_/g, ' ')}: ${c.detail}`);
|
|
396
|
+
}
|
|
397
|
+
/** Collects one ffmpeg run's stdout (up to `limit` bytes) and stderr text; rejects on a failed exit. */
|
|
398
|
+
function runFfmpeg(ffmpeg, args, signal, limit, timeoutMs) {
|
|
399
|
+
return new Promise((resolve, reject) => {
|
|
400
|
+
const child = (0, child_process_1.spawn)(ffmpeg, args, { stdio: ['ignore', 'pipe', 'pipe'], env: (0, toolchain_1.childEnv)(), signal });
|
|
401
|
+
const out = [];
|
|
402
|
+
let size = 0;
|
|
403
|
+
let stderr = '';
|
|
404
|
+
const timer = setTimeout(() => child.kill('SIGKILL'), timeoutMs);
|
|
405
|
+
child.stdout.on('data', (chunk) => {
|
|
406
|
+
if (size < limit)
|
|
407
|
+
out.push(chunk.subarray(0, limit - size));
|
|
408
|
+
size += chunk.length;
|
|
409
|
+
});
|
|
410
|
+
child.stderr.on('data', (chunk) => {
|
|
411
|
+
if (stderr.length < 4_000_000)
|
|
412
|
+
stderr += chunk.toString('utf8');
|
|
413
|
+
});
|
|
414
|
+
child.on('error', (error) => {
|
|
415
|
+
clearTimeout(timer);
|
|
416
|
+
reject(error);
|
|
417
|
+
});
|
|
418
|
+
child.on('close', (code) => {
|
|
419
|
+
clearTimeout(timer);
|
|
420
|
+
if (code === 0)
|
|
421
|
+
resolve({ stdout: Buffer.concat(out), stderr });
|
|
422
|
+
else
|
|
423
|
+
reject(new Error(`ffmpeg exited with ${code}: ${stderr.slice(-500)}`));
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
/** `start: X` / `end: Y` pairs from an ffmpeg filter log, in ms; an open start runs to the end. */
|
|
428
|
+
function logIntervals(log, startKey, endKey, durationMs) {
|
|
429
|
+
const out = [];
|
|
430
|
+
let opened = null;
|
|
431
|
+
const pattern = new RegExp(`(${startKey}|${endKey}):\\s*([0-9.]+)`, 'g');
|
|
432
|
+
for (const match of log.matchAll(pattern)) {
|
|
433
|
+
const at = Math.min(durationMs, Math.round(Number(match[2]) * 1000));
|
|
434
|
+
if (match[1] === startKey)
|
|
435
|
+
opened = at;
|
|
436
|
+
else if (opened !== null) {
|
|
437
|
+
out.push([opened, at]);
|
|
438
|
+
opened = null;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (opened !== null)
|
|
442
|
+
out.push([opened, durationMs]);
|
|
443
|
+
return out;
|
|
444
|
+
}
|
|
445
|
+
/** Mono samples at this rate are enough for every sound check. */
|
|
446
|
+
const MEASURE_RATE = 16_000;
|
|
447
|
+
/** The longest final the line takes is 180 s; a little more is decoded so a long tail still shows. */
|
|
448
|
+
const MAX_AUDIO_S = 200;
|
|
449
|
+
const TOOL_MS = 600_000;
|
|
450
|
+
/**
|
|
451
|
+
* Measures the final with the kit's ffmpeg: one decode of the sound, one freezedetect pass, a
|
|
452
|
+
* scene-cut pass when no timeline names the shots, and one tiny frame per long shot. Throws when a
|
|
453
|
+
* tool fails, so a missing measurement is never a pass.
|
|
454
|
+
*/
|
|
455
|
+
async function measureFinal(opts) {
|
|
456
|
+
const d = opts.durationMs;
|
|
457
|
+
let audio = null;
|
|
458
|
+
if (opts.hasAudio) {
|
|
459
|
+
const { stdout } = await runFfmpeg(opts.ffmpeg, ['-nostdin', '-v', 'error', '-i', opts.file, '-vn', '-ac', '1', '-ar', String(MEASURE_RATE), '-f', 'f32le', 'pipe:1'], opts.signal, MAX_AUDIO_S * MEASURE_RATE * 4, TOOL_MS);
|
|
460
|
+
const aligned = Buffer.from(stdout.subarray(0, stdout.length - (stdout.length % 4)));
|
|
461
|
+
audio = analyseAudio(new Float32Array(aligned.buffer, aligned.byteOffset, aligned.length / 4), MEASURE_RATE);
|
|
462
|
+
}
|
|
463
|
+
const frozen = await runFfmpeg(opts.ffmpeg, ['-nostdin', '-hide_banner', '-i', opts.file, '-map', '0:v:0', '-vf', `freezedetect=n=${T.freeze_noise}:d=${T.freeze_min_s}`, '-f', 'null', '-'], opts.signal, 0, TOOL_MS);
|
|
464
|
+
const freezes = logIntervals(frozen.stderr, 'lavfi.freezedetect.freeze_start', 'lavfi.freezedetect.freeze_end', d);
|
|
465
|
+
let listed;
|
|
466
|
+
if (opts.timeline?.segments.length)
|
|
467
|
+
listed = opts.timeline.segments.map((s) => ({ id: s.id, start_ms: s.start_ms, end_ms: s.end_ms, ...(s.intent ? { intent: s.intent } : {}) }));
|
|
468
|
+
else {
|
|
469
|
+
const scenes = await runFfmpeg(opts.ffmpeg, ['-nostdin', '-hide_banner', '-i', opts.file, '-map', '0:v:0', '-vf', `select='gt(scene,${T.scene_cut_threshold})',showinfo`, '-f', 'null', '-'], opts.signal, 0, TOOL_MS);
|
|
470
|
+
const cuts = [...new Set([...scenes.stderr.matchAll(/pts_time:\s*([0-9.]+)/g)].map((m) => Math.round(Number(m[1]) * 1000)).filter((at) => at > 0 && at < d))].sort((a, b) => a - b);
|
|
471
|
+
const edges = [0, ...cuts, d];
|
|
472
|
+
listed = edges.slice(1).map((end, i) => ({ id: `shot-${i + 1}`, start_ms: edges[i], end_ms: end }));
|
|
473
|
+
}
|
|
474
|
+
const shots = [];
|
|
475
|
+
for (const shot of listed) {
|
|
476
|
+
let hash = null;
|
|
477
|
+
if (shot.end_ms - shot.start_ms > T.repeated_shot_min_s * 1000) {
|
|
478
|
+
const at = ((shot.start_ms + shot.end_ms) / 2000).toFixed(3);
|
|
479
|
+
const { stdout } = await runFfmpeg(opts.ffmpeg, ['-nostdin', '-v', 'error', '-ss', at, '-i', opts.file, '-frames:v', '1', '-vf', 'scale=9:8:flags=area,format=gray', '-f', 'rawvideo', 'pipe:1'], opts.signal, 72, 60_000);
|
|
480
|
+
hash = stdout.length === 72 ? dHash(new Uint8Array(stdout)) : null;
|
|
481
|
+
}
|
|
482
|
+
shots.push({ ...shot, hash });
|
|
483
|
+
}
|
|
484
|
+
return {
|
|
485
|
+
format: exports.FINAL_MEASURE_FORMAT,
|
|
486
|
+
output_sha256: opts.outputSha256,
|
|
487
|
+
measured_duration_ms: d,
|
|
488
|
+
checks: finalMeasureChecks({ durationMs: d, audio, freezes, shots, timeline: opts.timeline, referenceFrozenShare: opts.referenceFrozenShare }),
|
|
489
|
+
thresholds: exports.FINAL_MEASURE_THRESHOLDS,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
//# sourceMappingURL=final-measure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"final-measure.js","sourceRoot":"","sources":["../../../src/kit/core/final-measure.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ProgressStep } from '../line/types';
|
|
2
|
-
import { type SheetTile } from './eyes';
|
|
2
|
+
import { type Eyes, type SheetTile, type ReviewAudio } from './eyes';
|
|
3
3
|
import { type RunLayout } from './paths';
|
|
4
4
|
import type { MakeResult } from './run';
|
|
5
5
|
/** The exit code of each outcome. 2 is left to the command line's own usage errors. */
|
|
@@ -106,6 +106,10 @@ export interface VerifyRecord {
|
|
|
106
106
|
/** What the final checks noted without failing the video. */
|
|
107
107
|
warnings: string[];
|
|
108
108
|
look_for: string[];
|
|
109
|
+
review_status?: 'required' | 'incomplete';
|
|
110
|
+
output_sha256?: string;
|
|
111
|
+
coverage?: Eyes['coverage'];
|
|
112
|
+
audio?: ReviewAudio;
|
|
109
113
|
}
|
|
110
114
|
/** Reads the finished video's folder for `video verify`. */
|
|
111
115
|
export declare function verifyOf(home: string, videoId: string): Promise<VerifyRecord>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../../../src/kit/core/outcome.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../../../src/kit/core/outcome.ts"],"names":[],"mappings":"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"}
|
package/dist/kit/core/outcome.js
CHANGED
|
@@ -49,6 +49,7 @@ const promises_1 = require("fs/promises");
|
|
|
49
49
|
const fs_1 = require("fs");
|
|
50
50
|
const path = __importStar(require("path"));
|
|
51
51
|
const eyes_1 = require("./eyes");
|
|
52
|
+
const files_1 = require("./files");
|
|
52
53
|
const paths_1 = require("./paths");
|
|
53
54
|
const save_1 = require("./save");
|
|
54
55
|
/** The exit code of each outcome. 2 is left to the command line's own usage errors. */
|
|
@@ -219,13 +220,19 @@ async function verifyOf(home, videoId) {
|
|
|
219
220
|
// Only the final the last run finished and our server passed: never a leftover from a run that ended otherwise.
|
|
220
221
|
if (!made || result?.status !== 'done' || result.final !== final)
|
|
221
222
|
return record;
|
|
223
|
+
const current = await (0, files_1.hashFile)(final).catch(() => null);
|
|
224
|
+
const sameOutput = Boolean(current && eyes?.output_sha256 && current.sha256 === eyes.output_sha256);
|
|
222
225
|
const sheet = typeof eyes?.contact_sheet === 'string' ? eyes.contact_sheet : null;
|
|
226
|
+
const sheetReady = Boolean(sheet && await (0, promises_1.stat)(sheet).then((info) => info.isFile(), () => false));
|
|
223
227
|
const warned = Array.isArray(result.warnings) ? result.warnings : (eyes?.warnings ?? []).map((w) => w.message);
|
|
228
|
+
const audioReady = !eyes?.audio?.required || Boolean(eyes.audio.final_mix && !eyes.warnings?.some((warning) => warning.check === 'review_audio') && (await Promise.all([eyes.audio.final_mix, ...(eyes.audio.before_sound ? [eyes.audio.before_sound] : [])].map((file) => (0, promises_1.stat)(file).then((info) => info.isFile(), () => false)))).every(Boolean));
|
|
224
229
|
return {
|
|
225
230
|
...record,
|
|
226
231
|
final,
|
|
227
|
-
...(
|
|
228
|
-
|
|
232
|
+
...(sameOutput && sheetReady ? { contact_sheet: sheet, tiles: eyes.tiles } : {}),
|
|
233
|
+
...(sameOutput ? { output_sha256: current.sha256, coverage: eyes?.coverage, audio: eyes?.audio } : {}),
|
|
234
|
+
review_status: sameOutput && sheetReady && eyes?.coverage?.complete && audioReady ? 'required' : 'incomplete',
|
|
235
|
+
warnings: [...warned.filter((w) => typeof w === 'string'), ...(!sameOutput ? ['Review evidence is missing or belongs to different output bytes. Review the actual current video.'] : [])],
|
|
229
236
|
};
|
|
230
237
|
}
|
|
231
238
|
/** `video verify` for the person, or the AI, about to say the video is ready. */
|
|
@@ -237,6 +244,11 @@ function verifyLines(found) {
|
|
|
237
244
|
found.contact_sheet
|
|
238
245
|
? `Its frame sheet: ${found.contact_sheet} (frames across the video, labelled by scene: S2 4.1 is scene 2 at 4.1 seconds, END the end card)`
|
|
239
246
|
: 'No frame sheet was made for it, so watch the video itself.',
|
|
247
|
+
'File checks passed; picture and audio review is still required. This command does not certify clean speech or correct product scale.',
|
|
248
|
+
...(found.audio?.final_mix ? [`Full final audio: ${found.audio.final_mix}`] : []),
|
|
249
|
+
...(found.audio?.before_sound ? [`Audio before the sound layer: ${found.audio.before_sound} (may contain source ambience; compare it with the final mix)`] : []),
|
|
250
|
+
...(found.audio?.windows ?? []).map((window) => `Listen closely at ${window.start_s.toFixed(2)}–${window.end_s.toFixed(2)} seconds (${window.reason === 'cut' ? 'cut boundary' : 'gap between recognised words; may be intentional silence'}).`),
|
|
251
|
+
...(found.review_status === 'incomplete' ? ['Review evidence is incomplete. Do not call the video ready until the missing checks are performed on the actual output.'] : []),
|
|
240
252
|
'Before you say it is ready, check:',
|
|
241
253
|
...found.look_for.map((item) => `- ${item}`),
|
|
242
254
|
'If any of that is wrong, it isn’t ready: say what you saw and fix that scene first.',
|