@bitmagic/cli 0.1.70-dev.0 → 0.1.70-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 (96) hide show
  1. package/dist/bin.js +5 -4
  2. package/dist/bin.js.map +1 -1
  3. package/dist/cli.js +6 -5
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/trailer.js +6 -10
  6. package/dist/commands/trailer.js.map +1 -1
  7. package/dist/editor/recording-sink.d.ts +2 -9
  8. package/dist/editor/recording-sink.js +3 -15
  9. package/dist/editor/recording-sink.js.map +1 -1
  10. package/dist/editor/recording-stream.d.ts +3 -2
  11. package/dist/editor/recording-stream.js +14 -48
  12. package/dist/editor/recording-stream.js.map +1 -1
  13. package/dist/editor/shell-page.js +1 -1
  14. package/dist/editor/shell-page.js.map +1 -1
  15. package/dist/errors.d.ts +8 -0
  16. package/dist/errors.js +16 -0
  17. package/dist/errors.js.map +1 -1
  18. package/dist/generate/video-review.js +1 -1
  19. package/dist/generate/video-review.js.map +1 -1
  20. package/dist/render/qr-png.d.ts +3 -6
  21. package/dist/render/qr-png.js +4 -33
  22. package/dist/render/qr-png.js.map +1 -1
  23. package/dist/scaffold/asset-pipeline-skill-files.d.ts +1 -1
  24. package/dist/scaffold/asset-pipeline-skill-files.js +3 -3
  25. package/dist/trailer/chrome-rasterizers.d.ts +7 -0
  26. package/dist/trailer/chrome-rasterizers.js +7 -0
  27. package/dist/trailer/chrome-rasterizers.js.map +1 -0
  28. package/dist/trailer/game-name.d.ts +2 -0
  29. package/dist/trailer/game-name.js +20 -0
  30. package/dist/trailer/game-name.js.map +1 -0
  31. package/dist/trailer/hud-raster.d.ts +1 -1
  32. package/dist/trailer/hud-raster.js +1 -1
  33. package/dist/trailer/hud-raster.js.map +1 -1
  34. package/dist/trailer/record-session.js +1 -2
  35. package/dist/trailer/record-session.js.map +1 -1
  36. package/dist/trailer/title-raster.d.ts +9 -2
  37. package/dist/trailer/title-raster.js +17 -3
  38. package/dist/trailer/title-raster.js.map +1 -1
  39. package/package.json +4 -4
  40. package/dist/editor/capture-file.d.ts +0 -70
  41. package/dist/editor/capture-file.js +0 -204
  42. package/dist/editor/capture-file.js.map +0 -1
  43. package/dist/trailer/analyze.d.ts +0 -23
  44. package/dist/trailer/analyze.js +0 -186
  45. package/dist/trailer/analyze.js.map +0 -1
  46. package/dist/trailer/auto-edl.d.ts +0 -50
  47. package/dist/trailer/auto-edl.js +0 -267
  48. package/dist/trailer/auto-edl.js.map +0 -1
  49. package/dist/trailer/beat-cut.d.ts +0 -57
  50. package/dist/trailer/beat-cut.js +0 -232
  51. package/dist/trailer/beat-cut.js.map +0 -1
  52. package/dist/trailer/edl-time.d.ts +0 -61
  53. package/dist/trailer/edl-time.js +0 -105
  54. package/dist/trailer/edl-time.js.map +0 -1
  55. package/dist/trailer/ffmpeg.d.ts +0 -18
  56. package/dist/trailer/ffmpeg.js +0 -100
  57. package/dist/trailer/ffmpeg.js.map +0 -1
  58. package/dist/trailer/hud-state.d.ts +0 -181
  59. package/dist/trailer/hud-state.js +0 -525
  60. package/dist/trailer/hud-state.js.map +0 -1
  61. package/dist/trailer/io.d.ts +0 -22
  62. package/dist/trailer/io.js +0 -20
  63. package/dist/trailer/io.js.map +0 -1
  64. package/dist/trailer/link.d.ts +0 -1
  65. package/dist/trailer/link.js +0 -15
  66. package/dist/trailer/link.js.map +0 -1
  67. package/dist/trailer/make.d.ts +0 -56
  68. package/dist/trailer/make.js +0 -212
  69. package/dist/trailer/make.js.map +0 -1
  70. package/dist/trailer/merge.d.ts +0 -7
  71. package/dist/trailer/merge.js +0 -165
  72. package/dist/trailer/merge.js.map +0 -1
  73. package/dist/trailer/music-beats.d.ts +0 -123
  74. package/dist/trailer/music-beats.js +0 -672
  75. package/dist/trailer/music-beats.js.map +0 -1
  76. package/dist/trailer/paths.d.ts +0 -28
  77. package/dist/trailer/paths.js +0 -101
  78. package/dist/trailer/paths.js.map +0 -1
  79. package/dist/trailer/render.d.ts +0 -59
  80. package/dist/trailer/render.js +0 -521
  81. package/dist/trailer/render.js.map +0 -1
  82. package/dist/trailer/revision.d.ts +0 -8
  83. package/dist/trailer/revision.js +0 -31
  84. package/dist/trailer/revision.js.map +0 -1
  85. package/dist/trailer/synth.d.ts +0 -9
  86. package/dist/trailer/synth.js +0 -120
  87. package/dist/trailer/synth.js.map +0 -1
  88. package/dist/trailer/timeline-types.d.ts +0 -195
  89. package/dist/trailer/timeline-types.js +0 -419
  90. package/dist/trailer/timeline-types.js.map +0 -1
  91. package/dist/trailer/titles.d.ts +0 -44
  92. package/dist/trailer/titles.js +0 -124
  93. package/dist/trailer/titles.js.map +0 -1
  94. package/dist/trailer/video-chain.d.ts +0 -129
  95. package/dist/trailer/video-chain.js +0 -261
  96. package/dist/trailer/video-chain.js.map +0 -1
@@ -1,267 +0,0 @@
1
- import { FORCED_EVENT_TYPES, eventWeight } from './analyze.js';
2
- /** Seconds per body shot, cycled. All inside the craft doc's 1.5–3 s band, never two alike in a row. */
3
- export const SHOT_LENGTH_PATTERN_SEC = [2, 1.5, 3, 2, 2.5, 1.5, 3];
4
- export const END_CARD_SEC = 2.5;
5
- /** How far before the peak event a shot begins, as a fraction of its length. */
6
- export const LEAD_IN_FRACTION = 0.6;
7
- /** Nothing in the first second: the game is still fading in from its menu. */
8
- export const SKIP_LEADING_SEC = 1;
9
- export const MIN_BEATS_PER_SHOT = 2;
10
- export const MAX_BEATS_PER_SHOT = 8;
11
- /** A shot may carry at most this share of missing frames before it reads as a freeze. */
12
- export const MAX_MISSING_FRACTION = 0.1;
13
- /** Prefix sums over the missing set, so any range's missing count is two lookups. */
14
- class MissingIndex {
15
- prefix;
16
- constructor(missing, frameCount) {
17
- const flags = new Uint8Array(frameCount);
18
- for (const f of missing)
19
- if (f >= 0 && f < frameCount)
20
- flags[f] = 1;
21
- this.prefix = new Uint32Array(frameCount + 1);
22
- for (let i = 0; i < frameCount; i++)
23
- this.prefix[i + 1] = this.prefix[i] + flags[i];
24
- }
25
- count(start, end) {
26
- const a = Math.max(0, Math.min(start, this.prefix.length - 1));
27
- const b = Math.max(a, Math.min(end, this.prefix.length - 1));
28
- return this.prefix[b] - this.prefix[a];
29
- }
30
- fraction(start, end) {
31
- return end > start ? this.count(start, end) / (end - start) : 0;
32
- }
33
- /**
34
- * The last frame worth cutting up to: walk back from the end while the trailing second is
35
- * mostly missing. A recorder that stalls at the stop leaves exactly that shape — a good body
36
- * and a dead tail — and the auto cut should treat the tail as if it were never recorded.
37
- */
38
- usableEnd(frameCount, fps) {
39
- let end = frameCount;
40
- const window = Math.round(fps);
41
- while (end > window && this.fraction(end - window, end) > MAX_MISSING_FRACTION)
42
- end -= window;
43
- return end;
44
- }
45
- }
46
- /** `"f3121 explosion i0.9"` -> the event's frame, type and weighted intensity. */
47
- function parseDigest(line) {
48
- const match = /^f(\d+)\s+(\S+)\s+i([\d.]+)$/.exec(line.trim());
49
- if (match === null)
50
- return null;
51
- const intensity = Number(match[3]);
52
- return {
53
- frame: Number(match[1]),
54
- type: match[2],
55
- weighted: eventWeight(match[2]) * (Number.isFinite(intensity) ? intensity : 1),
56
- };
57
- }
58
- function toCandidate(window) {
59
- let best = null;
60
- let forced = false;
61
- for (const line of window.events) {
62
- const event = parseDigest(line);
63
- if (event === null)
64
- continue;
65
- if (FORCED_EVENT_TYPES.includes(event.type))
66
- forced = true;
67
- if (best === null || event.weighted > best.weighted)
68
- best = event;
69
- }
70
- const mid = Math.round((window.startFrame + window.endFrame) / 2);
71
- return {
72
- window,
73
- peakFrame: best?.frame ?? mid,
74
- peakType: best?.type ?? 'none',
75
- forced,
76
- };
77
- }
78
- /** A shot's length in whole beats when there is a grid — rounding the seconds, clamped to the band. */
79
- function beatsFor(seconds, beats) {
80
- const beatSec = 60 / beats.bpm;
81
- return Math.min(MAX_BEATS_PER_SHOT, Math.max(MIN_BEATS_PER_SHOT, Math.round(seconds / beatSec)));
82
- }
83
- /** Frame count a shot of `seconds` will occupy, including the slack a beat-snapped cut can add. */
84
- function framesFor(seconds, fps, beats) {
85
- const slack = beats !== null ? 60 / beats.bpm : 0;
86
- return Math.ceil((seconds + slack) * fps);
87
- }
88
- function describe(candidate, fps) {
89
- const sec = candidate.peakFrame / fps;
90
- const mm = Math.floor(sec / 60);
91
- const ss = Math.floor(sec % 60).toString().padStart(2, '0');
92
- const types = new Set();
93
- for (const line of candidate.window.events) {
94
- const event = parseDigest(line);
95
- if (event !== null && event.weighted > 0)
96
- types.add(event.type);
97
- }
98
- const what = types.size > 0 ? [...types].slice(0, 3).join(' + ') : 'gameplay';
99
- return `${what} @${mm}:${ss}`;
100
- }
101
- export function buildAutoShots(input) {
102
- const { analysis, beats } = input;
103
- const fps = analysis.fps;
104
- const lost = new MissingIndex(input.missingFrames ?? [], analysis.frameCount);
105
- // Everything below cuts inside [0, frameCount): a dead tail is simply not part of the recording.
106
- const frameCount = lost.usableEnd(analysis.frameCount, fps);
107
- const skipFrames = Math.round(SKIP_LEADING_SEC * fps);
108
- /**
109
- * A start frame for a shot of `lenFrames` whose range is mostly present. An analysed moment is
110
- * nudged EARLIER (the peak stays inside the shot); a filler is nudged LATER, so it never backs
111
- * into the shot before it and repeats footage.
112
- */
113
- const placeShot = (ideal, lenFrames, direction) => {
114
- const latest = Math.max(0, frameCount - lenFrames);
115
- if (ideal > latest && direction === 'later')
116
- return null;
117
- for (let attempt = 0; attempt < 4; attempt++) {
118
- const nudge = attempt * Math.round(lenFrames / 2);
119
- const start = Math.max(0, Math.min(direction === 'earlier' ? ideal - nudge : ideal + nudge, latest));
120
- if (lost.fraction(start, start + lenFrames) <= MAX_MISSING_FRACTION)
121
- return start;
122
- }
123
- return null;
124
- };
125
- const bodyBudget = Math.max(SHOT_LENGTH_PATTERN_SEC[0], input.targetSeconds - END_CARD_SEC);
126
- const meanLen = SHOT_LENGTH_PATTERN_SEC.reduce((a, b) => a + b, 0) / SHOT_LENGTH_PATTERN_SEC.length;
127
- // Never ask for more footage than the recording holds: shots that overlap repeat the same
128
- // seconds twice, which reads worse than a shorter trailer. A short recording gets a short cut.
129
- const usableSec = Math.max(0, frameCount - skipFrames) / fps;
130
- const slots = Math.max(1, Math.min(Math.floor(bodyBudget / meanLen), Math.floor(usableSec / meanLen)));
131
- // Candidates: every analysed window with its peak inside the usable range; forced ones first,
132
- // then by score, so the k best are taken but a forced window is never dropped for a louder one.
133
- const candidates = analysis.windows
134
- .map(toCandidate)
135
- .filter((c) => c.peakFrame >= skipFrames && c.peakFrame < frameCount)
136
- .filter((c) => c.peakType !== 'state');
137
- const ranked = [...candidates].sort((a, b) => {
138
- if (a.forced !== b.forced)
139
- return a.forced ? -1 : 1;
140
- return b.window.score - a.window.score;
141
- });
142
- const chosen = ranked.slice(0, Math.min(slots, ranked.length));
143
- // Fill: evenly spaced across the recording, skipping spots an ANALYSED window already covers.
144
- // Only the analysed picks count as cover — a filler must never shadow the next filler, or a
145
- // short recording (fillers closer together than the radius) loses every second slot.
146
- const missing = slots - chosen.length;
147
- if (missing > 0) {
148
- const analysed = [...chosen];
149
- const usable = frameCount - skipFrames;
150
- const spacing = usable / missing;
151
- const radius = Math.min(3 * fps, spacing / 2);
152
- for (let i = 0; i < missing; i++) {
153
- const frame = skipFrames + Math.round((i + 0.5) * spacing);
154
- const covered = analysed.some((c) => Math.abs(c.peakFrame - frame) < radius);
155
- const filler = {
156
- window: { startFrame: frame, endFrame: frame, score: 0, events: [], sheet: '' },
157
- peakFrame: frame,
158
- peakType: 'none',
159
- forced: false,
160
- };
161
- if (!covered)
162
- chosen.push(filler);
163
- }
164
- }
165
- // Chronological, with a match-end pinned last.
166
- chosen.sort((a, b) => a.peakFrame - b.peakFrame);
167
- const endIndex = chosen.findIndex((c) => c.window.events.some((e) => parseDigest(e)?.type === 'match-end'));
168
- if (endIndex >= 0 && endIndex !== chosen.length - 1) {
169
- const [end] = chosen.splice(endIndex, 1);
170
- chosen.push(end);
171
- }
172
- const shots = [];
173
- let prevEnd = 0;
174
- chosen.forEach((candidate, i) => {
175
- const seconds = SHOT_LENGTH_PATTERN_SEC[i % SHOT_LENGTH_PATTERN_SEC.length];
176
- const lenFrames = framesFor(seconds, fps, beats);
177
- const isFiller = candidate.window.score === 0 && candidate.window.events.length === 0;
178
- const lead = Math.round(LEAD_IN_FRACTION * seconds * fps);
179
- // A filler starts no earlier than the previous shot ended: the same seconds twice is the one
180
- // thing worse than a shorter trailer. A real moment keeps its peak in frame instead.
181
- const ideal = isFiller ? Math.max(candidate.peakFrame - lead, prevEnd) : candidate.peakFrame - lead;
182
- const start = placeShot(ideal, lenFrames, isFiller ? 'later' : 'earlier');
183
- if (start === null)
184
- return; // no clean footage near this moment — better one shot fewer than a freeze
185
- const shot = { in: start, label: describe(candidate, fps) };
186
- if (beats !== null)
187
- shot.beats = beatsFor(seconds, beats);
188
- else
189
- shot.seconds = seconds;
190
- if (input.ui === true)
191
- shot.ui = true;
192
- shots.push(shot);
193
- prevEnd = start + lenFrames;
194
- });
195
- // Fillers dropped above (covered by an analysed moment, or with no clean footage where they
196
- // fell) leave the cut short. Put them back where the footage is idle: the largest gap between
197
- // shots, again and again, until the slots are full or no gap holds a shot.
198
- const lenOf = (shot) => framesFor(shot.seconds ?? (shot.beats ?? 0) * (beats !== null ? 60 / beats.bpm : 0), fps, beats);
199
- const pinnedEnd = endIndex >= 0 && shots.length > 0 ? shots[shots.length - 1] : null;
200
- for (let guard = 0; shots.length < slots && guard < slots; guard++) {
201
- const ordered = shots.filter((sh) => sh !== pinnedEnd).sort((a, b) => a.in - b.in);
202
- const limit = pinnedEnd !== null ? pinnedEnd.in : frameCount;
203
- let best = null;
204
- let cursor = skipFrames;
205
- for (const sh of [...ordered, null]) {
206
- const gapEnd = sh === null ? limit : sh.in;
207
- if (gapEnd - cursor > (best?.size ?? 0))
208
- best = { start: cursor, size: gapEnd - cursor };
209
- if (sh !== null)
210
- cursor = Math.max(cursor, sh.in + lenOf(sh));
211
- }
212
- if (best === null)
213
- break;
214
- // The pattern's next length when it fits, else the longest pattern length that does — a 2 s
215
- // gap still deserves a 1.5 s shot rather than nothing.
216
- const preferred = SHOT_LENGTH_PATTERN_SEC[shots.length % SHOT_LENGTH_PATTERN_SEC.length];
217
- const fitting = [preferred, ...[...SHOT_LENGTH_PATTERN_SEC].sort((a, b) => b - a)]
218
- .find((sec) => framesFor(sec, fps, beats) <= best.size);
219
- if (fitting === undefined)
220
- break;
221
- const seconds = fitting;
222
- const lenFrames = framesFor(seconds, fps, beats);
223
- const start = placeShot(best.start + Math.round((best.size - lenFrames) / 2), lenFrames, 'later');
224
- if (start === null || start + lenFrames > best.start + best.size)
225
- break;
226
- const label = describe({ window: { startFrame: start, endFrame: start, score: 0, events: [], sheet: '' }, peakFrame: start + Math.round(lenFrames / 2), peakType: 'none', forced: false }, fps);
227
- const shot = { in: start, label };
228
- if (beats !== null)
229
- shot.beats = beatsFor(seconds, beats);
230
- else
231
- shot.seconds = seconds;
232
- if (input.ui === true)
233
- shot.ui = true;
234
- shots.push(shot);
235
- }
236
- // Chronological again after the gap fills, keeping a pinned match-end last.
237
- shots.sort((a, b) => (a === pinnedEnd ? 1 : b === pinnedEnd ? -1 : a.in - b.in));
238
- if (shots.length === 0) {
239
- // Nothing clean anywhere: hold the opening, which at least exists.
240
- const shot = { in: Math.min(skipFrames, Math.max(0, frameCount - 1)), label: 'gameplay @0:01' };
241
- if (beats !== null)
242
- shot.beats = beatsFor(END_CARD_SEC, beats);
243
- else
244
- shot.seconds = END_CARD_SEC;
245
- shots.push(shot);
246
- }
247
- // The end card sits over the last shot, so that shot must be long enough to carry it.
248
- const last = shots[shots.length - 1];
249
- if (beats !== null)
250
- last.beats = Math.max(last.beats ?? 0, beatsFor(END_CARD_SEC, beats));
251
- else
252
- last.seconds = Math.max(last.seconds ?? 0, END_CARD_SEC);
253
- const lastLen = framesFor(last.seconds ?? END_CARD_SEC, fps, beats);
254
- last.in = placeShot(Math.min(last.in, frameCount - lastLen), lastLen, 'earlier') ?? Math.max(0, Math.min(last.in, frameCount - lastLen));
255
- const title = { at: 'last-clip', text: input.title.toUpperCase(), style: 'card' };
256
- if (input.sub !== undefined)
257
- title.sub = input.sub;
258
- return {
259
- version: 1,
260
- recording: input.recordingName,
261
- notes: 'First cut written by `bitmagic trailer make`. Edit freely: reorder, swap "in" frames for ' +
262
- 'better moments from analysis.json, change beats/seconds, add titles. Re-run make to render.',
263
- shots,
264
- titles: [title],
265
- };
266
- }
267
- //# sourceMappingURL=auto-edl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-edl.js","sourceRoot":"","sources":["../../src/trailer/auto-edl.ts"],"names":[],"mappings":"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"}
@@ -1,57 +0,0 @@
1
- import type { BeatAnalysis } from './music-beats.js';
2
- import type { TitleCue } from './titles.js';
3
- import type { Edl } from './timeline-types.js';
4
- export interface Shot {
5
- /** Source frame the shot starts on. */
6
- in: number;
7
- /** Hold for this many beats (needs a beat grid). */
8
- beats?: number;
9
- /** Hold for this many seconds (used when there is no beat grid, or the shot has no `beats`). */
10
- seconds?: number;
11
- label: string;
12
- /** Playback speed; the craft rule is 1.0 — slow-mo reads as a low framerate. */
13
- speed?: number;
14
- /** Draw (or suppress) the HUD replay over this shot; menus want `false`. */
15
- ui?: boolean;
16
- transition?: 'cut' | 'crossfade';
17
- transitionDuration?: number;
18
- }
19
- /** A title whose `at` may be the literal `"last-clip"`; `dur` is then the last clip's length. */
20
- export type ShotTitle = Omit<TitleCue, 'at' | 'dur'> & {
21
- at: number | 'last-clip';
22
- dur?: number;
23
- };
24
- export interface ShotsFile {
25
- version: 1;
26
- /** Name of the recording these frame indices were chosen from. */
27
- recording?: string;
28
- /** Free-form notes the author keeps with the cut (never read by the tool). */
29
- notes?: string;
30
- shots: Shot[];
31
- titles?: ShotTitle[];
32
- }
33
- export interface CutOptions {
34
- /** Frames in the recording; a shot that would run past the end is shifted earlier and reported. */
35
- frameCount?: number;
36
- }
37
- export interface CutResult {
38
- edl: Edl;
39
- /** Beats consumed from the downbeat (0 without a grid). */
40
- beatsUsed: number;
41
- totalSec: number;
42
- /** Largest distance between a cut and its beat target, in ms (0 without a grid). */
43
- worstCutErrorMs: number;
44
- /** The first shot that did not fit in the track, when the grid ran out. */
45
- truncatedAt?: string;
46
- }
47
- /** Parse a shots document: either a bare array of shots or `{ version, shots, titles? }`. */
48
- export declare function parseShots(raw: unknown, source: string): ShotsFile;
49
- export declare function loadShots(filePath: string): ShotsFile;
50
- /**
51
- * Turn shots into frame-exact clips. With `beats` every cut lands on the grid counted from the
52
- * downbeat; without, each shot's `seconds` decides its length. Returns the EDL plus the numbers
53
- * the command prints so the author can judge the fit.
54
- */
55
- export declare function cutShots(shots: ShotsFile, beats: BeatAnalysis | null, fps: number, options?: CutOptions): CutResult;
56
- /** The one-line summary `bitmagic trailer cut` prints, mirroring the Python script's. */
57
- export declare function describeCut(result: CutResult, beats: BeatAnalysis | null): string;
@@ -1,232 +0,0 @@
1
- /**
2
- * Snap a shot list onto a beat grid (or plain seconds) and emit an EDL.
3
- *
4
- * A shot says WHICH source frame to start on and HOW LONG to hold, in beats when there is music
5
- * and in seconds when there is not; this turns that into the frame-exact `edl.json` the renderer
6
- * consumes. It is the TypeScript port of the make-trailer skill's `beat-edl.py`, so creators need
7
- * no Python.
8
- *
9
- * Each cut's target time comes straight from the beat grid, and the frame count is the difference
10
- * against the frames ACTUALLY emitted so far — not against the previous target. That matters for
11
- * speed-ramped clips: at 0.5x the output length is forced to an even number of frames, so a clip
12
- * whose beat-target is odd lands one frame long. Measuring from actual output makes the next clip
13
- * absorb that frame instead of every later cut inheriting it.
14
- *
15
- * A title cue with `"at": "last-clip"` is resolved to cover the final clip (the end card), so it
16
- * survives regeneration without hand-editing output times.
17
- */
18
- import * as fs from 'fs';
19
- import { CliError } from '../errors.js';
20
- import { warn } from './io.js';
21
- function isRecord(value) {
22
- return typeof value === 'object' && value !== null && !Array.isArray(value);
23
- }
24
- function finiteNumber(value, ctx) {
25
- if (typeof value !== 'number' || !Number.isFinite(value)) {
26
- throw new CliError(`${ctx}: expected a number, got ${JSON.stringify(value)}`);
27
- }
28
- return value;
29
- }
30
- function parseShot(raw, index) {
31
- const ctx = `shots[${index}]`;
32
- if (!isRecord(raw))
33
- throw new CliError(`${ctx}: expected an object`);
34
- const shot = {
35
- in: finiteNumber(raw.in, `${ctx}.in`),
36
- label: typeof raw.label === 'string' && raw.label.length > 0 ? raw.label : `shot ${index + 1}`,
37
- };
38
- if (shot.in < 0 || !Number.isInteger(shot.in))
39
- throw new CliError(`${ctx}.in: expected a frame index >= 0`);
40
- if (raw.beats !== undefined) {
41
- shot.beats = finiteNumber(raw.beats, `${ctx}.beats`);
42
- if (shot.beats <= 0)
43
- throw new CliError(`${ctx}.beats: must be > 0`);
44
- }
45
- if (raw.seconds !== undefined) {
46
- shot.seconds = finiteNumber(raw.seconds, `${ctx}.seconds`);
47
- if (shot.seconds <= 0)
48
- throw new CliError(`${ctx}.seconds: must be > 0`);
49
- }
50
- if (shot.beats === undefined && shot.seconds === undefined) {
51
- throw new CliError(`${ctx} ("${shot.label}"): needs "beats" (with music) or "seconds"`);
52
- }
53
- if (raw.speed !== undefined)
54
- shot.speed = finiteNumber(raw.speed, `${ctx}.speed`);
55
- if (raw.ui !== undefined) {
56
- if (typeof raw.ui !== 'boolean')
57
- throw new CliError(`${ctx}.ui: expected true or false`);
58
- shot.ui = raw.ui;
59
- }
60
- if (raw.transition !== undefined) {
61
- if (raw.transition !== 'cut' && raw.transition !== 'crossfade') {
62
- throw new CliError(`${ctx}.transition: expected "cut" or "crossfade"`);
63
- }
64
- shot.transition = raw.transition;
65
- }
66
- if (raw.transitionDuration !== undefined) {
67
- shot.transitionDuration = finiteNumber(raw.transitionDuration, `${ctx}.transitionDuration`);
68
- }
69
- return shot;
70
- }
71
- function parseTitle(raw, index) {
72
- const ctx = `titles[${index}]`;
73
- if (!isRecord(raw))
74
- throw new CliError(`${ctx}: expected an object`);
75
- if (typeof raw.text !== 'string')
76
- throw new CliError(`${ctx}.text: expected a string`);
77
- const title = { text: raw.text, at: 0 };
78
- if (raw.at === 'last-clip')
79
- title.at = 'last-clip';
80
- else
81
- title.at = finiteNumber(raw.at, `${ctx}.at`);
82
- if (raw.dur !== undefined)
83
- title.dur = finiteNumber(raw.dur, `${ctx}.dur`);
84
- if (typeof raw.sub === 'string')
85
- title.sub = raw.sub;
86
- if (typeof raw.note === 'string')
87
- title.note = raw.note;
88
- if (raw.style === 'title' || raw.style === 'line' || raw.style === 'card')
89
- title.style = raw.style;
90
- return title;
91
- }
92
- /** Parse a shots document: either a bare array of shots or `{ version, shots, titles? }`. */
93
- export function parseShots(raw, source) {
94
- const shotsRaw = Array.isArray(raw) ? raw : isRecord(raw) ? raw.shots : undefined;
95
- if (!Array.isArray(shotsRaw))
96
- throw new CliError(`${source}: expected a "shots" array`);
97
- if (shotsRaw.length === 0)
98
- throw new CliError(`${source}: "shots" is empty — nothing to cut`);
99
- const file = { version: 1, shots: shotsRaw.map(parseShot) };
100
- if (isRecord(raw)) {
101
- if (raw.version !== undefined && raw.version !== 1) {
102
- throw new CliError(`${source}: unsupported version ${JSON.stringify(raw.version)} (this CLI writes version 1)`);
103
- }
104
- if (typeof raw.recording === 'string')
105
- file.recording = raw.recording;
106
- if (typeof raw.notes === 'string')
107
- file.notes = raw.notes;
108
- if (raw.titles !== undefined) {
109
- if (!Array.isArray(raw.titles))
110
- throw new CliError(`${source}: "titles" must be an array`);
111
- file.titles = raw.titles.map(parseTitle);
112
- }
113
- }
114
- return file;
115
- }
116
- export function loadShots(filePath) {
117
- if (!fs.existsSync(filePath))
118
- throw new CliError(`Shots file not found: ${filePath}`);
119
- let raw;
120
- try {
121
- raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
122
- }
123
- catch (err) {
124
- throw new CliError(`Invalid JSON in ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
125
- }
126
- return parseShots(raw, filePath);
127
- }
128
- /**
129
- * Turn shots into frame-exact clips. With `beats` every cut lands on the grid counted from the
130
- * downbeat; without, each shot's `seconds` decides its length. Returns the EDL plus the numbers
131
- * the command prints so the author can judge the fit.
132
- */
133
- export function cutShots(shots, beats, fps, options = {}) {
134
- if (!Number.isFinite(fps) || fps <= 0)
135
- throw new CliError(`invalid fps: ${fps}`);
136
- const grid = beats?.beatTimes ?? null;
137
- const start = beats?.downbeatIndex ?? 0;
138
- const t0 = grid !== null ? grid[start] : 0;
139
- if (grid !== null && (t0 === undefined || grid.length < 2)) {
140
- throw new CliError('The beat grid has too few beats to cut on — check the music file or pass --bpm.');
141
- }
142
- const clips = [];
143
- let cum = start;
144
- let emitted = 0;
145
- let worst = 0;
146
- let truncatedAt;
147
- for (const shot of shots.shots) {
148
- const speed = shot.speed ?? 1.0;
149
- let need;
150
- let suffix;
151
- if (grid !== null && shot.beats !== undefined) {
152
- const next = cum + shot.beats;
153
- if (next >= grid.length) {
154
- truncatedAt = shot.label;
155
- break;
156
- }
157
- const target = Math.round((grid[next] - t0) * fps);
158
- need = target - emitted;
159
- cum = next;
160
- suffix = `[${shot.beats}b]`;
161
- }
162
- else if (shot.seconds !== undefined) {
163
- need = Math.round(shot.seconds * fps);
164
- suffix = `[${shot.seconds}s]`;
165
- }
166
- else {
167
- throw new CliError(`Shot "${shot.label}" is timed in beats but there is no beat grid — pass --music (or --beats), or give it "seconds".`);
168
- }
169
- const src = Math.max(1, Math.round(need * speed));
170
- const actual = Math.round(src / speed);
171
- emitted += actual;
172
- if (grid !== null && shot.beats !== undefined) {
173
- const target = Math.round((grid[cum] - t0) * fps);
174
- worst = Math.max(worst, (Math.abs(emitted - target) / fps) * 1000);
175
- }
176
- let inFrame = shot.in;
177
- if (options.frameCount !== undefined && inFrame + src > options.frameCount) {
178
- const shifted = Math.max(0, options.frameCount - src);
179
- warn(`shot "${shot.label}" runs past the recording's last frame — starting it at ${shifted} instead of ${inFrame}`);
180
- inFrame = shifted;
181
- }
182
- const clip = {
183
- in: inFrame,
184
- out: inFrame + src,
185
- speed,
186
- transition: shot.transition ?? 'cut',
187
- label: `${shot.label} ${suffix}`,
188
- };
189
- if (shot.transitionDuration !== undefined)
190
- clip.transitionDuration = shot.transitionDuration;
191
- if (shot.ui !== undefined)
192
- clip.ui = shot.ui;
193
- clips.push(clip);
194
- }
195
- if (clips.length === 0) {
196
- throw new CliError(`Not a single shot fits the music: "${truncatedAt ?? shots.shots[0].label}" already runs past the end of the track.`);
197
- }
198
- const totalSec = emitted / fps;
199
- const edl = { version: 1, targetDuration: Math.round(totalSec * 100) / 100, clips };
200
- if (shots.titles !== undefined && shots.titles.length > 0) {
201
- const last = clips[clips.length - 1];
202
- const lastDur = Math.round(last.out - last.in) / ((last.speed ?? 1) * fps);
203
- edl.titles = shots.titles.map((title) => {
204
- const { at, dur, ...rest } = title;
205
- if (at === 'last-clip') {
206
- return { ...rest, at: Math.round((totalSec - lastDur) * 1000) / 1000, dur: Math.round(lastDur * 1000) / 1000 };
207
- }
208
- return { ...rest, at, dur: dur ?? 2.5 };
209
- });
210
- }
211
- const result = {
212
- edl,
213
- beatsUsed: grid !== null ? cum - start : 0,
214
- totalSec,
215
- worstCutErrorMs: worst,
216
- };
217
- if (truncatedAt !== undefined)
218
- result.truncatedAt = truncatedAt;
219
- return result;
220
- }
221
- /** The one-line summary `bitmagic trailer cut` prints, mirroring the Python script's. */
222
- export function describeCut(result, beats) {
223
- const parts = [
224
- beats !== null ? `bpm=${beats.bpm.toFixed(2)}` : 'no beat grid',
225
- `clips=${result.edl.clips.length}`,
226
- beats !== null ? `beats=${result.beatsUsed}` : null,
227
- `total=${result.totalSec.toFixed(3)}s`,
228
- beats !== null ? `worst cut error=${result.worstCutErrorMs.toFixed(1)} ms` : null,
229
- ].filter((p) => p !== null);
230
- return parts.join(' ');
231
- }
232
- //# sourceMappingURL=beat-cut.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"beat-cut.js","sourceRoot":"","sources":["../../src/trailer/beat-cut.ts"],"names":[],"mappings":"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"}