@bitmagic/asset-core 0.2.24 → 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,130 @@
1
+ import type { ClipTiming } from './edl-time.js';
2
+ /** Format seconds/ratios for filtergraph text without float noise. */
3
+ export declare function fmtNum(value: number): string;
4
+ /** One rasterized HUD overlay and the output window it is live for. */
5
+ export interface UiOverlay {
6
+ filePath: string;
7
+ /** Which EDL clip produced it; windows only ever chain within one clip. */
8
+ clipIndex: number;
9
+ startSec: number;
10
+ endSec: number;
11
+ }
12
+ /** An output-time window during which HUD overlays must not draw. */
13
+ export interface BlockedWindow {
14
+ startSec: number;
15
+ endSec: number;
16
+ }
17
+ /**
18
+ * Width/height straight out of a PNG's IHDR chunk, so the filtergraph only
19
+ * pays for a scale filter when the overlay really is the wrong size.
20
+ */
21
+ export declare function readPngSize(filePath: string): {
22
+ width: number;
23
+ height: number;
24
+ } | null;
25
+ /** One keyframe's window, as `foldUiOverlays` needs it. */
26
+ export interface UiKeyframeWindow {
27
+ clipIndex: number;
28
+ outputStartSec: number;
29
+ outputEndSec: number;
30
+ }
31
+ /** Overlays plus the count of windows left with no UI at all. */
32
+ export interface FoldedOverlays {
33
+ overlays: UiOverlay[];
34
+ bare: number;
35
+ }
36
+ /**
37
+ * Turn rasterized paths (with null for the ones that failed) into overlay
38
+ * windows, holding the previous overlay across a failure.
39
+ *
40
+ * The hold is deliberately limited to the SAME clip. A clip's last window ends
41
+ * at exactly the next clip's outputStart — for cuts and crossfades alike — so
42
+ * comparing times alone matches across the boundary too, and a failed first
43
+ * keyframe would stretch the previous SHOT's HUD over new footage: the wrong
44
+ * score over the wrong scene, which is worse than no HUD at all. A window with
45
+ * no in-clip predecessor goes bare instead.
46
+ *
47
+ * Pure and exported so this is testable: render.ts reaches Playwright through
48
+ * hud-raster.ts, which jest cannot load.
49
+ */
50
+ export declare function foldUiOverlays(paths: ReadonlyArray<string | null>, keyframes: readonly UiKeyframeWindow[]): FoldedOverlays;
51
+ /** A gap-free PNG sequence, one entry per output frame, ready for image2. */
52
+ export interface UiSequence {
53
+ /** Holds ui_%06d.png from index 0, plus the shared transparent filler. */
54
+ dir: string;
55
+ frameCount: number;
56
+ /** Entries resolved to the filler: no overlay owned them, or a card blocked them. */
57
+ blankFrames: number;
58
+ /** Overlay windows too short to contain a frame time. */
59
+ unusedOverlays: number;
60
+ }
61
+ /**
62
+ * A fully transparent PNG, written without shelling out.
63
+ *
64
+ * `ffmpeg -f lavfi -i color=black@0.0 -pix_fmt rgba` looks like it produces
65
+ * this and does not — every alpha byte comes back 255, which would black out
66
+ * the whole frame. The chunk/CRC primitives are the QR encoder's.
67
+ */
68
+ export declare function writeTransparentPng(filePath: string, width: number, height: number): void;
69
+ /**
70
+ * Densify the overlay windows into one gap-free image2 sequence in OUTPUT time.
71
+ *
72
+ * Why not one ffmpeg input per keyframe (what this replaced): that shape costs
73
+ * ~23 MB of RSS and one serial filter node per overlay, so it was the real
74
+ * ceiling on how often the HUD could change — measured 4.31 s / 3.8 GB for 126
75
+ * overlays, 32 s / 17.2 GB at one per output frame, and above ~400 inputs
76
+ * ffmpeg starts failing scaler allocations, drops the HUD from the rest of the
77
+ * video, and still exits 0. One sequence is flat in keyframe count: 2.83 s /
78
+ * 0.94 GB whether it carries 126 distinct rasters or 902.
79
+ *
80
+ * Output time, not per-clip source time: the windows are already computed in
81
+ * output time (so exactly one HUD is live across a crossfade), and title-card
82
+ * blocked windows are output time too. A per-clip overlay applied before the
83
+ * xfade would cross-dissolve two HUDs against each other.
84
+ *
85
+ * The sequence MUST be gap-free: a missing index truncates the image2 input,
86
+ * ffmpeg exits 0, and the HUD silently disappears for the rest of the video.
87
+ * Running long is free, so the frame count deliberately rounds up and adds one.
88
+ */
89
+ export declare function buildUiSequence(overlays: readonly UiOverlay[], fps: number, totalDurationSec: number, seqDir: string, blocked?: readonly BlockedWindow[]): UiSequence;
90
+ /**
91
+ * Chain the UI sequence onto the finished video chain. Runs in yuv444p so the
92
+ * alpha blend keeps HUD text edges crisp (yuv420 would subsample them), and
93
+ * converts back for libx264 at the end.
94
+ *
95
+ * `eof_action=pass`, never `repeat`: if the sequence ever does come up short,
96
+ * passing drops the HUD from that point, while repeating would freeze the last
97
+ * raster to the end AND punch it through every title card.
98
+ */
99
+ export declare function appendUiSequenceChain(lines: string[], sequence: UiSequence, uiIndex: number, width: number, height: number, endLabel: string): void;
100
+ export interface LogoPlacement {
101
+ /** ffmpeg input index of the logo image. */
102
+ inputIndex: number;
103
+ opacity: number;
104
+ /** Logo height as a fraction of video height. */
105
+ heightFrac: number;
106
+ /** Edge margin as a fraction of video width. */
107
+ marginFrac: number;
108
+ corner: 'br' | 'bl' | 'tr' | 'tl';
109
+ }
110
+ /**
111
+ * Watermark chain, applied last so the logo sits above the HUD overlay too.
112
+ *
113
+ * The brand mark is white, and gameplay footage is frequently bright (sunlit
114
+ * sand measures luma 120-185 in the corner), so a plain translucent white logo
115
+ * washes out. A blurred black copy of the same alpha is laid underneath as a
116
+ * soft drop shadow — the standard broadcast treatment — which keeps the mark
117
+ * readable over light and dark backgrounds without altering the brand colour.
118
+ *
119
+ * Composited in yuv444 so the mark's edges stay crisp, converted to yuv420p at
120
+ * the very end for libx264.
121
+ */
122
+ export declare function buildLogoChain(inLabel: string, outLabel: string, placement: LogoPlacement, width: number, height: number): string[];
123
+ /**
124
+ * Build the per-clip prep + chaining lines.
125
+ *
126
+ * @param chainEnd label the finished video chain must land on (`vout`, or
127
+ * `vbase` when a UI overlay chain will be appended after it).
128
+ */
129
+ export declare function buildVideoChain(timings: ClipTiming[], fps: number, chainEnd: string): string[];
130
+ //# sourceMappingURL=video-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-chain.d.ts","sourceRoot":"","sources":["../../src/trailer/video-chain.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKhD,sEAAsE;AACtE,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAUtF;AAED,2DAA2D;AAC3D,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC,EACnC,SAAS,EAAE,SAAS,gBAAgB,EAAE,GACrC,cAAc,CA2BhB;AAKD,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,0EAA0E;IAC1E,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAiBzF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,SAAS,EAAE,EAC9B,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,SAAS,aAAa,EAAO,GACrC,UAAU,CAyCZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,IAAI,CAaN;AAED,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,EAAE,CAoBV;AAMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAmC9F"}
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Video half of the trailer filtergraph: per-clip prep, cut/crossfade
3
+ * chaining, and the HUD overlay chain.
4
+ *
5
+ * Split out of render.ts so it can be unit-tested — render.ts reaches
6
+ * Playwright through hud-raster.ts, which jest can't parse under this
7
+ * package's CommonJS transform.
8
+ */
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ import * as zlib from 'zlib';
12
+ import { warn } from './io.js';
13
+ import { linkOrCopy } from './link.js';
14
+ import { PNG_SIGNATURE, pngChunk } from './png.js';
15
+ /** Format seconds/ratios for filtergraph text without float noise. */
16
+ export function fmtNum(value) {
17
+ const fixed = value.toFixed(6);
18
+ return fixed.includes('.') ? fixed.replace(/0+$/, '').replace(/\.$/, '') : fixed;
19
+ }
20
+ /**
21
+ * Width/height straight out of a PNG's IHDR chunk, so the filtergraph only
22
+ * pays for a scale filter when the overlay really is the wrong size.
23
+ */
24
+ export function readPngSize(filePath) {
25
+ const header = Buffer.alloc(24);
26
+ const fd = fs.openSync(filePath, 'r');
27
+ try {
28
+ if (fs.readSync(fd, header, 0, 24, 0) < 24)
29
+ return null;
30
+ }
31
+ finally {
32
+ fs.closeSync(fd);
33
+ }
34
+ if (header.readUInt32BE(0) !== 0x89504e47 || header.toString('ascii', 12, 16) !== 'IHDR')
35
+ return null;
36
+ return { width: header.readUInt32BE(16), height: header.readUInt32BE(20) };
37
+ }
38
+ /**
39
+ * Turn rasterized paths (with null for the ones that failed) into overlay
40
+ * windows, holding the previous overlay across a failure.
41
+ *
42
+ * The hold is deliberately limited to the SAME clip. A clip's last window ends
43
+ * at exactly the next clip's outputStart — for cuts and crossfades alike — so
44
+ * comparing times alone matches across the boundary too, and a failed first
45
+ * keyframe would stretch the previous SHOT's HUD over new footage: the wrong
46
+ * score over the wrong scene, which is worse than no HUD at all. A window with
47
+ * no in-clip predecessor goes bare instead.
48
+ *
49
+ * Pure and exported so this is testable: render.ts reaches Playwright through
50
+ * hud-raster.ts, which jest cannot load.
51
+ */
52
+ export function foldUiOverlays(paths, keyframes) {
53
+ const overlays = [];
54
+ let bare = 0;
55
+ for (let i = 0; i < keyframes.length; i++) {
56
+ const filePath = paths[i];
57
+ const keyframe = keyframes[i];
58
+ if (filePath === null || filePath === undefined) {
59
+ const previous = overlays[overlays.length - 1];
60
+ if (previous !== undefined &&
61
+ previous.clipIndex === keyframe.clipIndex &&
62
+ previous.endSec === keyframe.outputStartSec) {
63
+ previous.endSec = keyframe.outputEndSec;
64
+ }
65
+ else {
66
+ bare++;
67
+ }
68
+ continue;
69
+ }
70
+ overlays.push({
71
+ filePath,
72
+ clipIndex: keyframe.clipIndex,
73
+ startSec: keyframe.outputStartSec,
74
+ endSec: keyframe.outputEndSec,
75
+ });
76
+ }
77
+ return { overlays, bare };
78
+ }
79
+ /** Larger than float noise on a frame-time sum, far smaller than a frame. */
80
+ const BOUNDARY_EPSILON = 1e-9;
81
+ /**
82
+ * A fully transparent PNG, written without shelling out.
83
+ *
84
+ * `ffmpeg -f lavfi -i color=black@0.0 -pix_fmt rgba` looks like it produces
85
+ * this and does not — every alpha byte comes back 255, which would black out
86
+ * the whole frame. The chunk/CRC primitives are the QR encoder's.
87
+ */
88
+ export function writeTransparentPng(filePath, width, height) {
89
+ const ihdr = Buffer.alloc(13);
90
+ ihdr.writeUInt32BE(width, 0);
91
+ ihdr.writeUInt32BE(height, 4);
92
+ ihdr[8] = 8; // bit depth
93
+ ihdr[9] = 6; // RGBA
94
+ // One filter byte per row, then width*4 zero bytes — zeroes are transparent.
95
+ const raw = Buffer.alloc(height * (1 + width * 4));
96
+ fs.writeFileSync(filePath, Buffer.concat([
97
+ PNG_SIGNATURE,
98
+ pngChunk('IHDR', ihdr),
99
+ pngChunk('IDAT', zlib.deflateSync(raw)),
100
+ pngChunk('IEND', Buffer.alloc(0)),
101
+ ]));
102
+ }
103
+ /**
104
+ * Densify the overlay windows into one gap-free image2 sequence in OUTPUT time.
105
+ *
106
+ * Why not one ffmpeg input per keyframe (what this replaced): that shape costs
107
+ * ~23 MB of RSS and one serial filter node per overlay, so it was the real
108
+ * ceiling on how often the HUD could change — measured 4.31 s / 3.8 GB for 126
109
+ * overlays, 32 s / 17.2 GB at one per output frame, and above ~400 inputs
110
+ * ffmpeg starts failing scaler allocations, drops the HUD from the rest of the
111
+ * video, and still exits 0. One sequence is flat in keyframe count: 2.83 s /
112
+ * 0.94 GB whether it carries 126 distinct rasters or 902.
113
+ *
114
+ * Output time, not per-clip source time: the windows are already computed in
115
+ * output time (so exactly one HUD is live across a crossfade), and title-card
116
+ * blocked windows are output time too. A per-clip overlay applied before the
117
+ * xfade would cross-dissolve two HUDs against each other.
118
+ *
119
+ * The sequence MUST be gap-free: a missing index truncates the image2 input,
120
+ * ffmpeg exits 0, and the HUD silently disappears for the rest of the video.
121
+ * Running long is free, so the frame count deliberately rounds up and adds one.
122
+ */
123
+ export function buildUiSequence(overlays, fps, totalDurationSec, seqDir, blocked = []) {
124
+ // Never append to a stale dir: entries are hardlinks onto the .ui rasters,
125
+ // so writing through one would corrupt the raster it shares an inode with.
126
+ fs.rmSync(seqDir, { recursive: true, force: true });
127
+ fs.mkdirSync(seqDir, { recursive: true });
128
+ const size = overlays.length > 0 ? readPngSize(overlays[0].filePath) : null;
129
+ const blankPath = path.join(seqDir, 'blank.png');
130
+ // Named outside the ui_%06d.png glob so image2 cannot pick it up as a frame.
131
+ writeTransparentPng(blankPath, size?.width ?? 16, size?.height ?? 16);
132
+ const sorted = [...overlays].sort((a, b) => a.startSec - b.startSec);
133
+ const frameCount = Math.ceil(totalDurationSec * fps - 1e-9) + 1;
134
+ const owned = new Set();
135
+ let cursor = 0;
136
+ let blankFrames = 0;
137
+ for (let n = 0; n < frameCount; n++) {
138
+ const t = n / fps;
139
+ // Window bounds are `outputStart + k/fps/speed` sums, which land one ulp
140
+ // above the frame time they mean for ~5% of boundaries (8.666666666666668
141
+ // vs 520/60); a bound that is mathematically the frame time must own that
142
+ // frame, or a clip's first frame goes to the previous shot's HUD. The same
143
+ // epsilon decides release and ownership, so shared boundaries stay
144
+ // half-open. Blocked windows are compared exactly: they are already
145
+ // rounded to the card's own gate (render.ts), and an epsilon there would
146
+ // blank a frame the card never covers.
147
+ const tEps = t + BOUNDARY_EPSILON;
148
+ while (cursor < sorted.length && sorted[cursor].endSec <= tEps)
149
+ cursor++;
150
+ const own = sorted[cursor];
151
+ const isBlocked = blocked.some((w) => t >= w.startSec && t < w.endSec);
152
+ const drawable = own !== undefined && own.startSec <= tEps && !isBlocked;
153
+ if (drawable)
154
+ owned.add(own.filePath);
155
+ else
156
+ blankFrames++;
157
+ linkOrCopy(drawable ? own.filePath : blankPath, path.join(seqDir, `ui_${String(n).padStart(6, '0')}.png`));
158
+ }
159
+ return {
160
+ dir: seqDir,
161
+ frameCount,
162
+ blankFrames,
163
+ unusedOverlays: overlays.filter((o) => !owned.has(o.filePath)).length,
164
+ };
165
+ }
166
+ /**
167
+ * Chain the UI sequence onto the finished video chain. Runs in yuv444p so the
168
+ * alpha blend keeps HUD text edges crisp (yuv420 would subsample them), and
169
+ * converts back for libx264 at the end.
170
+ *
171
+ * `eof_action=pass`, never `repeat`: if the sequence ever does come up short,
172
+ * passing drops the HUD from that point, while repeating would freeze the last
173
+ * raster to the end AND punch it through every title card.
174
+ */
175
+ export function appendUiSequenceChain(lines, sequence, uiIndex, width, height, endLabel) {
176
+ const size = readPngSize(path.join(sequence.dir, 'ui_000000.png'));
177
+ const needsScale = size === null || size.width !== width || size.height !== height;
178
+ if (needsScale && size !== null) {
179
+ // One line, not one per frame: with window-parity rasterization every
180
+ // overlay is deliberately supersampled and lands here by design.
181
+ warn(`ui: scaling overlays from ${size.width}x${size.height} to ${width}x${height}`);
182
+ }
183
+ const prep = needsScale ? `scale=${width}:${height},format=yuva444p` : 'format=yuva444p';
184
+ lines.push('[vbase]format=yuv444p[uibase]');
185
+ lines.push(`[${uiIndex}:v]${prep}[uiseq]`);
186
+ lines.push('[uibase][uiseq]overlay=0:0:format=yuv444:eof_action=pass:shortest=0[uidone]');
187
+ lines.push(`[uidone]format=yuv420p[${endLabel}]`);
188
+ }
189
+ /**
190
+ * Watermark chain, applied last so the logo sits above the HUD overlay too.
191
+ *
192
+ * The brand mark is white, and gameplay footage is frequently bright (sunlit
193
+ * sand measures luma 120-185 in the corner), so a plain translucent white logo
194
+ * washes out. A blurred black copy of the same alpha is laid underneath as a
195
+ * soft drop shadow — the standard broadcast treatment — which keeps the mark
196
+ * readable over light and dark backgrounds without altering the brand colour.
197
+ *
198
+ * Composited in yuv444 so the mark's edges stay crisp, converted to yuv420p at
199
+ * the very end for libx264.
200
+ */
201
+ export function buildLogoChain(inLabel, outLabel, placement, width, height) {
202
+ const logoHeight = Math.max(1, Math.round(height * placement.heightFrac));
203
+ const margin = Math.max(0, Math.round(width * placement.marginFrac));
204
+ const shadowOffset = Math.max(1, Math.round(logoHeight * 0.06));
205
+ const blur = Math.max(1, Math.round(logoHeight * 0.08));
206
+ const shadowAlpha = clamp01(placement.opacity * 0.6);
207
+ const opacity = clamp01(placement.opacity);
208
+ const x = placement.corner === 'br' || placement.corner === 'tr' ? `W-w-${margin}` : `${margin}`;
209
+ const y = placement.corner === 'br' || placement.corner === 'bl' ? `H-h-${margin}` : `${margin}`;
210
+ return [
211
+ `[${inLabel}]format=yuv444p[lgbase]`,
212
+ `[${placement.inputIndex}:v]scale=-1:${logoHeight},format=rgba,split=2[lgfg0][lgsh0]`,
213
+ `[lgsh0]colorchannelmixer=rr=0:gg=0:bb=0:aa=${fmtNum(shadowAlpha)},boxblur=${blur}:1[lgshadow]`,
214
+ `[lgbase][lgshadow]overlay=${x}+${shadowOffset}:${y}+${shadowOffset}:format=yuv444[lgstep]`,
215
+ `[lgfg0]colorchannelmixer=aa=${fmtNum(opacity)}[lgfg]`,
216
+ `[lgstep][lgfg]overlay=${x}:${y}:format=yuv444[lgdone]`,
217
+ `[lgdone]format=yuv420p[${outLabel}]`,
218
+ ];
219
+ }
220
+ function clamp01(value) {
221
+ return value < 0 ? 0 : value > 1 ? 1 : value;
222
+ }
223
+ /**
224
+ * Build the per-clip prep + chaining lines.
225
+ *
226
+ * @param chainEnd label the finished video chain must land on (`vout`, or
227
+ * `vbase` when a UI overlay chain will be appended after it).
228
+ */
229
+ export function buildVideoChain(timings, fps, chainEnd) {
230
+ const lines = [];
231
+ // Per-clip video prep. fps=<fps> after setpts materializes duplicated
232
+ // (slow-mo) or dropped (fast-mo) frames at a constant rate so concat/xfade
233
+ // inputs always match.
234
+ const singleClip = timings.length === 1;
235
+ timings.forEach((timing, i) => {
236
+ const label = singleClip ? chainEnd : `v${i}`;
237
+ const setpts = timing.speed === 1 ? 'setpts=PTS-STARTPTS' : `setpts=(PTS-STARTPTS)/${fmtNum(timing.speed)}`;
238
+ lines.push(`[${i}:v]trim=end_frame=${timing.out - timing.in},${setpts},fps=${fps},format=yuv420p[${label}]`);
239
+ });
240
+ // Chain clips. For a crossfade into clip i, the xfade offset (time in the
241
+ // accumulated chain where the fade starts) equals clip i's outputStart.
242
+ let current = 'v0';
243
+ for (let i = 1; i < timings.length; i++) {
244
+ const timing = timings[i];
245
+ const nextLabel = i === timings.length - 1 ? chainEnd : `vchain${i}`;
246
+ if (timing.transition === 'crossfade') {
247
+ // xfade rejects inputs whose timebases differ, and concat re-stamps its
248
+ // output to microseconds — so a crossfade following any run of cuts sees
249
+ // 1/1000000 on the left and 1/60 on the right. Normalize both sides.
250
+ lines.push(`[${current}]settb=AVTB[${current}tb]`);
251
+ lines.push(`[v${i}]settb=AVTB[v${i}tb]`);
252
+ lines.push(`[${current}tb][v${i}tb]xfade=transition=fade:duration=${fmtNum(timing.transitionDuration)}:offset=${fmtNum(timing.outputStart)}[${nextLabel}]`);
253
+ }
254
+ else {
255
+ lines.push(`[${current}][v${i}]concat=n=2:v=1:a=0[${nextLabel}]`);
256
+ }
257
+ current = nextLabel;
258
+ }
259
+ return lines;
260
+ }
261
+ //# sourceMappingURL=video-chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-chain.js","sourceRoot":"","sources":["../../src/trailer/video-chain.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitmagic/asset-core",
3
- "version": "0.2.24",
3
+ "version": "0.2.25-dev.1",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "author": "Bitmagic Oy",
6
6
  "type": "module",
@@ -34,6 +34,10 @@
34
34
  "./reference-record": {
35
35
  "types": "./dist/reference-record.d.ts",
36
36
  "default": "./dist/reference-record.js"
37
+ },
38
+ "./trailer": {
39
+ "types": "./dist/trailer/index.d.ts",
40
+ "default": "./dist/trailer/index.js"
37
41
  }
38
42
  },
39
43
  "files": [