@vosjs/cli 0.24.0 → 0.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{chunk-NOR522G5.js → chunk-GHJ2BFQG.js} +26 -8
- package/dist/chunk-GHJ2BFQG.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{run-UZW5LPJQ.js → run-NTVAMME2.js} +2 -2
- package/package.json +3 -3
- package/schema/doc.schema.json +86 -43
- package/dist/chunk-NOR522G5.js.map +0 -1
- /package/dist/{run-UZW5LPJQ.js.map → run-NTVAMME2.js.map} +0 -0
package/README.md
CHANGED
|
@@ -89,7 +89,7 @@ vos plan take --reuse # re-time that cut onto
|
|
|
89
89
|
|
|
90
90
|
**Digest first.** `vos digest <take>` is how an agent sees a recording without reading the video. It writes `digest/digest.json`: one moment per thing the cursor track says mattered (click clusters, typing sessions, scroll runs, dwells, idle gaps, head, tail, and frame-diff scene changes), each with source and output extents, a normalized `focus` and `rect` you can copy into a zoom span, per-second `activity`, and the planners' `proposed` span ids; plus one footage frame and a crop around the target per moment, and `sheet.png`, the contact sheet. Read the JSON, then the sheet, then a crop only where you must decide. `vos validate` then warns when a zoom does not contain what was clicked under it, and `vos frames --at-moments` renders the composed output at every moment so a still and its footage crop share an id.
|
|
91
91
|
|
|
92
|
-
**Many media in one take (concat).** `doc.json` may carry `media: [{ id, videoKey, cursor, meta, … }]`, the take's OTHER recordings or uploads, each the `source` shape with an `id`; a segment on one (`{ in, out, media: "m1" }`) plays it, and a zoom, tilt, speed, freeze or cam-move span names the media its source seconds belong to (absent = the primary, `source`). The Video row shows the clips in order, a span is drawn where its media plays, `vos plan` proposes zoom and speed spans on every media from its own cursor track, `vos validate` measures each span against its own media's length, and `vos push` and `vos pull --media` carry every media through the recording door. Sound: the primary's tracks play at the primary's moments; another media's own audio is not spliced into the cut yet.
|
|
92
|
+
**Many media in one take (concat).** `doc.json` may carry `media: [{ id, videoKey, cursor, meta, … }]`, the take's OTHER recordings or uploads, each the `source` shape with an `id`; a segment on one (`{ in, out, media: "m1" }`) plays it, and a zoom, tilt, speed, freeze or cam-move span names the media its source seconds belong to (absent = the primary, `source`). The Video row shows the clips in order, a span is drawn where its media plays, `vos plan` proposes zoom and speed spans on every media from its own cursor track, `vos validate` measures each span against its own media's length, and `vos push` and `vos pull --media` carry every media through the recording door. A media wears its OWN card: `media[].frame` carries the card-owned fields (its placement and size as `inset`, the browser bar, the corner, the shadow, the border, the cover fit and its focus) over the take's frame while it plays; the bar names that media's recorded page, an upload with no page wears none, and the frame-wide fields (the aspect, the padding, the ground, the backdrop, the card's animation) stay the take's. Sound: the primary's tracks play at the primary's moments; another media's own audio is not spliced into the cut yet.
|
|
93
93
|
|
|
94
94
|
**A series shares its look by data.** `vos plan <take> --style <seed doc.json | vosId>` copies the seed's `zoomStyle`, `zoomParams`, `speedParams`, `tiltStyle`, `frame`, `cursor`, `cam` and `export` onto a new take (never its spans, overlays or audio) and re-plans the automatic spans under them. A seed that is a POSTER carries its layout too: its card placement, its `stage-*` clips by id (with the release's words from LAUNCH.md's `headline` and `kicker` roles, BRAND.md's `wordmark`, or `--headline` and `--kicker` patched in; the brand's mark from BRAND.md `logoUrl` fetched into `<take>/brand/` for `stage-mark`), its rest lean, its trailing freeze. What could not follow is said in words.
|
|
95
95
|
|
|
@@ -186,16 +186,17 @@ import {
|
|
|
186
186
|
CAM_SPAN_MIN,
|
|
187
187
|
CARD_ENTER_KINDS,
|
|
188
188
|
CARD_EXIT_KINDS,
|
|
189
|
-
IDLE_KINDS,
|
|
190
|
-
MEDIA_ENTER_KINDS,
|
|
191
|
-
MEDIA_EXIT_KINDS,
|
|
192
|
-
TEXT_ENTER_KINDS,
|
|
193
|
-
TEXT_EXIT_KINDS,
|
|
194
189
|
EXPORT_RESOLUTION_OPTIONS,
|
|
195
190
|
FREEZE_SECONDS_MAX,
|
|
196
191
|
FREEZE_SECONDS_MIN,
|
|
192
|
+
IDLE_KINDS,
|
|
193
|
+
MEDIA_ENTER_KINDS,
|
|
194
|
+
MEDIA_EXIT_KINDS,
|
|
195
|
+
MEDIA_FRAME_KEYS,
|
|
197
196
|
SPEED_RATE_MAX,
|
|
198
197
|
SPEED_RATE_MIN,
|
|
198
|
+
TEXT_ENTER_KINDS,
|
|
199
|
+
TEXT_EXIT_KINDS,
|
|
199
200
|
TILT_DEG_MAX,
|
|
200
201
|
TILT_SPAN_MIN,
|
|
201
202
|
ZOOM_LEVEL_MAX,
|
|
@@ -366,6 +367,21 @@ function lintDoc(docIn) {
|
|
|
366
367
|
if (!id) problems.push(`media[${i}]: id must be a string`);
|
|
367
368
|
else if (mediaLen.has(id))
|
|
368
369
|
problems.push(`media[${i}] (${id}): duplicate id`);
|
|
370
|
+
const mf = m.frame;
|
|
371
|
+
if (mf !== void 0) {
|
|
372
|
+
if (!isObj(mf)) {
|
|
373
|
+
problems.push(
|
|
374
|
+
`media[${i}]${id ? ` (${id})` : ""}: frame must be an object`
|
|
375
|
+
);
|
|
376
|
+
} else {
|
|
377
|
+
for (const k of Object.keys(mf)) {
|
|
378
|
+
if (!MEDIA_FRAME_KEYS.includes(k))
|
|
379
|
+
problems.push(
|
|
380
|
+
`media[${i}]${id ? ` (${id})` : ""}.frame.${k}: not a card field (a media's frame carries ${MEDIA_FRAME_KEYS.join(", ")}; the rest is the take's frame)`
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
369
385
|
if (typeof m.videoKey !== "string")
|
|
370
386
|
problems.push(
|
|
371
387
|
`media[${i}]${id ? ` (${id})` : ""}: videoKey must be a string`
|
|
@@ -3482,6 +3498,7 @@ import {
|
|
|
3482
3498
|
endCardClips,
|
|
3483
3499
|
migrateMotion,
|
|
3484
3500
|
ratedSegments as ratedSegments4,
|
|
3501
|
+
sameMedia,
|
|
3485
3502
|
spanOutputExtent as spanOutputExtent4
|
|
3486
3503
|
} from "@vosjs/studio-core";
|
|
3487
3504
|
var SOUND_DESTINATIONS = /* @__PURE__ */ new Set([
|
|
@@ -3609,7 +3626,7 @@ function proposeMotion(input, opts) {
|
|
|
3609
3626
|
const lastSeg = doc.segments.at(-1);
|
|
3610
3627
|
if (lastSeg) {
|
|
3611
3628
|
const own = (doc.freeze ?? []).filter(
|
|
3612
|
-
(f) => Math.abs(f.at - lastSeg.out) > 1e-9
|
|
3629
|
+
(f) => Math.abs(f.at - lastSeg.out) > 1e-9 || !sameMedia(f.media, lastSeg.media)
|
|
3613
3630
|
);
|
|
3614
3631
|
const taken = new Set(own.map((f) => f.id));
|
|
3615
3632
|
let n = 0;
|
|
@@ -3620,7 +3637,8 @@ function proposeMotion(input, opts) {
|
|
|
3620
3637
|
id: `f${n}`,
|
|
3621
3638
|
at: lastSeg.out,
|
|
3622
3639
|
seconds: END_CARD_SECONDS,
|
|
3623
|
-
from: END_CARD_FROM
|
|
3640
|
+
from: END_CARD_FROM,
|
|
3641
|
+
...lastSeg.media ? { media: lastSeg.media } : {}
|
|
3624
3642
|
}
|
|
3625
3643
|
].sort((a, b) => a.at - b.at);
|
|
3626
3644
|
}
|
|
@@ -10343,4 +10361,4 @@ export {
|
|
|
10343
10361
|
convertAgentBrowser,
|
|
10344
10362
|
run
|
|
10345
10363
|
};
|
|
10346
|
-
//# sourceMappingURL=chunk-
|
|
10364
|
+
//# sourceMappingURL=chunk-GHJ2BFQG.js.map
|