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

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,120 @@
1
+ /**
2
+ * Pure-TypeScript sound synthesizer for timeline synth recipes.
3
+ *
4
+ * Renders a SynthRecipe to 48kHz mono 16-bit PCM WAV: layers are summed,
5
+ * [start, end] freq/gain values ramp linearly, the mix is clamped to [-1, 1]
6
+ * and a ~5ms linear fade-in/out avoids clicks. No audio libraries; the WAV
7
+ * header is written by hand. Output is fully deterministic (seeded noise) so
8
+ * recipe-hash-named cache files are reproducible.
9
+ */
10
+ import { createHash } from 'crypto';
11
+ export const SYNTH_SAMPLE_RATE = 48000;
12
+ const FADE_SEC = 0.005;
13
+ const NOISE_SEED = 0x9e3779b9;
14
+ /** Deterministic PRNG (mulberry32) so noise layers render identically every run. */
15
+ function mulberry32(seed) {
16
+ let state = seed >>> 0;
17
+ return () => {
18
+ state = (state + 0x6d2b79f5) >>> 0;
19
+ let t = state;
20
+ t = Math.imul(t ^ (t >>> 15), t | 1);
21
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
22
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
23
+ };
24
+ }
25
+ function interp(value, fallback, progress) {
26
+ if (value === undefined)
27
+ return fallback;
28
+ if (typeof value === 'number')
29
+ return value;
30
+ return value[0] + (value[1] - value[0]) * progress;
31
+ }
32
+ function layerSamples(layer, sampleCount) {
33
+ const buf = new Float64Array(sampleCount);
34
+ const wave = layer.wave;
35
+ const rand = mulberry32(NOISE_SEED);
36
+ // Phase in cycles, accumulated per sample so frequency ramps chirp smoothly.
37
+ let phase = 0;
38
+ for (let i = 0; i < sampleCount; i++) {
39
+ const progress = sampleCount > 1 ? i / (sampleCount - 1) : 0;
40
+ const gain = interp(layer.gain, 1, progress);
41
+ let value;
42
+ if (wave === 'noise') {
43
+ value = rand() * 2 - 1;
44
+ }
45
+ else {
46
+ const frac = phase - Math.floor(phase);
47
+ switch (wave) {
48
+ case 'sine':
49
+ value = Math.sin(2 * Math.PI * phase);
50
+ break;
51
+ case 'square':
52
+ value = frac < 0.5 ? 1 : -1;
53
+ break;
54
+ case 'sawtooth':
55
+ value = 2 * frac - 1;
56
+ break;
57
+ case 'triangle':
58
+ value = 1 - 4 * Math.abs(frac - 0.5);
59
+ break;
60
+ }
61
+ phase += interp(layer.freq, 440, progress) / SYNTH_SAMPLE_RATE;
62
+ }
63
+ buf[i] = value * gain;
64
+ }
65
+ return buf;
66
+ }
67
+ /** Render a recipe to mono float samples in [-1, 1], faded at both ends. */
68
+ export function synthesizeSamples(recipe) {
69
+ const sampleCount = Math.max(1, Math.round(recipe.dur * SYNTH_SAMPLE_RATE));
70
+ const mix = new Float64Array(sampleCount);
71
+ for (const layer of recipe.layers) {
72
+ const layerBuf = layerSamples(layer, sampleCount);
73
+ for (let i = 0; i < sampleCount; i++)
74
+ mix[i] += layerBuf[i];
75
+ }
76
+ const fadeSamples = Math.min(Math.round(FADE_SEC * SYNTH_SAMPLE_RATE), Math.floor(sampleCount / 2));
77
+ const result = new Float32Array(sampleCount);
78
+ for (let i = 0; i < sampleCount; i++) {
79
+ let v = Math.max(-1, Math.min(1, mix[i]));
80
+ if (fadeSamples > 0) {
81
+ if (i < fadeSamples)
82
+ v *= i / fadeSamples;
83
+ const fromEnd = sampleCount - 1 - i;
84
+ if (fromEnd < fadeSamples)
85
+ v *= fromEnd / fadeSamples;
86
+ }
87
+ result[i] = v;
88
+ }
89
+ return result;
90
+ }
91
+ /** Encode mono float samples as a 48kHz 16-bit PCM WAV file. */
92
+ export function samplesToWav(samples) {
93
+ const dataSize = samples.length * 2;
94
+ const buffer = Buffer.alloc(44 + dataSize);
95
+ buffer.write('RIFF', 0, 'ascii');
96
+ buffer.writeUInt32LE(36 + dataSize, 4);
97
+ buffer.write('WAVE', 8, 'ascii');
98
+ buffer.write('fmt ', 12, 'ascii');
99
+ buffer.writeUInt32LE(16, 16); // fmt chunk size
100
+ buffer.writeUInt16LE(1, 20); // PCM
101
+ buffer.writeUInt16LE(1, 22); // mono
102
+ buffer.writeUInt32LE(SYNTH_SAMPLE_RATE, 24);
103
+ buffer.writeUInt32LE(SYNTH_SAMPLE_RATE * 2, 28); // byte rate
104
+ buffer.writeUInt16LE(2, 32); // block align
105
+ buffer.writeUInt16LE(16, 34); // bits per sample
106
+ buffer.write('data', 36, 'ascii');
107
+ buffer.writeUInt32LE(dataSize, 40);
108
+ for (let i = 0; i < samples.length; i++) {
109
+ buffer.writeInt16LE(Math.round(samples[i] * 32767), 44 + i * 2);
110
+ }
111
+ return buffer;
112
+ }
113
+ export function synthesizeWav(recipe) {
114
+ return samplesToWav(synthesizeSamples(recipe));
115
+ }
116
+ /** Stable cache key for a recipe (16 hex chars of sha256 over its JSON). */
117
+ export function recipeHash(recipe) {
118
+ return createHash('sha256').update(JSON.stringify(recipe)).digest('hex').slice(0, 16);
119
+ }
120
+ //# sourceMappingURL=synth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synth.js","sourceRoot":"","sources":["../../src/trailer/synth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,196 @@
1
+ import type { TitleCue } from './titles.js';
2
+ export interface FrameClockEntry {
3
+ frame: number;
4
+ wallMs: number;
5
+ }
6
+ export interface TimelineRecording {
7
+ /** Frame files are named `<name>_%06d.png`, indexed from 0. */
8
+ name: string;
9
+ gameId?: string;
10
+ genre?: string;
11
+ width: number;
12
+ height: number;
13
+ fps: number;
14
+ frameCount: number;
15
+ /** Frame indices whose PNG failed to save; may be absent or empty. */
16
+ missingFrames?: number[];
17
+ /** Ignored in v1. */
18
+ frameClock?: FrameClockEntry[];
19
+ /**
20
+ * The window the DOM HUD laid out against during capture (the recorder
21
+ * resizes only the canvas). Absent on older recordings — HUD overlays then
22
+ * raster at the recording resolution, as they always did.
23
+ */
24
+ window?: RecordingWindow;
25
+ }
26
+ export interface RecordingWindow {
27
+ innerWidth: number;
28
+ innerHeight: number;
29
+ devicePixelRatio: number;
30
+ }
31
+ export interface TimelineEvent {
32
+ frame: number;
33
+ type: string;
34
+ intensity?: number;
35
+ position?: number[];
36
+ actor?: string;
37
+ data?: Record<string, unknown>;
38
+ }
39
+ export type SynthWave = 'sine' | 'square' | 'sawtooth' | 'triangle' | 'noise';
40
+ export interface SynthLayer {
41
+ wave: SynthWave;
42
+ /** Constant Hz or [start, end] linear ramp. Ignored for 'noise'. */
43
+ freq?: number | [number, number];
44
+ /** Constant gain or [start, end] linear ramp. Default 1. */
45
+ gain?: number | [number, number];
46
+ }
47
+ export interface SynthRecipe {
48
+ /** Duration in seconds. */
49
+ dur: number;
50
+ layers: SynthLayer[];
51
+ }
52
+ export interface AssetSound {
53
+ frame: number;
54
+ kind: 'asset';
55
+ assetId: string;
56
+ url: string;
57
+ volume?: number;
58
+ }
59
+ export interface SynthSound {
60
+ frame: number;
61
+ kind: 'synth';
62
+ name?: string;
63
+ recipe: SynthRecipe;
64
+ volume?: number;
65
+ }
66
+ export type TimelineSound = AssetSound | SynthSound;
67
+ export type HudElementKind = 'counter' | 'progress' | 'icon-text' | 'timer' | 'custom';
68
+ /**
69
+ * Recorded HUD state changes (the engine's `TimelineHudOp`). Frames use the
70
+ * recording's source clock. Elements that existed before the recording started
71
+ * are emitted as frame-0 `create` ops, so frame 0 is always a complete
72
+ * snapshot, and array order within a frame is stacking order in an anchor.
73
+ *
74
+ * `update` carries already-rendered text, so the replay never applies a game's
75
+ * `format` callback. Timers are the exception — they log start/pause/reset
76
+ * only and the displayed value is derived (see hud-state.ts).
77
+ */
78
+ export type HudOp = {
79
+ frame: number;
80
+ op: 'create';
81
+ id: string;
82
+ elType: HudElementKind;
83
+ params: Record<string, unknown>;
84
+ } | {
85
+ frame: number;
86
+ op: 'update';
87
+ id: string;
88
+ text?: string;
89
+ icon?: string;
90
+ percent?: number;
91
+ } | {
92
+ frame: number;
93
+ op: 'custom-html';
94
+ id: string;
95
+ html: string;
96
+ css?: string;
97
+ } | {
98
+ frame: number;
99
+ op: 'timer';
100
+ id: string;
101
+ action: 'start' | 'pause' | 'reset';
102
+ seconds?: number;
103
+ } | {
104
+ frame: number;
105
+ op: 'show' | 'hide' | 'remove';
106
+ id: string;
107
+ } | {
108
+ frame: number;
109
+ op: 'health';
110
+ current: number;
111
+ max: number;
112
+ } | {
113
+ frame: number;
114
+ op: 'health-visible';
115
+ visible: boolean;
116
+ width?: number;
117
+ } | {
118
+ frame: number;
119
+ op: 'toast';
120
+ message: string;
121
+ variant?: string;
122
+ durationMs?: number;
123
+ anchor?: string;
124
+ } | {
125
+ frame: number;
126
+ op: 'hud-visible';
127
+ visible: boolean;
128
+ } | {
129
+ frame: number;
130
+ op: 'theme';
131
+ theme: unknown;
132
+ } | {
133
+ frame: number;
134
+ op: 'stylesheet';
135
+ id: string;
136
+ css: string;
137
+ };
138
+ export interface Timeline {
139
+ version: number;
140
+ recording: TimelineRecording;
141
+ events: TimelineEvent[];
142
+ sounds: TimelineSound[];
143
+ /** HUD state changes; absent/empty when the recording captured no HUD. */
144
+ hud: HudOp[];
145
+ }
146
+ export interface EdlClip {
147
+ /** Source frame index, inclusive. */
148
+ in: number;
149
+ /** Source frame index, exclusive. */
150
+ out: number;
151
+ /** Playback speed 0.25–2.0; default 1.0 (0.5 = slow-mo). */
152
+ speed?: number;
153
+ /** Transition between the PREVIOUS clip and this one; first clip's is ignored. */
154
+ transition?: 'cut' | 'crossfade';
155
+ /** Crossfade length in seconds; default 0.25. */
156
+ transitionDuration?: number;
157
+ label?: string;
158
+ /** Draw the recorded HUD over this clip. Overrides the global --ui flag. */
159
+ ui?: boolean;
160
+ }
161
+ export interface Edl {
162
+ version: number;
163
+ /** Informational only. */
164
+ targetDuration?: number;
165
+ clips: EdlClip[];
166
+ /** Burned-in title cards, timed in OUTPUT seconds. */
167
+ titles?: TitleCue[];
168
+ }
169
+ export interface AnalysisWindow {
170
+ startFrame: number;
171
+ endFrame: number;
172
+ score: number;
173
+ /** Compact digest lines, e.g. "f3121 explosion i0.9". */
174
+ events: string[];
175
+ /** Path relative to the recording dir, e.g. "sheets/window_00.png". */
176
+ sheet: string;
177
+ }
178
+ export interface Analysis {
179
+ version: number;
180
+ fps: number;
181
+ frameCount: number;
182
+ windows: AnalysisWindow[];
183
+ }
184
+ export declare function frameFileName(recordingName: string, frame: number): string;
185
+ export declare function frameFilePath(recordingDir: string, recordingName: string, frame: number): string;
186
+ export declare function parseRecipe(raw: unknown, ctx: string): SynthRecipe;
187
+ /**
188
+ * Parse the hud[] track. Skipped entries are reported (grouped by op name) so
189
+ * a forward-compatible skip is never silent.
190
+ */
191
+ export declare function parseHudOps(raw: unknown, source: string): HudOp[];
192
+ export declare function parseTimeline(raw: unknown, source: string): Timeline;
193
+ export declare function loadTimeline(recordingDir: string): Timeline;
194
+ export declare function parseEdl(raw: unknown, source: string): Edl;
195
+ export declare function loadEdl(filePath: string): Edl;
196
+ //# sourceMappingURL=timeline-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline-types.d.ts","sourceRoot":"","sources":["../../src/trailer/timeline-types.ts"],"names":[],"mappings":"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"}