@bitmagic/cli 0.1.70-dev.0 → 0.1.70-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.
- package/README.md +47 -1
- package/assets/skills/publishing-to-poki/SKILL.md +50 -0
- package/dist/bin.js +5 -4
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +6 -5
- package/dist/cli.js.map +1 -1
- package/dist/commands/publish.d.ts +11 -0
- package/dist/commands/publish.js +18 -0
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/trailer.js +6 -10
- package/dist/commands/trailer.js.map +1 -1
- package/dist/editor/recording-sink.d.ts +2 -9
- package/dist/editor/recording-sink.js +3 -15
- package/dist/editor/recording-sink.js.map +1 -1
- package/dist/editor/recording-stream.d.ts +3 -2
- package/dist/editor/recording-stream.js +14 -48
- package/dist/editor/recording-stream.js.map +1 -1
- package/dist/editor/shell-page.js +1 -1
- package/dist/editor/shell-page.js.map +1 -1
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +16 -0
- package/dist/errors.js.map +1 -1
- package/dist/generate/video-review.js +1 -1
- package/dist/generate/video-review.js.map +1 -1
- package/dist/ios/collect-urls.d.ts +1 -75
- package/dist/ios/collect-urls.js +2 -219
- package/dist/ios/collect-urls.js.map +1 -1
- package/dist/ios/local-server.d.ts +1 -11
- package/dist/ios/local-server.js +2 -87
- package/dist/ios/local-server.js.map +1 -1
- package/dist/ios/transform.d.ts +4 -45
- package/dist/ios/transform.js +3 -59
- package/dist/ios/transform.js.map +1 -1
- package/dist/ios/vendor.d.ts +1 -29
- package/dist/ios/vendor.js +2 -112
- package/dist/ios/vendor.js.map +1 -1
- package/dist/package/collect-urls.d.ts +75 -0
- package/dist/package/collect-urls.js +220 -0
- package/dist/package/collect-urls.js.map +1 -0
- package/dist/package/local-server.d.ts +13 -0
- package/dist/package/local-server.js +102 -0
- package/dist/package/local-server.js.map +1 -0
- package/dist/package/transform.d.ts +47 -0
- package/dist/package/transform.js +62 -0
- package/dist/package/transform.js.map +1 -0
- package/dist/package/vendor.d.ts +33 -0
- package/dist/package/vendor.js +114 -0
- package/dist/package/vendor.js.map +1 -0
- package/dist/poki/assets.d.ts +20 -0
- package/dist/poki/assets.js +154 -0
- package/dist/poki/assets.js.map +1 -0
- package/dist/poki/check.d.ts +21 -0
- package/dist/poki/check.js +134 -0
- package/dist/poki/check.js.map +1 -0
- package/dist/poki/publish.d.ts +22 -0
- package/dist/poki/publish.js +207 -0
- package/dist/poki/publish.js.map +1 -0
- package/dist/poki/transform.d.ts +6 -0
- package/dist/poki/transform.js +30 -0
- package/dist/poki/transform.js.map +1 -0
- package/dist/publish/bundle.d.ts +1 -0
- package/dist/publish/bundle.js +2 -2
- package/dist/publish/bundle.js.map +1 -1
- package/dist/render/qr-png.d.ts +3 -6
- package/dist/render/qr-png.js +4 -33
- package/dist/render/qr-png.js.map +1 -1
- package/dist/scaffold/asset-pipeline-skill-files.d.ts +1 -1
- package/dist/scaffold/asset-pipeline-skill-files.js +3 -3
- package/dist/scaffold/poki-skill-files.d.ts +2 -0
- package/dist/scaffold/poki-skill-files.js +7 -0
- package/dist/scaffold/poki-skill-files.js.map +1 -0
- package/dist/scaffold/project-files.js +1 -1
- package/dist/scaffold/project.js +2 -0
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/skill-files.js +6 -4
- package/dist/scaffold/skill-files.js.map +1 -1
- package/dist/trailer/chrome-rasterizers.d.ts +7 -0
- package/dist/trailer/chrome-rasterizers.js +7 -0
- package/dist/trailer/chrome-rasterizers.js.map +1 -0
- package/dist/trailer/game-name.d.ts +2 -0
- package/dist/trailer/game-name.js +20 -0
- package/dist/trailer/game-name.js.map +1 -0
- package/dist/trailer/hud-raster.d.ts +1 -1
- package/dist/trailer/hud-raster.js +1 -1
- package/dist/trailer/hud-raster.js.map +1 -1
- package/dist/trailer/record-session.js +1 -2
- package/dist/trailer/record-session.js.map +1 -1
- package/dist/trailer/title-raster.d.ts +9 -2
- package/dist/trailer/title-raster.js +17 -3
- package/dist/trailer/title-raster.js.map +1 -1
- package/dist/verify/browser.d.ts +3 -1
- package/dist/verify/browser.js +14 -9
- package/dist/verify/browser.js.map +1 -1
- package/dist/verify/classify.d.ts +2 -0
- package/dist/verify/classify.js +4 -1
- package/dist/verify/classify.js.map +1 -1
- package/package.json +4 -4
- package/dist/editor/capture-file.d.ts +0 -70
- package/dist/editor/capture-file.js +0 -204
- package/dist/editor/capture-file.js.map +0 -1
- package/dist/trailer/analyze.d.ts +0 -23
- package/dist/trailer/analyze.js +0 -186
- package/dist/trailer/analyze.js.map +0 -1
- package/dist/trailer/auto-edl.d.ts +0 -50
- package/dist/trailer/auto-edl.js +0 -267
- package/dist/trailer/auto-edl.js.map +0 -1
- package/dist/trailer/beat-cut.d.ts +0 -57
- package/dist/trailer/beat-cut.js +0 -232
- package/dist/trailer/beat-cut.js.map +0 -1
- package/dist/trailer/edl-time.d.ts +0 -61
- package/dist/trailer/edl-time.js +0 -105
- package/dist/trailer/edl-time.js.map +0 -1
- package/dist/trailer/ffmpeg.d.ts +0 -18
- package/dist/trailer/ffmpeg.js +0 -100
- package/dist/trailer/ffmpeg.js.map +0 -1
- package/dist/trailer/hud-state.d.ts +0 -181
- package/dist/trailer/hud-state.js +0 -525
- package/dist/trailer/hud-state.js.map +0 -1
- package/dist/trailer/io.d.ts +0 -22
- package/dist/trailer/io.js +0 -20
- package/dist/trailer/io.js.map +0 -1
- package/dist/trailer/link.d.ts +0 -1
- package/dist/trailer/link.js +0 -15
- package/dist/trailer/link.js.map +0 -1
- package/dist/trailer/make.d.ts +0 -56
- package/dist/trailer/make.js +0 -212
- package/dist/trailer/make.js.map +0 -1
- package/dist/trailer/merge.d.ts +0 -7
- package/dist/trailer/merge.js +0 -165
- package/dist/trailer/merge.js.map +0 -1
- package/dist/trailer/music-beats.d.ts +0 -123
- package/dist/trailer/music-beats.js +0 -672
- package/dist/trailer/music-beats.js.map +0 -1
- package/dist/trailer/paths.d.ts +0 -28
- package/dist/trailer/paths.js +0 -101
- package/dist/trailer/paths.js.map +0 -1
- package/dist/trailer/render.d.ts +0 -59
- package/dist/trailer/render.js +0 -521
- package/dist/trailer/render.js.map +0 -1
- package/dist/trailer/revision.d.ts +0 -8
- package/dist/trailer/revision.js +0 -31
- package/dist/trailer/revision.js.map +0 -1
- package/dist/trailer/synth.d.ts +0 -9
- package/dist/trailer/synth.js +0 -120
- package/dist/trailer/synth.js.map +0 -1
- package/dist/trailer/timeline-types.d.ts +0 -195
- package/dist/trailer/timeline-types.js +0 -419
- package/dist/trailer/timeline-types.js.map +0 -1
- package/dist/trailer/titles.d.ts +0 -44
- package/dist/trailer/titles.js +0 -124
- package/dist/trailer/titles.js.map +0 -1
- package/dist/trailer/video-chain.d.ts +0 -129
- package/dist/trailer/video-chain.js +0 -261
- package/dist/trailer/video-chain.js.map +0 -1
package/dist/trailer/beat-cut.js
DELETED
|
@@ -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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"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure EDL time mapping: source frames -> output-timeline seconds.
|
|
3
|
-
*
|
|
4
|
-
* Crossfades OVERLAP the previous clip, so every clip after a crossfade
|
|
5
|
-
* starts (and ends) earlier on the output timeline than a cut-only chain
|
|
6
|
-
* would place it. All render math (xfade offsets, sound delays, total
|
|
7
|
-
* duration) derives from this module so it can be unit-tested without ffmpeg.
|
|
8
|
-
*/
|
|
9
|
-
import type { EdlClip, TimelineSound } from './timeline-types.js';
|
|
10
|
-
export declare const DEFAULT_CROSSFADE_SEC = 0.25;
|
|
11
|
-
export declare const DEFAULT_TAIL_PAD_FRAMES = 30;
|
|
12
|
-
export declare const MIN_SPEED = 0.25;
|
|
13
|
-
export declare const MAX_SPEED = 2;
|
|
14
|
-
export interface ClipTiming {
|
|
15
|
-
index: number;
|
|
16
|
-
in: number;
|
|
17
|
-
out: number;
|
|
18
|
-
speed: number;
|
|
19
|
-
/** Resolved transition INTO this clip; first clip is always 'cut'. */
|
|
20
|
-
transition: 'cut' | 'crossfade';
|
|
21
|
-
/** Seconds; 0 for cuts. Also the xfade offset shortfall vs a plain concat. */
|
|
22
|
-
transitionDuration: number;
|
|
23
|
-
/** Seconds on the output timeline where this clip's first frame lands. */
|
|
24
|
-
outputStart: number;
|
|
25
|
-
/** Seconds this clip occupies on the output timeline (source frames / fps / speed). */
|
|
26
|
-
outputDuration: number;
|
|
27
|
-
label?: string;
|
|
28
|
-
/** Per-clip UI-overlay override; undefined means "follow the global --ui flag". */
|
|
29
|
-
ui?: boolean;
|
|
30
|
-
}
|
|
31
|
-
export interface ClipTimelineResult {
|
|
32
|
-
timings: ClipTiming[];
|
|
33
|
-
totalDuration: number;
|
|
34
|
-
warnings: string[];
|
|
35
|
-
}
|
|
36
|
-
export declare function computeClipTimeline(clips: EdlClip[], fps: number): ClipTimelineResult;
|
|
37
|
-
/**
|
|
38
|
-
* Output-timeline seconds where a source frame inside `timing` lands. Frames
|
|
39
|
-
* before the clip's first frame (sound tail pad) clamp to the clip start.
|
|
40
|
-
*/
|
|
41
|
-
export declare function sourceFrameToOutputSec(timing: ClipTiming, sourceFrame: number, fps: number): number;
|
|
42
|
-
/**
|
|
43
|
-
* Output time at which a clip stops being the only source on screen. A
|
|
44
|
-
* crossfade INTO the next clip begins at that clip's outputStart — before this
|
|
45
|
-
* clip's last frame — so anything that must not double up (UI overlays) hands
|
|
46
|
-
* over there rather than at this clip's own end.
|
|
47
|
-
*/
|
|
48
|
-
export declare function exclusiveOutputEnd(timings: readonly ClipTiming[], index: number): number;
|
|
49
|
-
export interface PlacedSound {
|
|
50
|
-
sound: TimelineSound;
|
|
51
|
-
clipIndex: number;
|
|
52
|
-
/** Seconds on the output timeline where this sound instance starts. */
|
|
53
|
-
outputTimeSec: number;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Place timeline sounds onto the output timeline. A clip picks up sounds with
|
|
57
|
-
* frame in [in - tailPadFrames, out); sounds from the tail pad (before the
|
|
58
|
-
* clip's first frame) clamp to the clip's output start. The same sound can be
|
|
59
|
-
* placed once per clip whose source range covers it.
|
|
60
|
-
*/
|
|
61
|
-
export declare function placeSounds(timings: ClipTiming[], sounds: TimelineSound[], fps: number, tailPadFrames?: number): PlacedSound[];
|
package/dist/trailer/edl-time.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { CliError } from '../errors.js';
|
|
2
|
-
export const DEFAULT_CROSSFADE_SEC = 0.25;
|
|
3
|
-
export const DEFAULT_TAIL_PAD_FRAMES = 30;
|
|
4
|
-
export const MIN_SPEED = 0.25;
|
|
5
|
-
export const MAX_SPEED = 2.0;
|
|
6
|
-
export function computeClipTimeline(clips, fps) {
|
|
7
|
-
if (clips.length === 0)
|
|
8
|
-
throw new CliError('EDL has no clips');
|
|
9
|
-
if (!Number.isFinite(fps) || fps <= 0)
|
|
10
|
-
throw new Error(`invalid fps: ${fps}`);
|
|
11
|
-
const warnings = [];
|
|
12
|
-
const timings = [];
|
|
13
|
-
let cursor = 0; // output-timeline end of the previous clip
|
|
14
|
-
clips.forEach((clip, index) => {
|
|
15
|
-
if (!Number.isInteger(clip.in) || !Number.isInteger(clip.out) || clip.in < 0 || clip.out <= clip.in) {
|
|
16
|
-
throw new Error(`clip ${index}: invalid frame range in=${clip.in} out=${clip.out}`);
|
|
17
|
-
}
|
|
18
|
-
let speed = clip.speed ?? 1;
|
|
19
|
-
if (speed < MIN_SPEED || speed > MAX_SPEED) {
|
|
20
|
-
const clamped = Math.min(MAX_SPEED, Math.max(MIN_SPEED, speed));
|
|
21
|
-
warnings.push(`clip ${index}: speed ${speed} outside [${MIN_SPEED}, ${MAX_SPEED}], clamped to ${clamped}`);
|
|
22
|
-
speed = clamped;
|
|
23
|
-
}
|
|
24
|
-
const outputDuration = (clip.out - clip.in) / fps / speed;
|
|
25
|
-
let transition = 'cut';
|
|
26
|
-
let transitionDuration = 0;
|
|
27
|
-
if (index === 0) {
|
|
28
|
-
if (clip.transition === 'crossfade')
|
|
29
|
-
warnings.push('clip 0: transition on the first clip is ignored');
|
|
30
|
-
}
|
|
31
|
-
else if (clip.transition === 'crossfade') {
|
|
32
|
-
transition = 'crossfade';
|
|
33
|
-
transitionDuration = clip.transitionDuration ?? DEFAULT_CROSSFADE_SEC;
|
|
34
|
-
if (transitionDuration <= 0) {
|
|
35
|
-
warnings.push(`clip ${index}: non-positive transitionDuration ${transitionDuration}, treating as cut`);
|
|
36
|
-
transition = 'cut';
|
|
37
|
-
transitionDuration = 0;
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
const maxFade = Math.min(timings[index - 1].outputDuration, outputDuration);
|
|
41
|
-
if (transitionDuration > maxFade) {
|
|
42
|
-
warnings.push(`clip ${index}: transitionDuration ${transitionDuration} longer than an adjacent clip, clamped to ${maxFade}`);
|
|
43
|
-
transitionDuration = maxFade;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const outputStart = index === 0 ? 0 : cursor - transitionDuration;
|
|
48
|
-
const timing = {
|
|
49
|
-
index,
|
|
50
|
-
in: clip.in,
|
|
51
|
-
out: clip.out,
|
|
52
|
-
speed,
|
|
53
|
-
transition,
|
|
54
|
-
transitionDuration,
|
|
55
|
-
outputStart,
|
|
56
|
-
outputDuration
|
|
57
|
-
};
|
|
58
|
-
if (clip.label !== undefined)
|
|
59
|
-
timing.label = clip.label;
|
|
60
|
-
if (clip.ui !== undefined)
|
|
61
|
-
timing.ui = clip.ui;
|
|
62
|
-
timings.push(timing);
|
|
63
|
-
cursor = outputStart + outputDuration;
|
|
64
|
-
});
|
|
65
|
-
return { timings, totalDuration: cursor, warnings };
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Output-timeline seconds where a source frame inside `timing` lands. Frames
|
|
69
|
-
* before the clip's first frame (sound tail pad) clamp to the clip start.
|
|
70
|
-
*/
|
|
71
|
-
export function sourceFrameToOutputSec(timing, sourceFrame, fps) {
|
|
72
|
-
return timing.outputStart + Math.max(0, sourceFrame - timing.in) / fps / timing.speed;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Output time at which a clip stops being the only source on screen. A
|
|
76
|
-
* crossfade INTO the next clip begins at that clip's outputStart — before this
|
|
77
|
-
* clip's last frame — so anything that must not double up (UI overlays) hands
|
|
78
|
-
* over there rather than at this clip's own end.
|
|
79
|
-
*/
|
|
80
|
-
export function exclusiveOutputEnd(timings, index) {
|
|
81
|
-
const timing = timings[index];
|
|
82
|
-
const ownEnd = timing.outputStart + timing.outputDuration;
|
|
83
|
-
const next = timings[index + 1];
|
|
84
|
-
return next === undefined ? ownEnd : Math.min(ownEnd, next.outputStart);
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Place timeline sounds onto the output timeline. A clip picks up sounds with
|
|
88
|
-
* frame in [in - tailPadFrames, out); sounds from the tail pad (before the
|
|
89
|
-
* clip's first frame) clamp to the clip's output start. The same sound can be
|
|
90
|
-
* placed once per clip whose source range covers it.
|
|
91
|
-
*/
|
|
92
|
-
export function placeSounds(timings, sounds, fps, tailPadFrames = DEFAULT_TAIL_PAD_FRAMES) {
|
|
93
|
-
const placements = [];
|
|
94
|
-
for (const timing of timings) {
|
|
95
|
-
for (const sound of sounds) {
|
|
96
|
-
if (sound.frame < timing.in - tailPadFrames || sound.frame >= timing.out)
|
|
97
|
-
continue;
|
|
98
|
-
const outputTimeSec = sourceFrameToOutputSec(timing, sound.frame, fps);
|
|
99
|
-
placements.push({ sound, clipIndex: timing.index, outputTimeSec });
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
placements.sort((a, b) => a.outputTimeSec - b.outputTimeSec);
|
|
103
|
-
return placements;
|
|
104
|
-
}
|
|
105
|
-
//# sourceMappingURL=edl-time.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"edl-time.js","sourceRoot":"","sources":["../../src/trailer/edl-time.ts"],"names":[],"mappings":"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"}
|
package/dist/trailer/ffmpeg.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export type FfmpegTool = 'ffmpeg' | 'ffprobe';
|
|
2
|
-
export declare function missingFfmpegMessage(tool?: FfmpegTool): string;
|
|
3
|
-
/**
|
|
4
|
-
* Refuse up front when a tool is missing, before any frames are read or sparks spent. `spawnSync`
|
|
5
|
-
* with `-version` is the cheapest probe that also proves the binary actually runs.
|
|
6
|
-
*/
|
|
7
|
-
export declare function ensureFfmpeg(tools?: readonly FfmpegTool[]): void;
|
|
8
|
-
/**
|
|
9
|
-
* The first of `tools` that is not on PATH, or null when they all are — the non-throwing half of
|
|
10
|
-
* {@link ensureFfmpeg}, for callers that skip a step rather than fail when ffmpeg is absent.
|
|
11
|
-
*/
|
|
12
|
-
export declare function missingFfmpegTool(tools?: readonly FfmpegTool[]): FfmpegTool | null;
|
|
13
|
-
export declare function runFfmpeg(args: string[]): Promise<void>;
|
|
14
|
-
/**
|
|
15
|
-
* Run a tool and keep stdout. {@link runFfmpeg} discards it — everything in the trailer pipeline
|
|
16
|
-
* writes files — so the PCM decode and every ffprobe query come through here instead.
|
|
17
|
-
*/
|
|
18
|
-
export declare function captureFfmpegTool(tool: FfmpegTool, args: string[]): Promise<Buffer>;
|
package/dist/trailer/ffmpeg.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thin ffmpeg process wrapper. Always argument arrays, never shell strings.
|
|
3
|
-
*
|
|
4
|
-
* ffmpeg is the one external tool this CLI needs and the one a creator's machine is least likely to
|
|
5
|
-
* have, so its absence is reported as a sentence with the install command rather than as an ENOENT
|
|
6
|
-
* stack trace from deep inside a filtergraph.
|
|
7
|
-
*
|
|
8
|
-
* Two callers with opposite stakes, hence both `ensureFfmpeg` and `missingFfmpegTool`: the trailer
|
|
9
|
-
* lane cannot do its job at all without ffmpeg and refuses up front, while `generate video`'s clip
|
|
10
|
-
* review is a nicety on top of an already-paid generation and must degrade to a note.
|
|
11
|
-
*/
|
|
12
|
-
import { spawn, spawnSync } from 'child_process';
|
|
13
|
-
import { CliError, errnoCode } from '../errors.js';
|
|
14
|
-
const STDERR_KEEP_BYTES = 65536;
|
|
15
|
-
const STDERR_REPORT_LINES = 30;
|
|
16
|
-
export function missingFfmpegMessage(tool = 'ffmpeg') {
|
|
17
|
-
return (`${tool} was not found on PATH. \`bitmagic trailer\` cuts and encodes with ffmpeg (and ffprobe) — ` +
|
|
18
|
-
'install it (macOS: brew install ffmpeg · Debian/Ubuntu: sudo apt install ffmpeg · ' +
|
|
19
|
-
'Windows: winget install Gyan.FFmpeg) and run the command again.');
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Refuse up front when a tool is missing, before any frames are read or sparks spent. `spawnSync`
|
|
23
|
-
* with `-version` is the cheapest probe that also proves the binary actually runs.
|
|
24
|
-
*/
|
|
25
|
-
export function ensureFfmpeg(tools = ['ffmpeg']) {
|
|
26
|
-
const missing = missingFfmpegTool(tools);
|
|
27
|
-
if (missing !== null)
|
|
28
|
-
throw new CliError(missingFfmpegMessage(missing), 1, 'ffmpeg_missing');
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* The first of `tools` that is not on PATH, or null when they all are — the non-throwing half of
|
|
32
|
-
* {@link ensureFfmpeg}, for callers that skip a step rather than fail when ffmpeg is absent.
|
|
33
|
-
*/
|
|
34
|
-
export function missingFfmpegTool(tools = ['ffmpeg']) {
|
|
35
|
-
for (const tool of tools) {
|
|
36
|
-
const probe = spawnSync(tool, ['-version'], { stdio: 'ignore' });
|
|
37
|
-
if (probe.error !== undefined && errnoCode(probe.error) === 'ENOENT')
|
|
38
|
-
return tool;
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
export async function runFfmpeg(args) {
|
|
43
|
-
return new Promise((resolve, reject) => {
|
|
44
|
-
const child = spawn('ffmpeg', args, { stdio: ['ignore', 'ignore', 'pipe'] });
|
|
45
|
-
let stderr = '';
|
|
46
|
-
child.stderr.on('data', (chunk) => {
|
|
47
|
-
stderr += chunk.toString('utf-8');
|
|
48
|
-
if (stderr.length > STDERR_KEEP_BYTES)
|
|
49
|
-
stderr = stderr.slice(-STDERR_KEEP_BYTES / 2);
|
|
50
|
-
});
|
|
51
|
-
child.on('error', (err) => {
|
|
52
|
-
if (errnoCode(err) === 'ENOENT')
|
|
53
|
-
reject(new CliError(missingFfmpegMessage('ffmpeg'), 1, 'ffmpeg_missing'));
|
|
54
|
-
else
|
|
55
|
-
reject(new Error(`failed to start ffmpeg: ${err.message}`));
|
|
56
|
-
});
|
|
57
|
-
child.on('close', (code) => {
|
|
58
|
-
if (code === 0) {
|
|
59
|
-
resolve();
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
const tail = stderr.trim().split('\n').slice(-STDERR_REPORT_LINES).join('\n');
|
|
63
|
-
reject(new CliError(`ffmpeg exited with code ${code}:\n${tail}`));
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Run a tool and keep stdout. {@link runFfmpeg} discards it — everything in the trailer pipeline
|
|
70
|
-
* writes files — so the PCM decode and every ffprobe query come through here instead.
|
|
71
|
-
*/
|
|
72
|
-
export async function captureFfmpegTool(tool, args) {
|
|
73
|
-
return new Promise((resolve, reject) => {
|
|
74
|
-
const child = spawn(tool, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
75
|
-
const chunks = [];
|
|
76
|
-
let stderr = '';
|
|
77
|
-
child.stdout.on('data', (chunk) => chunks.push(chunk));
|
|
78
|
-
child.stderr.on('data', (chunk) => {
|
|
79
|
-
stderr += chunk.toString('utf-8');
|
|
80
|
-
if (stderr.length > STDERR_KEEP_BYTES)
|
|
81
|
-
stderr = stderr.slice(-STDERR_KEEP_BYTES / 2);
|
|
82
|
-
});
|
|
83
|
-
child.on('error', (err) => {
|
|
84
|
-
if (errnoCode(err) === 'ENOENT')
|
|
85
|
-
reject(new CliError(missingFfmpegMessage(tool), 1, 'ffmpeg_missing'));
|
|
86
|
-
else
|
|
87
|
-
reject(new Error(`failed to start ${tool}: ${err.message}`));
|
|
88
|
-
});
|
|
89
|
-
child.on('close', (code) => {
|
|
90
|
-
if (code === 0) {
|
|
91
|
-
resolve(Buffer.concat(chunks));
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
const tail = stderr.trim().split('\n').slice(-STDERR_REPORT_LINES).join('\n');
|
|
95
|
-
reject(new Error(`${tool} exited with code ${code}:\n${tail}`));
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
//# sourceMappingURL=ffmpeg.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ffmpeg.js","sourceRoot":"","sources":["../../src/trailer/ffmpeg.ts"],"names":[],"mappings":"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"}
|