@bitmagic/asset-core 0.2.25-dev.0 → 0.2.25-dev.1

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.
Files changed (89) hide show
  1. package/dist/trailer/analyze.d.ts +24 -0
  2. package/dist/trailer/analyze.d.ts.map +1 -0
  3. package/dist/trailer/analyze.js +186 -0
  4. package/dist/trailer/analyze.js.map +1 -0
  5. package/dist/trailer/auto-edl.d.ts +51 -0
  6. package/dist/trailer/auto-edl.d.ts.map +1 -0
  7. package/dist/trailer/auto-edl.js +266 -0
  8. package/dist/trailer/auto-edl.js.map +1 -0
  9. package/dist/trailer/beat-cut.d.ts +58 -0
  10. package/dist/trailer/beat-cut.d.ts.map +1 -0
  11. package/dist/trailer/beat-cut.js +232 -0
  12. package/dist/trailer/beat-cut.js.map +1 -0
  13. package/dist/trailer/capture.d.ts +102 -0
  14. package/dist/trailer/capture.d.ts.map +1 -0
  15. package/dist/trailer/capture.js +268 -0
  16. package/dist/trailer/capture.js.map +1 -0
  17. package/dist/trailer/edl-time.d.ts +62 -0
  18. package/dist/trailer/edl-time.d.ts.map +1 -0
  19. package/dist/trailer/edl-time.js +105 -0
  20. package/dist/trailer/edl-time.js.map +1 -0
  21. package/dist/trailer/errors.d.ts +15 -0
  22. package/dist/trailer/errors.d.ts.map +1 -0
  23. package/dist/trailer/errors.js +22 -0
  24. package/dist/trailer/errors.js.map +1 -0
  25. package/dist/trailer/ffmpeg.d.ts +19 -0
  26. package/dist/trailer/ffmpeg.d.ts.map +1 -0
  27. package/dist/trailer/ffmpeg.js +100 -0
  28. package/dist/trailer/ffmpeg.js.map +1 -0
  29. package/dist/trailer/hud-state.d.ts +182 -0
  30. package/dist/trailer/hud-state.d.ts.map +1 -0
  31. package/dist/trailer/hud-state.js +523 -0
  32. package/dist/trailer/hud-state.js.map +1 -0
  33. package/dist/trailer/index.d.ts +30 -0
  34. package/dist/trailer/index.d.ts.map +1 -0
  35. package/dist/trailer/index.js +30 -0
  36. package/dist/trailer/index.js.map +1 -0
  37. package/dist/trailer/io.d.ts +23 -0
  38. package/dist/trailer/io.d.ts.map +1 -0
  39. package/dist/trailer/io.js +20 -0
  40. package/dist/trailer/io.js.map +1 -0
  41. package/dist/trailer/link.d.ts +2 -0
  42. package/dist/trailer/link.d.ts.map +1 -0
  43. package/dist/trailer/link.js +15 -0
  44. package/dist/trailer/link.js.map +1 -0
  45. package/dist/trailer/make.d.ts +60 -0
  46. package/dist/trailer/make.d.ts.map +1 -0
  47. package/dist/trailer/make.js +196 -0
  48. package/dist/trailer/make.js.map +1 -0
  49. package/dist/trailer/merge.d.ts +8 -0
  50. package/dist/trailer/merge.d.ts.map +1 -0
  51. package/dist/trailer/merge.js +165 -0
  52. package/dist/trailer/merge.js.map +1 -0
  53. package/dist/trailer/music-beats.d.ts +124 -0
  54. package/dist/trailer/music-beats.d.ts.map +1 -0
  55. package/dist/trailer/music-beats.js +672 -0
  56. package/dist/trailer/music-beats.js.map +1 -0
  57. package/dist/trailer/paths.d.ts +29 -0
  58. package/dist/trailer/paths.d.ts.map +1 -0
  59. package/dist/trailer/paths.js +101 -0
  60. package/dist/trailer/paths.js.map +1 -0
  61. package/dist/trailer/png.d.ts +10 -0
  62. package/dist/trailer/png.d.ts.map +1 -0
  63. package/dist/trailer/png.js +37 -0
  64. package/dist/trailer/png.js.map +1 -0
  65. package/dist/trailer/render.d.ts +93 -0
  66. package/dist/trailer/render.d.ts.map +1 -0
  67. package/dist/trailer/render.js +527 -0
  68. package/dist/trailer/render.js.map +1 -0
  69. package/dist/trailer/revision.d.ts +9 -0
  70. package/dist/trailer/revision.d.ts.map +1 -0
  71. package/dist/trailer/revision.js +31 -0
  72. package/dist/trailer/revision.js.map +1 -0
  73. package/dist/trailer/synth.d.ts +10 -0
  74. package/dist/trailer/synth.d.ts.map +1 -0
  75. package/dist/trailer/synth.js +120 -0
  76. package/dist/trailer/synth.js.map +1 -0
  77. package/dist/trailer/timeline-types.d.ts +196 -0
  78. package/dist/trailer/timeline-types.d.ts.map +1 -0
  79. package/dist/trailer/timeline-types.js +419 -0
  80. package/dist/trailer/timeline-types.js.map +1 -0
  81. package/dist/trailer/titles.d.ts +38 -0
  82. package/dist/trailer/titles.d.ts.map +1 -0
  83. package/dist/trailer/titles.js +110 -0
  84. package/dist/trailer/titles.js.map +1 -0
  85. package/dist/trailer/video-chain.d.ts +130 -0
  86. package/dist/trailer/video-chain.d.ts.map +1 -0
  87. package/dist/trailer/video-chain.js +261 -0
  88. package/dist/trailer/video-chain.js.map +1 -0
  89. package/package.json +5 -1
@@ -0,0 +1,523 @@
1
+ import { exclusiveOutputEnd, sourceFrameToOutputSec } from './edl-time.js';
2
+ import { warn } from './io.js';
3
+ /**
4
+ * Engine-owned chrome that lives in the HUD element registry but must never
5
+ * reach a trailer: interactive controls the viewer can't click in a video.
6
+ * `mute-button` is `MuteControl`'s custom element (engine/ui/MuteControl.ts).
7
+ */
8
+ export const CHROME_ELEMENT_IDS = new Set(['mute-button', 'pause-button']);
9
+ /**
10
+ * Where to lay the HUD out for rasterization.
11
+ *
12
+ * During capture only the CANVAS is resized to the recording resolution — the
13
+ * DOM HUD keeps laying out against the player's window. Rastering at the
14
+ * recording size therefore renders every fixed-pixel HUD metric too small
15
+ * relative to the footage (and flips vw-clamps and media queries). With the
16
+ * recorded window known, raster at an ASPECT-CORRECTED viewport: the window's
17
+ * height (so element size relative to screen height matches what the player
18
+ * saw) at the recording's aspect (raw window dimensions would stretch glyphs
19
+ * non-uniformly under the final scale whenever the aspects differ). The
20
+ * deviceScaleFactor keeps the PNG at or above the recording resolution so
21
+ * ffmpeg only ever downscales.
22
+ *
23
+ * No recorded window → the recording resolution at 1x, bit-for-bit the old
24
+ * behavior.
25
+ */
26
+ export function computeRasterGeometry(recordingWidth, recordingHeight, window) {
27
+ if (window === undefined) {
28
+ return { viewportWidth: recordingWidth, viewportHeight: recordingHeight, deviceScaleFactor: 1 };
29
+ }
30
+ const viewportHeight = Math.max(1, Math.round(window.innerHeight));
31
+ const viewportWidth = Math.max(1, Math.round(viewportHeight * (recordingWidth / recordingHeight)));
32
+ const deviceScaleFactor = Math.max(1, recordingHeight / viewportHeight);
33
+ return { viewportWidth, viewportHeight, deviceScaleFactor };
34
+ }
35
+ // ---------------------------------------------------------------------------
36
+ // Defaults
37
+ // ---------------------------------------------------------------------------
38
+ /** The engine records `frame` on a 60fps source clock. */
39
+ export const DEFAULT_HUD_FPS = 60;
40
+ /** IGameHUD.showToast's default duration. */
41
+ export const DEFAULT_TOAST_MS = 2500;
42
+ /** IGameHUD's per-kind default anchor, used when a create op omits one. */
43
+ const DEFAULT_ANCHOR = {
44
+ progress: 'top-left',
45
+ counter: 'top-right',
46
+ 'icon-text': 'bottom-left',
47
+ timer: 'top-center',
48
+ custom: 'top-left'
49
+ };
50
+ /** Derived timer seconds are rounded to this many decimals for a stable key. */
51
+ const SECONDS_DECIMALS = 3;
52
+ // ---------------------------------------------------------------------------
53
+ // Reduction
54
+ // ---------------------------------------------------------------------------
55
+ function readString(params, key) {
56
+ const value = params[key];
57
+ return typeof value === 'string' ? value : undefined;
58
+ }
59
+ function readNumber(params, key) {
60
+ const value = params[key];
61
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
62
+ }
63
+ function readBoolean(params, key) {
64
+ const value = params[key];
65
+ return typeof value === 'boolean' ? value : undefined;
66
+ }
67
+ function round(value) {
68
+ const factor = 10 ** SECONDS_DECIMALS;
69
+ return Math.round(value * factor) / factor;
70
+ }
71
+ /**
72
+ * Incremental reducer over a frame-sorted op stream. Public callers go through
73
+ * `reduceHudState`; `collectUiKeyframes` drives one instance forward across a
74
+ * clip so a frame-by-frame walk stays linear in the op count.
75
+ */
76
+ /**
77
+ * Whether a container's recorded cssText hides it outright.
78
+ *
79
+ * Visibility has two records: the show/hide ops, and the `display` inside the
80
+ * cssText snapshot the recorder takes on create and on every update (a game
81
+ * that toggles `container.style.display` itself, as the docs' Weapon Wheel
82
+ * does, never logs a hide op). Neither is authoritative alone — the most
83
+ * recent one in frame order is, and only the reducer sees that order — so a
84
+ * css snapshot sets `visible` here and later show/hide ops override it.
85
+ */
86
+ function cssHidesElement(css) {
87
+ return /(^|;)\s*display\s*:\s*none\b/i.test(css);
88
+ }
89
+ class HudReducer {
90
+ constructor(ops, fps) {
91
+ this.cursor = 0;
92
+ this.hudVisible = true;
93
+ this.health = null;
94
+ this.theme = null;
95
+ this.elements = [];
96
+ this.toasts = [];
97
+ /** Insertion-ordered; a re-logged id updates in place (last write wins). */
98
+ this.stylesheets = new Map();
99
+ /** The emitted stylesheet array, rebuilt only when a sheet actually changes. */
100
+ this.stylesheetsEmitted = [];
101
+ /** Bumped with every real change to the set above; `stateKey` identifies the set by it. */
102
+ this.stylesheetsVersion = 0;
103
+ // Stable sort: entries recorded on the same frame keep emission order,
104
+ // which IS the stacking order within an anchor.
105
+ this.ops = [...ops].sort((a, b) => a.frame - b.frame);
106
+ this.fps = fps;
107
+ }
108
+ /** Apply every op at or before `frame`. Frames must not go backwards. */
109
+ advanceTo(frame) {
110
+ while (this.cursor < this.ops.length && this.ops[this.cursor].frame <= frame) {
111
+ this.apply(this.ops[this.cursor]);
112
+ this.cursor++;
113
+ }
114
+ }
115
+ find(id) {
116
+ return this.elements.find((el) => el.id === id);
117
+ }
118
+ apply(op) {
119
+ // Engine chrome is part of the HUD but never part of a trailer. A
120
+ // stylesheet op's `id` is a head <style> element's id, a different
121
+ // namespace from HUD element ids, so it must not be filtered here — a game
122
+ // sheet named after a chrome element would otherwise vanish silently.
123
+ if (op.op !== 'stylesheet' && 'id' in op && CHROME_ELEMENT_IDS.has(op.id))
124
+ return;
125
+ switch (op.op) {
126
+ case 'create':
127
+ this.applyCreate(op.frame, op.id, op.elType, op.params);
128
+ break;
129
+ case 'update':
130
+ this.applyUpdate(op.id, op.text, op.icon, op.percent);
131
+ break;
132
+ case 'custom-html': {
133
+ const el = this.find(op.id);
134
+ if (el !== undefined) {
135
+ el.html = op.html;
136
+ // The container's own cssText rides updates too (onUpdate mutates it
137
+ // as freely as the markup); absent on older recordings. Its display
138
+ // is a visibility verdict of its own — see cssHidesElement.
139
+ if (op.css !== undefined) {
140
+ el.css = op.css;
141
+ el.visible = !cssHidesElement(op.css);
142
+ }
143
+ }
144
+ break;
145
+ }
146
+ case 'timer':
147
+ this.applyTimer(op.frame, op.id, op.action, op.seconds);
148
+ break;
149
+ case 'show':
150
+ case 'hide': {
151
+ const el = this.find(op.id);
152
+ if (el !== undefined)
153
+ el.visible = op.op === 'show';
154
+ break;
155
+ }
156
+ case 'remove': {
157
+ const index = this.elements.findIndex((el) => el.id === op.id);
158
+ if (index >= 0)
159
+ this.elements.splice(index, 1);
160
+ break;
161
+ }
162
+ case 'health': {
163
+ const width = this.health?.width;
164
+ this.health = { current: op.current, max: op.max, visible: this.health?.visible ?? false };
165
+ if (width !== undefined)
166
+ this.health.width = width;
167
+ break;
168
+ }
169
+ case 'health-visible': {
170
+ const width = op.width ?? this.health?.width;
171
+ this.health = {
172
+ current: this.health?.current ?? 0,
173
+ max: this.health?.max ?? 100,
174
+ visible: op.visible
175
+ };
176
+ if (width !== undefined)
177
+ this.health.width = width;
178
+ break;
179
+ }
180
+ case 'toast': {
181
+ const durationMs = op.durationMs ?? DEFAULT_TOAST_MS;
182
+ const toast = {
183
+ message: op.message,
184
+ startFrame: op.frame,
185
+ endFrame: op.frame + (durationMs / 1000) * this.fps
186
+ };
187
+ if (op.variant !== undefined)
188
+ toast.variant = op.variant;
189
+ if (op.anchor !== undefined)
190
+ toast.anchor = op.anchor;
191
+ this.toasts.push(toast);
192
+ break;
193
+ }
194
+ case 'hud-visible':
195
+ this.hudVisible = op.visible;
196
+ break;
197
+ case 'theme':
198
+ this.theme = op.theme;
199
+ break;
200
+ case 'stylesheet': {
201
+ // An empty css body is a tombstone: the recorder logs it when a sheet
202
+ // it had captured disappears from the head, so a skin swapped by
203
+ // removal does not replay with both skins applied at once.
204
+ const removed = op.css === '';
205
+ if (removed ? !this.stylesheets.delete(op.id) : this.stylesheets.get(op.id) === op.css)
206
+ break;
207
+ if (!removed)
208
+ this.stylesheets.set(op.id, op.css);
209
+ this.stylesheetsEmitted = [...this.stylesheets].map(([id, css]) => ({ id, css }));
210
+ this.stylesheetsVersion++;
211
+ break;
212
+ }
213
+ default:
214
+ // Forward compatibility: a newer engine may log ops we predate.
215
+ break;
216
+ }
217
+ }
218
+ applyCreate(frame, id, elType, params) {
219
+ // Re-creating an id replaces the old element and re-appends it, matching
220
+ // the DOM's append-on-create stacking.
221
+ const existing = this.elements.findIndex((el) => el.id === id);
222
+ if (existing >= 0)
223
+ this.elements.splice(existing, 1);
224
+ const css = readString(params, 'css');
225
+ const el = {
226
+ id,
227
+ type: elType,
228
+ anchor: readString(params, 'anchor') ?? DEFAULT_ANCHOR[elType] ?? 'top-left',
229
+ visible: css === undefined || !cssHidesElement(css)
230
+ };
231
+ const label = readString(params, 'label');
232
+ const color = readString(params, 'color');
233
+ const width = readNumber(params, 'width');
234
+ const showText = readBoolean(params, 'showText');
235
+ const percent = readNumber(params, 'percent');
236
+ const icon = readString(params, 'icon');
237
+ const text = readString(params, 'text');
238
+ const iconSize = readNumber(params, 'iconSize');
239
+ const countDown = readBoolean(params, 'countDown');
240
+ const format = readString(params, 'format');
241
+ const html = readString(params, 'html');
242
+ if (label !== undefined)
243
+ el.label = label;
244
+ if (color !== undefined)
245
+ el.color = color;
246
+ if (width !== undefined)
247
+ el.width = width;
248
+ if (showText !== undefined)
249
+ el.showText = showText;
250
+ if (percent !== undefined)
251
+ el.percent = percent;
252
+ if (icon !== undefined)
253
+ el.icon = icon;
254
+ if (text !== undefined)
255
+ el.text = text;
256
+ if (iconSize !== undefined)
257
+ el.iconSize = iconSize;
258
+ if (countDown !== undefined)
259
+ el.countDown = countDown;
260
+ if (format !== undefined)
261
+ el.format = format;
262
+ if (html !== undefined)
263
+ el.html = html;
264
+ if (css !== undefined)
265
+ el.css = css;
266
+ if (elType === 'timer') {
267
+ const seconds = readNumber(params, 'seconds') ?? 0;
268
+ el.timer = { anchorSeconds: seconds, anchorFrame: frame, running: false, createSeconds: seconds };
269
+ }
270
+ this.elements.push(el);
271
+ }
272
+ applyUpdate(id, text, icon, percent) {
273
+ const el = this.find(id);
274
+ if (el === undefined)
275
+ return; // updates can trail a remove
276
+ if (text !== undefined)
277
+ el.text = text;
278
+ if (icon !== undefined)
279
+ el.icon = icon;
280
+ if (percent !== undefined)
281
+ el.percent = percent;
282
+ }
283
+ applyTimer(frame, id, action, seconds) {
284
+ const el = this.find(id);
285
+ const timer = el?.timer;
286
+ if (el === undefined || timer === undefined)
287
+ return;
288
+ switch (action) {
289
+ case 'start':
290
+ timer.anchorSeconds = seconds ?? derivedSeconds(timer, frame, el.countDown ?? false, this.fps);
291
+ timer.anchorFrame = frame;
292
+ timer.running = true;
293
+ break;
294
+ case 'pause':
295
+ timer.anchorSeconds = derivedSeconds(timer, frame, el.countDown ?? false, this.fps);
296
+ timer.anchorFrame = frame;
297
+ timer.running = false;
298
+ break;
299
+ case 'reset':
300
+ timer.anchorSeconds = seconds ?? timer.createSeconds;
301
+ timer.anchorFrame = frame;
302
+ timer.running = false;
303
+ break;
304
+ }
305
+ }
306
+ /** The replay state as of `frame`. Requires `advanceTo(frame)` first. */
307
+ snapshot(frame) {
308
+ this.toasts = this.toasts.filter((t) => t.endFrame > frame);
309
+ return {
310
+ version: 1,
311
+ hudVisible: this.hudVisible,
312
+ health: this.health === null ? null : { ...this.health },
313
+ theme: this.theme,
314
+ elements: this.elements.map((el) => emitElement(el, frame, this.fps)),
315
+ toasts: this.toasts
316
+ .filter((t) => t.startFrame <= frame)
317
+ .map((t) => {
318
+ const toast = { message: t.message };
319
+ if (t.variant !== undefined)
320
+ toast.variant = t.variant;
321
+ if (t.anchor !== undefined)
322
+ toast.anchor = t.anchor;
323
+ return toast;
324
+ }),
325
+ stylesheets: this.stylesheetsEmitted
326
+ };
327
+ }
328
+ }
329
+ function derivedSeconds(timer, frame, countDown, fps) {
330
+ if (!timer.running)
331
+ return timer.anchorSeconds;
332
+ const elapsed = Math.max(0, frame - timer.anchorFrame) / fps;
333
+ return countDown ? Math.max(0, timer.anchorSeconds - elapsed) : timer.anchorSeconds + elapsed;
334
+ }
335
+ /** Build the emitted element, in a fixed key order, omitting unset optionals. */
336
+ function emitElement(el, frame, fps) {
337
+ const state = { id: el.id, type: el.type, anchor: el.anchor, visible: el.visible };
338
+ if (el.label !== undefined)
339
+ state.label = el.label;
340
+ if (el.color !== undefined)
341
+ state.color = el.color;
342
+ if (el.width !== undefined)
343
+ state.width = el.width;
344
+ if (el.showText !== undefined)
345
+ state.showText = el.showText;
346
+ if (el.percent !== undefined)
347
+ state.percent = el.percent;
348
+ if (el.icon !== undefined)
349
+ state.icon = el.icon;
350
+ if (el.text !== undefined)
351
+ state.text = el.text;
352
+ if (el.iconSize !== undefined)
353
+ state.iconSize = el.iconSize;
354
+ if (el.timer !== undefined)
355
+ state.seconds = round(derivedSeconds(el.timer, frame, el.countDown ?? false, fps));
356
+ if (el.countDown !== undefined)
357
+ state.countDown = el.countDown;
358
+ if (el.format !== undefined)
359
+ state.format = el.format;
360
+ if (el.html !== undefined)
361
+ state.html = el.html;
362
+ if (el.css !== undefined)
363
+ state.css = el.css;
364
+ return state;
365
+ }
366
+ /**
367
+ * The complete HUD state at `frame`. Ops after `frame` are ignored; unknown
368
+ * op names are skipped rather than throwing.
369
+ */
370
+ export function reduceHudState(ops, frame, fps = DEFAULT_HUD_FPS) {
371
+ const reducer = new HudReducer(ops, fps);
372
+ reducer.advanceTo(frame);
373
+ return reducer.snapshot(frame);
374
+ }
375
+ /** True when a state would rasterize to a fully transparent frame. */
376
+ export function isBlankHudState(state) {
377
+ if (!state.hudVisible)
378
+ return true;
379
+ if (state.toasts.length > 0)
380
+ return false;
381
+ if (state.health !== null && state.health.visible)
382
+ return false;
383
+ return !state.elements.some((el) => el.visible);
384
+ }
385
+ /**
386
+ * 30, not 15: measured on a real cut, the selected footage held 227 distinct
387
+ * HUD states across 15.3 s of output (14.8/s average, four of seven clips over
388
+ * 15/s), so a 15/s ceiling was discarding roughly 45% of the HUD motion the
389
+ * game actually rendered.
390
+ *
391
+ * ffmpeg used to be the reason for a low ceiling — one PNG input plus one
392
+ * serial overlay node per keyframe cost ~23 MB of RSS each and corrupted the
393
+ * render above ~400. The overlays now ride one densified image2 sequence whose
394
+ * cost is flat in keyframe count (measured 2.83 s / 0.94 GB at both 126 and
395
+ * 902 distinct rasters), so the remaining cost is ~25 ms of Playwright per
396
+ * keyframe plus its PNG on disk. 0 disables the limit entirely.
397
+ */
398
+ export const DEFAULT_MAX_KEYFRAMES_PER_SECOND = 30;
399
+ /**
400
+ * Sole per-clip ceiling, a backstop for `--ui-keyframe-rate 0`: at any real
401
+ * rate the limiter below admits at most rate·duration+1 keyframes per clip on
402
+ * its own, so nothing else can bind. A fixed 240 used to freeze the overlay
403
+ * after 16 s of any clip busy enough to sustain the default rate — exactly the
404
+ * clip a trailer is cut from. 60 s of output at 60/s.
405
+ */
406
+ export const MAX_KEYFRAMES_PER_CLIP_CEILING = 3600;
407
+ /**
408
+ * Frame times are exact ratios that land just under a spacing boundary in
409
+ * binary (frame 18 at 60fps is 0.09999999999999998s after frame 12), which
410
+ * would otherwise push every subsequent keyframe a frame later.
411
+ */
412
+ const SPACING_EPSILON = 1e-9;
413
+ /**
414
+ * Structural identity of a state. Timer seconds collapse to whole displayed
415
+ * seconds (floor — where both floor- and ceil-based formatters change), so a
416
+ * ticking clock yields ~1 keyframe per second instead of one per frame.
417
+ *
418
+ * Stylesheets are keyed by the reducer's change counter, not their bytes: the
419
+ * payload can run to the recorder's 128 KB budget and would otherwise be
420
+ * re-serialized once per source frame. Keys are only ever compared within one
421
+ * reducer's clip, so a per-reducer counter is exact — a set that changes and
422
+ * changes back emits one extra byte-identical keyframe, which is harmless.
423
+ */
424
+ function stateKey(state, stylesheetsVersion) {
425
+ const { stylesheets, ...rest } = state;
426
+ return (JSON.stringify({
427
+ ...rest,
428
+ elements: state.elements.map((el) => el.seconds === undefined ? el : { ...el, seconds: Math.floor(el.seconds) })
429
+ }) + (stylesheets.length === 0 ? '|none' : `|s${stylesheetsVersion}`));
430
+ }
431
+ /**
432
+ * Walk every enabled clip's source range and emit a keyframe wherever the
433
+ * reduced HUD state changes.
434
+ *
435
+ * A clip's overlays stop at `exclusiveOutputEnd`, so during a crossfade the
436
+ * incoming clip's UI takes over at the fade start and exactly one overlay is
437
+ * ever active — two stacked HUDs would double-draw every element.
438
+ */
439
+ export function collectUiKeyframes(ops, clips, opts = {}) {
440
+ const fps = opts.fps ?? DEFAULT_HUD_FPS;
441
+ const maxPerSecond = opts.maxPerSecond ?? DEFAULT_MAX_KEYFRAMES_PER_SECOND;
442
+ const clipEnabled = opts.clipEnabled ?? (() => true);
443
+ const log = opts.log ?? warn;
444
+ const minSpacingSec = maxPerSecond > 0 ? 1 / maxPerSecond : 0;
445
+ const keyframes = [];
446
+ for (let index = 0; index < clips.length; index++) {
447
+ if (!clipEnabled(index))
448
+ continue;
449
+ const timing = clips[index];
450
+ const windowEnd = exclusiveOutputEnd(clips, index);
451
+ const reducer = new HudReducer(ops, fps);
452
+ const maxPerClip = opts.maxPerClip ?? MAX_KEYFRAMES_PER_CLIP_CEILING;
453
+ const clipFrames = [];
454
+ let lastEmittedKey = null;
455
+ let lastEmittedSec = Number.NEGATIVE_INFINITY;
456
+ // The newest state still waiting for a slot; superseding it loses it.
457
+ let pendingKey = null;
458
+ let coalesced = 0;
459
+ let droppedByCap = 0;
460
+ let capped = false;
461
+ let firstDroppedFrame = -1;
462
+ for (let frame = timing.in; frame < timing.out; frame++) {
463
+ const outputSec = sourceFrameToOutputSec(timing, frame, fps);
464
+ if (outputSec >= windowEnd)
465
+ break;
466
+ reducer.advanceTo(frame);
467
+ const state = reducer.snapshot(frame);
468
+ const key = stateKey(state, reducer.stylesheetsVersion);
469
+ if (key === lastEmittedKey)
470
+ continue;
471
+ if (clipFrames.length >= maxPerClip) {
472
+ if (pendingKey !== null && pendingKey !== key)
473
+ droppedByCap++;
474
+ if (!capped)
475
+ firstDroppedFrame = frame;
476
+ capped = true;
477
+ pendingKey = key;
478
+ continue;
479
+ }
480
+ if (outputSec - lastEmittedSec < minSpacingSec - SPACING_EPSILON) {
481
+ // Rate limited: hold, and emit the newest state once spacing allows.
482
+ if (pendingKey !== null && pendingKey !== key)
483
+ coalesced++;
484
+ pendingKey = key;
485
+ continue;
486
+ }
487
+ if (pendingKey !== null && pendingKey !== key)
488
+ coalesced++;
489
+ clipFrames.push({
490
+ sourceFrame: frame,
491
+ frameTimeMs: (frame / fps) * 1000,
492
+ clipIndex: index,
493
+ outputStartSec: outputSec,
494
+ outputEndSec: windowEnd,
495
+ state
496
+ });
497
+ lastEmittedKey = key;
498
+ lastEmittedSec = outputSec;
499
+ pendingKey = null;
500
+ }
501
+ // Whatever is still pending when the clip ends is never rendered either.
502
+ if (pendingKey !== null) {
503
+ if (capped)
504
+ droppedByCap++;
505
+ else
506
+ coalesced++;
507
+ }
508
+ for (let i = 0; i < clipFrames.length - 1; i++) {
509
+ clipFrames[i].outputEndSec = clipFrames[i + 1].outputStartSec;
510
+ }
511
+ keyframes.push(...clipFrames);
512
+ if (coalesced > 0) {
513
+ log(`ui: clip ${index} rate-limited to ${maxPerSecond} keyframe(s)/s of output time — ` +
514
+ `${coalesced} intermediate HUD state(s) never rendered`);
515
+ }
516
+ if (droppedByCap > 0) {
517
+ log(`ui: clip ${index} hit the ${maxPerClip}-keyframe cap at source frame ${firstDroppedFrame} — ` +
518
+ `${droppedByCap} later HUD state(s) dropped; the overlay holds its last state`);
519
+ }
520
+ }
521
+ return keyframes;
522
+ }
523
+ //# sourceMappingURL=hud-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hud-state.js","sourceRoot":"","sources":["../../src/trailer/hud-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * `@bitmagic/asset-core/trailer` — the trailer compositor: a recording (PNG frames + timeline.json)
3
+ * in, a cut, beat-synced, titled MP4 out. Node-only (fs, child_process, a system ffmpeg), which is
4
+ * why it is a subpath and never reachable from the package root the browser imports.
5
+ *
6
+ * Hosts: the CLI (`bitmagic trailer`) and game-play-agent (the Creator's web trailer). Anything that
7
+ * needs a browser — the HUD replay and title cards — is injected through `TrailerRasterizers`.
8
+ */
9
+ export * from './analyze.js';
10
+ export * from './auto-edl.js';
11
+ export * from './capture.js';
12
+ export * from './beat-cut.js';
13
+ export * from './edl-time.js';
14
+ export * from './errors.js';
15
+ export * from './ffmpeg.js';
16
+ export * from './hud-state.js';
17
+ export * from './io.js';
18
+ export * from './link.js';
19
+ export * from './make.js';
20
+ export * from './merge.js';
21
+ export * from './music-beats.js';
22
+ export * from './paths.js';
23
+ export * from './png.js';
24
+ export * from './render.js';
25
+ export * from './revision.js';
26
+ export * from './synth.js';
27
+ export * from './timeline-types.js';
28
+ export * from './titles.js';
29
+ export * from './video-chain.js';
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/trailer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * `@bitmagic/asset-core/trailer` — the trailer compositor: a recording (PNG frames + timeline.json)
3
+ * in, a cut, beat-synced, titled MP4 out. Node-only (fs, child_process, a system ffmpeg), which is
4
+ * why it is a subpath and never reachable from the package root the browser imports.
5
+ *
6
+ * Hosts: the CLI (`bitmagic trailer`) and game-play-agent (the Creator's web trailer). Anything that
7
+ * needs a browser — the HUD replay and title cards — is injected through `TrailerRasterizers`.
8
+ */
9
+ export * from './analyze.js';
10
+ export * from './auto-edl.js';
11
+ export * from './capture.js';
12
+ export * from './beat-cut.js';
13
+ export * from './edl-time.js';
14
+ export * from './errors.js';
15
+ export * from './ffmpeg.js';
16
+ export * from './hud-state.js';
17
+ export * from './io.js';
18
+ export * from './link.js';
19
+ export * from './make.js';
20
+ export * from './merge.js';
21
+ export * from './music-beats.js';
22
+ export * from './paths.js';
23
+ export * from './png.js';
24
+ export * from './render.js';
25
+ export * from './revision.js';
26
+ export * from './synth.js';
27
+ export * from './timeline-types.js';
28
+ export * from './titles.js';
29
+ export * from './video-chain.js';
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/trailer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Where the compositor's words go.
3
+ *
4
+ * The trailer modules narrate as they work — windows scored, overlays rasterized, the render
5
+ * summary — and under `--json` every one of those lines must land on stderr, because stdout is
6
+ * reserved for the single result document (`output.ts`). The modules cannot know which mode the
7
+ * command runs in, so the command binds the Output seam here first and everything below it
8
+ * writes through `out`/`warn` without caring.
9
+ *
10
+ * Unbound (a test, or a module used as a library) both go to stderr: never stdout, so nothing here
11
+ * can corrupt a result by accident.
12
+ */
13
+ export interface TrailerLog {
14
+ info(line: string): void;
15
+ warn(line: string): void;
16
+ }
17
+ /** The command layer calls this once with `createOutput(json)` before running any pipeline step. */
18
+ export declare function bindTrailerLog(log: TrailerLog): void;
19
+ /** Back to stderr — for tests that bound a capturing log. */
20
+ export declare function resetTrailerLog(): void;
21
+ export declare function out(line: string): void;
22
+ export declare function warn(line: string): void;
23
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/trailer/io.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AASD,oGAAoG;AACpG,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAEpD;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEvC"}