@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.
- package/README.md +54 -2
- package/dist/bridge.d.ts +139 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +338 -0
- package/dist/bridge.js.map +1 -0
- package/dist/graph.d.ts +28 -22
- package/dist/graph.d.ts.map +1 -1
- package/dist/graph.js +7 -7
- package/dist/graph.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/pipelines.d.ts +516 -0
- package/dist/pipelines.d.ts.map +1 -0
- package/dist/pipelines.js +16 -0
- package/dist/pipelines.js.map +1 -0
- package/dist/presets/audio.d.ts +43 -0
- package/dist/presets/audio.d.ts.map +1 -0
- package/dist/presets/audio.js +148 -0
- package/dist/presets/audio.js.map +1 -0
- package/dist/presets/index.d.ts +5 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +5 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/position.d.ts +39 -0
- package/dist/presets/position.d.ts.map +1 -0
- package/dist/presets/position.js +40 -0
- package/dist/presets/position.js.map +1 -0
- package/dist/presets/text.d.ts +90 -0
- package/dist/presets/text.d.ts.map +1 -0
- package/dist/presets/text.js +132 -0
- package/dist/presets/text.js.map +1 -0
- package/dist/presets/video.d.ts +46 -0
- package/dist/presets/video.d.ts.map +1 -0
- package/dist/presets/video.js +108 -0
- package/dist/presets/video.js.map +1 -0
- package/dist/recipes/faceRedact.d.ts.map +1 -1
- package/dist/recipes/faceRedact.js +8 -4
- package/dist/recipes/faceRedact.js.map +1 -1
- package/dist/recipes/makeSlideshow.d.ts +2 -1
- package/dist/recipes/makeSlideshow.d.ts.map +1 -1
- package/dist/recipes/makeSlideshow.js +3 -71
- package/dist/recipes/makeSlideshow.js.map +1 -1
- package/dist/streams.d.ts +791 -699
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +283 -201
- package/dist/streams.js.map +1 -1
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- 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: '
|
|
40
|
-
.track({ algorithm: 'bytetrack' });
|
|
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
|
|
package/dist/bridge.d.ts
ADDED
|
@@ -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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"}
|