video-editing 1.3.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.
@@ -0,0 +1,162 @@
1
+ # Timeline v2 vocabulary — feature-by-feature reference
2
+
3
+ Every feature of the authored `<job>/timeline.json` (version 2), with one minimal JSON
4
+ example each. Validate with `video-editing timeline validate`; compile with
5
+ `timeline compile` (it resolves phrase anchors, derives caption cues and emits
6
+ `resolved/plan.json` + legacy `edl.json`). Items all carry a unique `id`; word anchors
7
+ (`{type:"words", source, phrase}`) resolve via the transcript — use `timeline resolve`
8
+ to disambiguate. Capability status per feature: run `timeline validate` — `staged`
9
+ features compile but warn (render path not yet proven); `ready` features render via
10
+ `compose` / the cloud render.
11
+
12
+ ## Cut (keep-ranges)
13
+
14
+ ```json
15
+ { "cut": { "ranges": [ { "id": "rng_1", "source": "SRC", "start": 11.35, "end": 14.12, "beat": "HOOK" } ] } }
16
+ ```
17
+
18
+ ## Captions (derived at compile — never hand-write cues)
19
+
20
+ ```json
21
+ { "captions": { "enabled": true, "preset": "grouped", "style": { "maxWords": 4 } } }
22
+ ```
23
+
24
+ ### Word styling — the canonical "make word X red"
25
+
26
+ `op:"style"` overrides tag the anchored words with `color` (hex or simple CSS name)
27
+ and/or `emphasis` (`"pop"` = scale pop at the word's onset, `"highlight"` = background
28
+ highlight sweep). At least one of color/emphasis is required. Styling never changes
29
+ cue grouping.
30
+
31
+ ```json
32
+ {
33
+ "captions": {
34
+ "enabled": true,
35
+ "overrides": [
36
+ {
37
+ "id": "capfix_red",
38
+ "op": "style",
39
+ "anchor": { "type": "words", "source": "SRC", "phrase": "important" },
40
+ "color": "#ff5c5c"
41
+ }
42
+ ]
43
+ }
44
+ }
45
+ ```
46
+
47
+ Emphasis variant: add `"emphasis": "pop"` (or `"highlight"`) to the same override.
48
+
49
+ ### Karaoke sweep (staged)
50
+
51
+ `style.karaoke: true` marks every derived cue for a per-word highlight sweep (each
52
+ word brightens at its onset within the grouped cue).
53
+
54
+ ```json
55
+ { "captions": { "enabled": true, "style": { "karaoke": true } } }
56
+ ```
57
+
58
+ ### Flow overrides (existing)
59
+
60
+ `op:"replace-text"` (needs `text`), `op:"hide"`, `op:"break-line"` — same anchor shape.
61
+
62
+ ## Zooms
63
+
64
+ Static punch-in: `rect` (unit-canvas crop region, `x+w<=1`, `y+h<=1`) + `scale`
65
+ (`1 < scale <= 3`).
66
+
67
+ ```json
68
+ {
69
+ "zooms": [
70
+ {
71
+ "id": "zm_1",
72
+ "anchor": { "type": "words", "source": "SRC", "phrase": "the key moment" },
73
+ "rect": { "x": 0.25, "y": 0.2, "w": 0.5, "h": 0.5 },
74
+ "scale": 1.35
75
+ }
76
+ ]
77
+ }
78
+ ```
79
+
80
+ ### Zoom ramp
81
+
82
+ Add `to` (`rect` and/or `scale`, same bounds) — the zoom animates from the base
83
+ rect/scale to `to` over the zoom window. `ease: {in, out}` shapes the ramp
84
+ (both > 0 → smooth in-out; one side → one-sided ease; both 0 → linear).
85
+
86
+ ```json
87
+ {
88
+ "zooms": [
89
+ {
90
+ "id": "zm_ramp",
91
+ "anchor": { "type": "source", "source": "SRC", "start": 18, "end": 22 },
92
+ "rect": { "x": 0.25, "y": 0.2, "w": 0.5, "h": 0.5 },
93
+ "scale": 1.2,
94
+ "to": { "scale": 1.8, "rect": { "x": 0.1, "y": 0.1, "w": 0.4, "h": 0.4 } },
95
+ "ease": { "in": 0.25, "out": 0.25 }
96
+ }
97
+ ]
98
+ }
99
+ ```
100
+
101
+ ## Overlays
102
+
103
+ Text / title-card (existing): `kind:"text"|"title-card"` + `text`.
104
+
105
+ ```json
106
+ {
107
+ "overlays": [
108
+ { "id": "ov_1", "kind": "text", "text": "wait for it…", "anchor": { "type": "output", "at": "start", "durationS": 2 } }
109
+ ]
110
+ }
111
+ ```
112
+
113
+ ### Sticker / image (positioned image, no card chrome)
114
+
115
+ `kind:"sticker"` (or `"image"`) requires `asset.ref` — a **job-dir-relative path**
116
+ (convention: keep files under `<job>/assets/`). `layout.x/y` is the center (unit
117
+ canvas), `size.w/h` are canvas fractions (sticker default ~0.25 of width, square),
118
+ `z` (0–50) is the stacking order. `enter`/`exit` are animation presets
119
+ (`fade | pop | slide-up | slide-down | scale-in`, `durationS` ≤ 2, capped by the
120
+ overlay's on-screen window; exit ends exactly at the overlay's end).
121
+
122
+ ```json
123
+ {
124
+ "overlays": [
125
+ {
126
+ "id": "ov_logo",
127
+ "kind": "sticker",
128
+ "asset": { "ref": "assets/logo.png" },
129
+ "anchor": { "type": "words", "source": "SRC", "phrase": "our product", "edge": "start" },
130
+ "durationS": 2.5,
131
+ "layout": { "x": 0.3, "y": 0.35 },
132
+ "size": { "w": 0.25 },
133
+ "z": 10,
134
+ "enter": { "preset": "pop", "durationS": 0.35 },
135
+ "exit": { "preset": "fade", "durationS": 0.4 }
136
+ }
137
+ ]
138
+ }
139
+ ```
140
+
141
+ Missing asset files fail `timeline compile` with `asset-missing`. On
142
+ `review push --timeline/--complete` referenced assets are uploaded to clipready
143
+ automatically (sha256-cached in `<job>/review/assets.json`).
144
+
145
+ ## Audio beds (staged)
146
+
147
+ ```json
148
+ {
149
+ "audio": [
150
+ { "id": "aud_1", "kind": "music", "asset": { "ref": "assets/bed.mp3" }, "anchor": { "type": "output", "at": "full" }, "gainDb": -18 }
151
+ ]
152
+ }
153
+ ```
154
+
155
+ ## Grade (staged)
156
+
157
+ Declarative color grade for the composition render path — distinct from the legacy
158
+ ffmpeg grade string (which `settings.grade` still accepts).
159
+
160
+ ```json
161
+ { "settings": { "grade": { "preset": "teal-orange", "intensity": 0.6 } } }
162
+ ```