@jtdigital/renderbox-sdk 0.4.1 → 0.6.0

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 (51) hide show
  1. package/README.md +54 -2
  2. package/dist/bridge.d.ts +139 -0
  3. package/dist/bridge.d.ts.map +1 -0
  4. package/dist/bridge.js +338 -0
  5. package/dist/bridge.js.map +1 -0
  6. package/dist/graph.d.ts +28 -22
  7. package/dist/graph.d.ts.map +1 -1
  8. package/dist/graph.js +7 -7
  9. package/dist/graph.js.map +1 -1
  10. package/dist/index.d.ts +4 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +4 -0
  13. package/dist/index.js.map +1 -1
  14. package/dist/pipelines.d.ts +516 -0
  15. package/dist/pipelines.d.ts.map +1 -0
  16. package/dist/pipelines.js +16 -0
  17. package/dist/pipelines.js.map +1 -0
  18. package/dist/presets/audio.d.ts +43 -0
  19. package/dist/presets/audio.d.ts.map +1 -0
  20. package/dist/presets/audio.js +148 -0
  21. package/dist/presets/audio.js.map +1 -0
  22. package/dist/presets/index.d.ts +5 -0
  23. package/dist/presets/index.d.ts.map +1 -0
  24. package/dist/presets/index.js +5 -0
  25. package/dist/presets/index.js.map +1 -0
  26. package/dist/presets/position.d.ts +39 -0
  27. package/dist/presets/position.d.ts.map +1 -0
  28. package/dist/presets/position.js +40 -0
  29. package/dist/presets/position.js.map +1 -0
  30. package/dist/presets/text.d.ts +90 -0
  31. package/dist/presets/text.d.ts.map +1 -0
  32. package/dist/presets/text.js +132 -0
  33. package/dist/presets/text.js.map +1 -0
  34. package/dist/presets/video.d.ts +46 -0
  35. package/dist/presets/video.d.ts.map +1 -0
  36. package/dist/presets/video.js +108 -0
  37. package/dist/presets/video.js.map +1 -0
  38. package/dist/recipes/faceRedact.d.ts.map +1 -1
  39. package/dist/recipes/faceRedact.js +8 -4
  40. package/dist/recipes/faceRedact.js.map +1 -1
  41. package/dist/recipes/makeSlideshow.d.ts +2 -1
  42. package/dist/recipes/makeSlideshow.d.ts.map +1 -1
  43. package/dist/recipes/makeSlideshow.js +3 -71
  44. package/dist/recipes/makeSlideshow.js.map +1 -1
  45. package/dist/streams.d.ts +791 -699
  46. package/dist/streams.d.ts.map +1 -1
  47. package/dist/streams.js +283 -201
  48. package/dist/streams.js.map +1 -1
  49. package/dist/types.d.ts +12 -0
  50. package/dist/types.d.ts.map +1 -1
  51. package/package.json +20 -5
package/README.md CHANGED
@@ -36,12 +36,36 @@ const g = graph();
36
36
  const [v, a] = g.open('street.mp4');
37
37
 
38
38
  const faces = v
39
- .detect({ model: 'scrfd_10g', threshold: 0.12 }) // VideoStream → DetectionStream
40
- .track({ algorithm: 'bytetrack' }); // stable ids across frames
39
+ .detect({ model: 'retinaface_mv2' }) // VideoStream → DetectionStream
40
+ .track({ algorithm: 'bytetrack' }); // stable ids across frames
41
41
 
42
42
  g.write('redacted.mp4', v.redact(faces, { mode: 'black' }), a);
43
43
  ```
44
44
 
45
+ ### The registry types your call sites
46
+
47
+ Op options are generated from the engine's Rust op registry, so its rules show
48
+ up as TypeScript errors instead of failed jobs:
49
+
50
+ ```ts
51
+ v.redact(faces, { mode: 'blur', radius: 21 }); // ✓ blur requires a radius
52
+ v.redact(faces, { mode: 'black', radius: 21 });
53
+ // ~~~~~~ compile error — `radius` is the
54
+ // blur/pixelate strength; black forbids it
55
+
56
+ v.pad({ w: 1920, h: 1080, align: 'center' }); // ✓ layout sugar
57
+ v.pad({ w: 1920, h: 1080, align: 'center', x: 0 });
58
+ // ~ compile error — `align` and
59
+ // `x`/`y` are mutually exclusive
60
+
61
+ v.detect({ model: 'dfine_x', threshold: 1.5 });
62
+ // throws RangeError while building: detect: threshold=1.5 must be in [0, 1]
63
+ ```
64
+
65
+ Optional params also accept an explicit `undefined` (stripped before the wire),
66
+ so computed options stay flat — `{ filter_classes: classes || undefined }`, no
67
+ conditional spreads.
68
+
45
69
  ### Multiple inputs
46
70
 
47
71
  Combine ops are methods on the first stream; open more inputs on the same graph:
@@ -81,6 +105,28 @@ const [v] = graph().open('long.mp4');
81
105
  const clip = snip(v, 30, 45); // seconds 30–45
82
106
  ```
83
107
 
108
+ ### Presets
109
+
110
+ Opinionated building blocks with production defaults — smaller than a recipe,
111
+ bigger than an op. Audio: `masterAudio` (podcast / music / broadcast / youtube
112
+ mastering chains), `noiseGate`, `limiter`, `radioVoice`, `telephone`, `ducking`,
113
+ `audioMix`, `channelMapPreset`, and synthesized `notification` / `ambience` /
114
+ `drone`. Text: `title`, `caption`, `textWatermark`, `lowerThird` on top of a
115
+ positioned `text` atom. Video: `xfadeChain` (automatic crossfade offset math),
116
+ `concatChain`, `fadeBookend`, and `kenBurns` / `kenBurnsChain` motion:
117
+
118
+ ```ts
119
+ import { graph, masterAudio, lowerThird, xfadeChain } from '@jtdigital/renderbox-sdk';
120
+
121
+ const g = graph();
122
+ const [v, a] = g.open('interview.mp4');
123
+
124
+ const video = lowerThird(v, 'Ada Lovelace', 'Analyst', { startTime: 2, endTime: 8 });
125
+ const audio = masterAudio(a, 'podcast'); // speechnorm → deesser → compressor → -16 LUFS
126
+
127
+ g.write('out.mp4', video, audio);
128
+ ```
129
+
84
130
  ## Running your pipeline on renderbox
85
131
 
86
132
  A `Graph` is a *description*. To actually render it, submit it as a job to
@@ -152,8 +198,14 @@ finished render back without running your own transport.
152
198
  - **Stream methods** — 220+ typed operations, one per engine op, on the sort it
153
199
  applies to (`scale`, `crop`, `fade`, `detect`, `track`, `transcribe`,
154
200
  `overlay`, `redact`, `depthBlur`, …).
201
+ - **Presets** — audio dynamics/mastering/synthesis (`masterAudio`, `noiseGate`,
202
+ `ducking`, `notification`, …), text styles (`title`, `caption`, `lowerThird`),
203
+ video sequencing (`xfadeChain`, `kenBurnsChain`, `fadeBookend`).
155
204
  - **Recipes** — `letterbox`, `snip`, `faceRedact`, `depthBlurPipeline`,
156
205
  `makeSlideshow`.
206
+ - **Named pipelines** — typed args for all 31 server-side pipelines
207
+ (`pipelineArgs('face-redact', { … })` → the `{ pipeline_id, args }` slice of a
208
+ `JobMessage`), generated from the exact serde structs the Rust builders parse.
157
209
  - **Wire types** — `GraphJSON`, `OpNode`, `JobMessage`, `ProgressMessage`,
158
210
  `CompletionMessage`, `FailureMessage`.
159
211
 
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Smart-editing bridge — the TS port of the Rust SDK's `ops::bridge`.
3
+ *
4
+ * Two-job pattern: run an analysis pass first (detections to JSONL via
5
+ * `writeDetections`, silences via `silencedetect`), post-process the results
6
+ * with the pure segment utilities here, then compile the edit decisions into a
7
+ * render graph (`compileHighlights`, `compileJumpCuts`, `compileSmartTrim`,
8
+ * `compileSmartCrop`).
9
+ */
10
+ import type { VideoStream, AudioStream } from './streams.js';
11
+ /** A scored, labeled time range (seconds). */
12
+ export interface TemporalSegment {
13
+ start: number;
14
+ end: number;
15
+ score: number;
16
+ label: string;
17
+ }
18
+ export declare function segmentDuration(s: TemporalSegment): number;
19
+ /** A detected silence (seconds), e.g. from `silencedetect`. */
20
+ export interface SilenceSegment {
21
+ start: number;
22
+ end: number;
23
+ }
24
+ export interface BBox {
25
+ x: number;
26
+ y: number;
27
+ w: number;
28
+ h: number;
29
+ confidence: number;
30
+ class: string;
31
+ }
32
+ /** One frame's detections, e.g. one line of a detections JSONL output. */
33
+ export interface DetectionFrame {
34
+ timestamp: number;
35
+ detections: BBox[];
36
+ }
37
+ /** A temporal condition over detection frames, evaluated into segments. */
38
+ export type TemporalPredicate = {
39
+ kind: 'threshold';
40
+ class: string;
41
+ minCount: number;
42
+ minDuration: number;
43
+ } | {
44
+ kind: 'absence';
45
+ class: string;
46
+ minDuration: number;
47
+ } | {
48
+ kind: 'region';
49
+ class: string;
50
+ region: BBox;
51
+ minOverlap: number;
52
+ minDuration: number;
53
+ };
54
+ /** An xfade transition between joined segments. */
55
+ export interface SegmentTransition {
56
+ /** xfade transition name, e.g. `'fade'`, `'dissolve'`. */
57
+ transition: string;
58
+ /** Overlap duration in seconds — must be shorter than every segment. */
59
+ duration: number;
60
+ }
61
+ /** A compiled edit: the video chain, its audio (when provided), and the
62
+ * resulting duration. */
63
+ export interface TimelineResult {
64
+ video: VideoStream;
65
+ audio?: AudioStream;
66
+ totalDuration: number;
67
+ }
68
+ export interface HighlightOpts {
69
+ transition?: SegmentTransition;
70
+ /** Seconds added before/after each segment. Default 0. */
71
+ padding?: number;
72
+ /** Keep only the N highest-scoring segments. */
73
+ maxSegments?: number;
74
+ /** Drop segments shorter than this (seconds). */
75
+ minSegmentDuration?: number;
76
+ /** Truncate the reel once this much content is collected (seconds). */
77
+ maxTotalDuration?: number;
78
+ }
79
+ export interface JumpCutOpts {
80
+ /** Source duration in seconds (bounds the kept ranges). */
81
+ totalDuration: number;
82
+ transition?: SegmentTransition;
83
+ padding?: number;
84
+ minSegmentDuration?: number;
85
+ maxTotalDuration?: number;
86
+ }
87
+ export interface SmartTrimOpts {
88
+ /** Source duration in seconds (bounds the kept ranges). */
89
+ totalDuration: number;
90
+ padding?: number;
91
+ minSegmentDuration?: number;
92
+ }
93
+ export interface SmartCropOpts {
94
+ /** Target aspect as [w, h], e.g. `[9, 16]`. */
95
+ targetAspect: [number, number];
96
+ /** Source frame size as [w, h] pixels. */
97
+ frameSize: [number, number];
98
+ /** EMA smoothing for the subject centroid, in [0, 1]. Default 0.8. */
99
+ smoothing?: number;
100
+ /** Pixels shaved off each side of the crop. Default 0. */
101
+ padding?: number;
102
+ /** Only follow detections of this class; omit to follow everything. */
103
+ subject?: string;
104
+ }
105
+ /** Merge segments whose gap is ≤ `minGap`, blending scores duration-weighted. */
106
+ export declare function mergeContiguous(segments: TemporalSegment[], minGap: number): TemporalSegment[];
107
+ /** The non-silent ranges of `[0, totalDuration]` as `[start, end]` pairs. */
108
+ export declare function invertSegments(silences: SilenceSegment[], totalDuration: number): Array<[number, number]>;
109
+ /** The `max` highest-scoring segments, re-sorted chronologically. */
110
+ export declare function selectTop(segments: TemporalSegment[], max: number): TemporalSegment[];
111
+ /** Keep segments until `maxDuration` of content is collected; the segment that
112
+ * crosses the budget is shortened to fit. */
113
+ export declare function truncateToDuration(segments: TemporalSegment[], maxDuration: number): TemporalSegment[];
114
+ export declare function filterByMinDuration(segments: TemporalSegment[], min: number): TemporalSegment[];
115
+ /** Widen each segment by `padding` seconds, clamped to `[0, totalDuration]`. */
116
+ export declare function applyPadding(segments: TemporalSegment[], padding: number, totalDuration: number): TemporalSegment[];
117
+ /** Intersection-over-union of two boxes. */
118
+ export declare function iou(a: BBox, b: BBox): number;
119
+ /** Evaluate a predicate over per-frame detections into temporal segments —
120
+ * consecutive matching frames become one segment; runs shorter than the
121
+ * predicate's `minDuration` are dropped. */
122
+ export declare function evaluatePredicate(frames: DetectionFrame[], predicate: TemporalPredicate, fps: number): TemporalSegment[];
123
+ /** Confidence-weighted centroid of the boxes, or undefined when empty. */
124
+ export declare function weightedCentroid(detections: BBox[]): [number, number] | undefined;
125
+ /** Exponential-moving-average smooth over a centroid track; returns the final
126
+ * smoothed point, or undefined when empty. */
127
+ export declare function smoothCentroids(points: Array<[number, number]>, alpha: number): [number, number] | undefined;
128
+ /** Cut the scored segments out of the source and join them into a highlight
129
+ * reel (optionally crossfaded), highest-value content first when capped. */
130
+ export declare function compileHighlights(video: VideoStream, audio: AudioStream | undefined, segments: TemporalSegment[], opts?: HighlightOpts): TimelineResult;
131
+ /** Remove the given silences, jump-cutting (or crossfading) the kept content
132
+ * back together. */
133
+ export declare function compileJumpCuts(video: VideoStream, audio: AudioStream | undefined, silences: SilenceSegment[], opts: JumpCutOpts): TimelineResult;
134
+ /** Like `compileJumpCuts` but always hard-cut (no transition path). */
135
+ export declare function compileSmartTrim(video: VideoStream, audio: AudioStream | undefined, silences: SilenceSegment[], opts: SmartTrimOpts): TimelineResult;
136
+ /** Crop the source to a target aspect around the (smoothed) subject centroid
137
+ * from per-frame detections. v1 is a single static crop — no per-frame track. */
138
+ export declare function compileSmartCrop(video: VideoStream, frames: DetectionFrame[], opts: SmartCropOpts): VideoStream;
139
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
package/dist/bridge.js ADDED
@@ -0,0 +1,338 @@
1
+ import { mk, _p } from './streams.js';
2
+ export function segmentDuration(s) {
3
+ return s.end - s.start;
4
+ }
5
+ // ---------------------------------------------------------------------------
6
+ // Segment utilities (pure)
7
+ // ---------------------------------------------------------------------------
8
+ /** Merge segments whose gap is ≤ `minGap`, blending scores duration-weighted. */
9
+ export function mergeContiguous(segments, minGap) {
10
+ if (segments.length === 0)
11
+ return [];
12
+ const sorted = [...segments].sort((a, b) => a.start - b.start);
13
+ const merged = [{ ...sorted[0] }];
14
+ for (const seg of sorted.slice(1)) {
15
+ const last = merged[merged.length - 1];
16
+ if (seg.start - last.end <= minGap) {
17
+ const lastDur = segmentDuration(last);
18
+ const segDur = segmentDuration(seg);
19
+ const totalDur = lastDur + segDur;
20
+ last.score = totalDur > 0
21
+ ? Math.min((last.score * lastDur + seg.score * segDur) / totalDur, 1)
22
+ : last.score;
23
+ last.end = Math.max(seg.end, last.end);
24
+ }
25
+ else {
26
+ merged.push({ ...seg });
27
+ }
28
+ }
29
+ return merged;
30
+ }
31
+ /** The non-silent ranges of `[0, totalDuration]` as `[start, end]` pairs. */
32
+ export function invertSegments(silences, totalDuration) {
33
+ if (silences.length === 0)
34
+ return [[0, totalDuration]];
35
+ const sorted = [...silences].sort((a, b) => a.start - b.start);
36
+ const keep = [];
37
+ let cursor = 0;
38
+ for (const s of sorted) {
39
+ if (s.start > cursor)
40
+ keep.push([cursor, s.start]);
41
+ cursor = Math.max(cursor, s.end);
42
+ }
43
+ if (cursor < totalDuration)
44
+ keep.push([cursor, totalDuration]);
45
+ return keep;
46
+ }
47
+ /** The `max` highest-scoring segments, re-sorted chronologically. */
48
+ export function selectTop(segments, max) {
49
+ return [...segments]
50
+ .sort((a, b) => b.score - a.score)
51
+ .slice(0, max)
52
+ .sort((a, b) => a.start - b.start);
53
+ }
54
+ /** Keep segments until `maxDuration` of content is collected; the segment that
55
+ * crosses the budget is shortened to fit. */
56
+ export function truncateToDuration(segments, maxDuration) {
57
+ const result = [];
58
+ let budget = maxDuration;
59
+ for (const seg of segments) {
60
+ if (budget <= 0)
61
+ break;
62
+ const dur = segmentDuration(seg);
63
+ if (dur <= budget) {
64
+ result.push({ ...seg });
65
+ budget -= dur;
66
+ }
67
+ else {
68
+ result.push({ ...seg, end: seg.start + budget });
69
+ break;
70
+ }
71
+ }
72
+ return result;
73
+ }
74
+ export function filterByMinDuration(segments, min) {
75
+ return segments.filter((s) => segmentDuration(s) >= min);
76
+ }
77
+ /** Widen each segment by `padding` seconds, clamped to `[0, totalDuration]`. */
78
+ export function applyPadding(segments, padding, totalDuration) {
79
+ return segments.map((s) => ({
80
+ ...s,
81
+ start: Math.max(s.start - padding, 0),
82
+ end: Math.min(s.end + padding, totalDuration),
83
+ }));
84
+ }
85
+ // ---------------------------------------------------------------------------
86
+ // Predicate evaluation
87
+ // ---------------------------------------------------------------------------
88
+ /** Intersection-over-union of two boxes. */
89
+ export function iou(a, b) {
90
+ const x1 = Math.max(a.x, b.x);
91
+ const y1 = Math.max(a.y, b.y);
92
+ const x2 = Math.min(a.x + a.w, b.x + b.w);
93
+ const y2 = Math.min(a.y + a.h, b.y + b.h);
94
+ const inter = Math.max(x2 - x1, 0) * Math.max(y2 - y1, 0);
95
+ const union = a.w * a.h + b.w * b.h - inter;
96
+ return union <= 0 ? 0 : inter / union;
97
+ }
98
+ function frameMatches(frame, predicate) {
99
+ switch (predicate.kind) {
100
+ case 'threshold':
101
+ return frame.detections.filter((d) => d.class === predicate.class).length >= predicate.minCount;
102
+ case 'absence':
103
+ return !frame.detections.some((d) => d.class === predicate.class);
104
+ case 'region':
105
+ return frame.detections.some((d) => d.class === predicate.class && iou(d, predicate.region) >= predicate.minOverlap);
106
+ }
107
+ }
108
+ /** Evaluate a predicate over per-frame detections into temporal segments —
109
+ * consecutive matching frames become one segment; runs shorter than the
110
+ * predicate's `minDuration` are dropped. */
111
+ export function evaluatePredicate(frames, predicate, fps) {
112
+ if (frames.length === 0 || fps <= 0)
113
+ return [];
114
+ const frameDur = 1 / fps;
115
+ const label = predicate.kind === 'absence' ? `no_${predicate.class}` : predicate.class;
116
+ const segments = [];
117
+ let runStart;
118
+ for (const frame of frames) {
119
+ if (frameMatches(frame, predicate)) {
120
+ runStart ??= frame.timestamp;
121
+ }
122
+ else if (runStart !== undefined) {
123
+ segments.push({ start: runStart, end: frame.timestamp, score: 1, label });
124
+ runStart = undefined;
125
+ }
126
+ }
127
+ if (runStart !== undefined) {
128
+ segments.push({ start: runStart, end: frames[frames.length - 1].timestamp + frameDur, score: 1, label });
129
+ }
130
+ return segments.filter((s) => segmentDuration(s) >= predicate.minDuration);
131
+ }
132
+ // ---------------------------------------------------------------------------
133
+ // Centroid / geometry helpers
134
+ // ---------------------------------------------------------------------------
135
+ /** Confidence-weighted centroid of the boxes, or undefined when empty. */
136
+ export function weightedCentroid(detections) {
137
+ if (detections.length === 0)
138
+ return undefined;
139
+ const totalConf = detections.reduce((s, d) => s + d.confidence, 0);
140
+ if (totalConf <= 0)
141
+ return undefined;
142
+ const cx = detections.reduce((s, d) => s + (d.x + d.w / 2) * d.confidence, 0) / totalConf;
143
+ const cy = detections.reduce((s, d) => s + (d.y + d.h / 2) * d.confidence, 0) / totalConf;
144
+ return [cx, cy];
145
+ }
146
+ /** Exponential-moving-average smooth over a centroid track; returns the final
147
+ * smoothed point, or undefined when empty. */
148
+ export function smoothCentroids(points, alpha) {
149
+ if (points.length === 0)
150
+ return undefined;
151
+ let [sx, sy] = points[0];
152
+ for (const [x, y] of points.slice(1)) {
153
+ sx = alpha * x + (1 - alpha) * sx;
154
+ sy = alpha * y + (1 - alpha) * sy;
155
+ }
156
+ return [sx, sy];
157
+ }
158
+ // ---------------------------------------------------------------------------
159
+ // Internal: segment extraction + joining
160
+ // ---------------------------------------------------------------------------
161
+ function extractVideo(video, ranges) {
162
+ return ranges.map(([start, end]) => video.trim({ start, end }).setpts({ expr: 'PTS-STARTPTS' }));
163
+ }
164
+ function extractAudio(audio, ranges) {
165
+ return ranges.map(([start, end]) => audio.atrim({ start, end }).asetpts({ expr: 'PTS-STARTPTS' }));
166
+ }
167
+ /** Audio counterpart of `concat` — same CombineN op with `v=0` (audio-only),
168
+ * mirroring the Rust SDK's `concat_audio`. Not a generated stream method
169
+ * because the generated `concat` is video-sorted. */
170
+ function concatAudio(segments) {
171
+ const first = segments[0];
172
+ const g = first._graph;
173
+ const id = g._addNode({
174
+ kind: 'CombineN',
175
+ op: 'concat',
176
+ streams: segments.map((s) => s._id),
177
+ params: _p({ v: 0 }),
178
+ });
179
+ return mk('Audio', id, g);
180
+ }
181
+ function acrossfadeChain(segments, duration) {
182
+ let acc = segments[0];
183
+ for (const seg of segments.slice(1))
184
+ acc = acc.acrossfade(seg, { d: duration });
185
+ return acc;
186
+ }
187
+ function xfadeChainWithDurations(clips, durations, t) {
188
+ let result = clips[0];
189
+ let elapsedContent = durations[0];
190
+ let elapsedTransitions = 0;
191
+ for (let i = 1; i < clips.length; i++) {
192
+ const offset = elapsedContent - elapsedTransitions - t.duration;
193
+ result = result.xfade(clips[i], { transition: t.transition, duration: t.duration, offset });
194
+ elapsedContent += durations[i];
195
+ elapsedTransitions += t.duration;
196
+ }
197
+ return result;
198
+ }
199
+ function singleSegmentResult(video, audio, seg) {
200
+ const v = video.trim({ start: seg.start, end: seg.end }).setpts({ expr: 'PTS-STARTPTS' });
201
+ const a = audio?.atrim({ start: seg.start, end: seg.end }).asetpts({ expr: 'PTS-STARTPTS' });
202
+ return { video: v, ...(a ? { audio: a } : {}), totalDuration: segmentDuration(seg) };
203
+ }
204
+ function buildJoin(videoSegments, audioSegments, durations, transition) {
205
+ let video;
206
+ if (transition) {
207
+ const minDur = Math.min(...durations);
208
+ if (transition.duration >= minDur) {
209
+ throw new Error(`transition duration ${transition.duration} must be less than shortest segment (${minDur}s)`);
210
+ }
211
+ video = xfadeChainWithDurations(videoSegments, durations, transition);
212
+ }
213
+ else {
214
+ video = videoSegments[0].concat(videoSegments.slice(1));
215
+ }
216
+ const audio = audioSegments.length === 0
217
+ ? undefined
218
+ : transition
219
+ ? acrossfadeChain(audioSegments, transition.duration)
220
+ : concatAudio(audioSegments);
221
+ const sum = durations.reduce((s, d) => s + d, 0);
222
+ const totalDuration = transition ? sum - (durations.length - 1) * transition.duration : sum;
223
+ return { video, ...(audio ? { audio } : {}), totalDuration };
224
+ }
225
+ function compileSegments(video, audio, working, transition) {
226
+ if (working.length === 1)
227
+ return singleSegmentResult(video, audio, working[0]);
228
+ const ranges = working.map((s) => [s.start, s.end]);
229
+ const durations = working.map(segmentDuration);
230
+ return buildJoin(extractVideo(video, ranges), audio ? extractAudio(audio, ranges) : [], durations, transition);
231
+ }
232
+ // ---------------------------------------------------------------------------
233
+ // Compile operations
234
+ // ---------------------------------------------------------------------------
235
+ /** Cut the scored segments out of the source and join them into a highlight
236
+ * reel (optionally crossfaded), highest-value content first when capped. */
237
+ export function compileHighlights(video, audio, segments, opts) {
238
+ if (segments.length === 0) {
239
+ throw new Error('compileHighlights: at least 1 segment required');
240
+ }
241
+ let working = [...segments];
242
+ if (opts?.minSegmentDuration !== undefined) {
243
+ working = filterByMinDuration(working, opts.minSegmentDuration);
244
+ }
245
+ if (opts?.maxSegments !== undefined) {
246
+ working = selectTop(working, opts.maxSegments);
247
+ }
248
+ else {
249
+ working.sort((a, b) => a.start - b.start);
250
+ }
251
+ const padding = opts?.padding ?? 0;
252
+ if (padding > 0) {
253
+ const maxEnd = working.reduce((m, s) => Math.max(m, s.end), 0);
254
+ working = applyPadding(working, padding, maxEnd + padding);
255
+ }
256
+ if (opts?.maxTotalDuration !== undefined) {
257
+ working = truncateToDuration(working, opts.maxTotalDuration);
258
+ }
259
+ if (working.length === 0) {
260
+ throw new Error('compileHighlights: no segments remain after filtering');
261
+ }
262
+ return compileSegments(video, audio, working, opts?.transition);
263
+ }
264
+ /** Remove the given silences, jump-cutting (or crossfading) the kept content
265
+ * back together. */
266
+ export function compileJumpCuts(video, audio, silences, opts) {
267
+ const working = keepSegmentsFromSilences(silences, opts.totalDuration, opts.padding ?? 0, opts.minSegmentDuration, opts.maxTotalDuration, 'compileJumpCuts');
268
+ return compileSegments(video, audio, working, opts.transition);
269
+ }
270
+ /** Like `compileJumpCuts` but always hard-cut (no transition path). */
271
+ export function compileSmartTrim(video, audio, silences, opts) {
272
+ const working = keepSegmentsFromSilences(silences, opts.totalDuration, opts.padding ?? 0, opts.minSegmentDuration, undefined, 'compileSmartTrim');
273
+ return compileSegments(video, audio, working, undefined);
274
+ }
275
+ function keepSegmentsFromSilences(silences, totalDuration, padding, minSegmentDuration, maxTotalDuration, ctx) {
276
+ if (totalDuration <= 0) {
277
+ throw new Error(`${ctx}: totalDuration must be positive, got ${totalDuration}`);
278
+ }
279
+ const keep = invertSegments(silences, totalDuration);
280
+ if (keep.length === 0) {
281
+ throw new Error(`${ctx}: silence covers entire duration, no segments to keep`);
282
+ }
283
+ let working = keep.map(([start, end]) => ({ start, end, score: 1, label: 'keep' }));
284
+ if (padding > 0) {
285
+ working = applyPadding(working, padding, totalDuration);
286
+ working = mergeContiguous(working, 0);
287
+ }
288
+ if (minSegmentDuration !== undefined) {
289
+ working = filterByMinDuration(working, minSegmentDuration);
290
+ }
291
+ if (maxTotalDuration !== undefined) {
292
+ working = truncateToDuration(working, maxTotalDuration);
293
+ }
294
+ if (working.length === 0) {
295
+ throw new Error(`${ctx}: no segments remain after filtering`);
296
+ }
297
+ return working;
298
+ }
299
+ /** Crop the source to a target aspect around the (smoothed) subject centroid
300
+ * from per-frame detections. v1 is a single static crop — no per-frame track. */
301
+ export function compileSmartCrop(video, frames, opts) {
302
+ if (frames.length === 0) {
303
+ throw new Error('compileSmartCrop: at least 1 detection frame required');
304
+ }
305
+ const [srcW, srcH] = opts.frameSize;
306
+ const [aspectW, aspectH] = opts.targetAspect;
307
+ if (srcW <= 0 || srcH <= 0) {
308
+ throw new Error(`compileSmartCrop: frame dimensions must be positive, got ${srcW}x${srcH}`);
309
+ }
310
+ if (aspectW <= 0 || aspectH <= 0) {
311
+ throw new Error(`compileSmartCrop: aspect ratio must be positive, got ${aspectW}:${aspectH}`);
312
+ }
313
+ const centroids = [];
314
+ for (const f of frames) {
315
+ const dets = opts.subject ? f.detections.filter((d) => d.class === opts.subject) : f.detections;
316
+ const c = weightedCentroid(dets);
317
+ if (c)
318
+ centroids.push(c);
319
+ }
320
+ const [cx, cy] = centroids.length === 0
321
+ ? [srcW / 2, srcH / 2]
322
+ : smoothCentroids(centroids, opts.smoothing ?? 0.8);
323
+ const targetRatio = aspectW / aspectH;
324
+ const srcRatio = srcW / srcH;
325
+ let [cropW, cropH] = targetRatio > srcRatio
326
+ ? [srcW, Math.round(srcW / targetRatio)]
327
+ : [Math.round(srcH * targetRatio), srcH];
328
+ const padding = opts.padding ?? 0;
329
+ cropW = Math.max(cropW - padding * 2, 0);
330
+ cropH = Math.max(cropH - padding * 2, 0);
331
+ if (cropW === 0 || cropH === 0) {
332
+ throw new Error(`compileSmartCrop: padding ${padding} too large, crop dimensions would be zero`);
333
+ }
334
+ const x = Math.min(Math.max(Math.round(cx - cropW / 2), 0), srcW - cropW);
335
+ const y = Math.min(Math.max(Math.round(cy - cropH / 2), 0), srcH - cropH);
336
+ return video.crop({ w: cropW, h: cropH, x, y });
337
+ }
338
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}