@pixerate/editor 0.222.1 → 0.222.3
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/package.json +1 -1
- package/skills/README.md +8 -1
- package/skills/pixerate-paint-editor/SKILL.md +20 -59
- package/skills/pixerate-paint-editor/references/oils.md +19 -0
- package/skills/pixerate-paint-editor/references/wet-media.md +35 -0
- package/skills/pixerate-paint-oil-impasto/SKILL.md +103 -0
- package/skills/pixerate-paint-oil-impasto/evals/impasto-highlights.json +24 -0
- package/skills/pixerate-paint-oil-impasto/evals/lean-to-thick.json +17 -0
- package/skills/pixerate-paint-oil-impasto/evals/mix-green.json +15 -0
- package/skills/pixerate-paint-sketch-to-finish/SKILL.md +97 -0
- package/skills/pixerate-paint-sketch-to-finish/evals/clipped-shading.json +26 -0
- package/skills/pixerate-paint-sketch-to-finish/evals/flats-under-ink.json +27 -0
- package/skills/pixerate-paint-sketch-to-finish/evals/sketch-ink-hide.json +20 -0
- package/skills/pixerate-paint-watercolour/SKILL.md +106 -0
- package/skills/pixerate-paint-watercolour/evals/glaze-over-dry.json +24 -0
- package/skills/pixerate-paint-watercolour/evals/paper-and-brush-for-detail.json +16 -0
- package/skills/pixerate-paint-watercolour/evals/sky-wash.json +19 -0
- package/skills/pixerate-video-colour-grade/SKILL.md +105 -0
- package/skills/pixerate-video-colour-grade/evals/look-in-one-place.json +16 -0
- package/skills/pixerate-video-colour-grade/evals/lut-keep-skin.json +132 -0
- package/skills/pixerate-video-colour-grade/evals/match-exposure.json +14 -0
- package/skills/pixerate-video-editor/SKILL.md +3 -0
- package/skills/pixerate-video-montage/SKILL.md +99 -0
- package/skills/pixerate-video-montage/evals/assemble-on-beats.json +231 -0
- package/skills/pixerate-video-montage/evals/music-and-ending.json +210 -0
- package/skills/pixerate-video-montage/evals/short-crossfades.json +190 -0
- package/skills/pixerate-video-social-cut/SKILL.md +105 -0
- package/skills/pixerate-video-social-cut/evals/hook-first.json +19 -0
- package/skills/pixerate-video-social-cut/evals/opening-title.json +14 -0
- package/skills/pixerate-video-social-cut/evals/vertical-reframe.json +15 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixerate-paint-watercolour
|
|
3
|
+
description: The watercolour workflow in the Pixerate paint editor - choosing the paper, planning light to dark and keeping the paper's white for highlights, wet-in-wet and wet-on-dry washes, letting water flow and drying before glazing, steering water with the wet tools, granulation, blooms and edge darkening, and finishing detail with a small brush. Use when asked to paint in watercolour or gouache, lay a wash, paint a sky, glaze, paint wet-in-wet, make blooms or granulation, or paint a loose or botanical watercolour, or when wet_paper, advance_wet_paint, dry_paint or set_wet_settings are available. Load with pixerate-paint-editor, which lists every tool.
|
|
4
|
+
metadata:
|
|
5
|
+
kind: workflow
|
|
6
|
+
reference: pixerate-paint-editor
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Painting in watercolour
|
|
10
|
+
|
|
11
|
+
Watercolour is transparent and it moves. Each wash lays water and pigment that keep flowing
|
|
12
|
+
until they dry: edges darken, pigment settles into the paper's valleys, wet colours bleed into
|
|
13
|
+
each other. Light comes from the paper, so you work light to dark and keep the white of the paper
|
|
14
|
+
where you want highlights. A dried wash is fixed; the next one glazes over it. For an agent,
|
|
15
|
+
time only passes when you call `advance_wet_paint` or `dry_paint`.
|
|
16
|
+
|
|
17
|
+
This skill is the method. `pixerate-paint-editor` has the full tool reference and
|
|
18
|
+
`references/wet-media.md` the engine's detail.
|
|
19
|
+
|
|
20
|
+
## Goal and quality bar
|
|
21
|
+
|
|
22
|
+
- The paper suits the piece: cold pressed for most work, rough for texture and granulation, hot
|
|
23
|
+
pressed for fine detail (`get_canvas_info` `paper.preset`).
|
|
24
|
+
- Washes are even where they should be and soft where they should be; colours glow because
|
|
25
|
+
they are layered, not mixed to mud.
|
|
26
|
+
- Highlights are the paper itself, not white paint (unless the user asks for gouache).
|
|
27
|
+
- Every wash is dry before the next glaze over it (`get_wet_paint` `wet: false`), and the
|
|
28
|
+
painting is dry before export.
|
|
29
|
+
|
|
30
|
+
## Inputs to confirm
|
|
31
|
+
|
|
32
|
+
- **Subject and look:** loose and atmospheric (wet-in-wet) or crisp and detailed (wet-on-dry).
|
|
33
|
+
- **Palette:** a few colours; `color_harmony` or `mix_colors` to plan.
|
|
34
|
+
- **Highlights to keep white**, and where they are.
|
|
35
|
+
|
|
36
|
+
## Working method
|
|
37
|
+
|
|
38
|
+
1. **Ground.** `set_paper` with a watercolour preset (`cold-pressed`, `rough-watercolor`,
|
|
39
|
+
`hot-pressed`). Keep each pass on its own layer when you may want to change it (`add_layer`).
|
|
40
|
+
**Check:** `get_canvas_info` shows the paper.
|
|
41
|
+
2. **Plan values light to dark** and where the paper stays white. Mix colours first
|
|
42
|
+
(`mix_colors` predicts the pigment mix; `add_swatch` keeps them).
|
|
43
|
+
3. **First wash, lightest colour.** For soft skies and backgrounds, `wet_paper` the area first
|
|
44
|
+
(wet-in-wet); for crisp edges paint on dry paper. `set_brush` `watercolor-wash`, `set_color`,
|
|
45
|
+
then a few long `paint_stroke`s across the area, overlapping, avoiding the highlights.
|
|
46
|
+
**Check:** `get_wet_paint` shows the layer wet; `pick_color` inside is the colour you meant.
|
|
47
|
+
4. **Let it move, then dry.** `advance_wet_paint` (`seconds` 1-5) to let it spread, bloom and
|
|
48
|
+
granulate; drop a second colour in while it is wet for soft blends. Then `dry_paint`.
|
|
49
|
+
**Check:** `get_wet_paint` `wet: false`.
|
|
50
|
+
5. **Glaze.** Each further wash goes over a dry one, a little darker or another hue (blue over
|
|
51
|
+
yellow makes green). Paint only where it should deepen.
|
|
52
|
+
**Check:** `pick_color` where you glazed is darker; where you did not, unchanged.
|
|
53
|
+
6. **Shapes, then details.** `watercolor-round` for shapes, `watercolor-detail` for lines and
|
|
54
|
+
details on dry paper, last.
|
|
55
|
+
7. **Steer and fix while wet**: `blot` lifts paint (clouds, a highlight you lost), the
|
|
56
|
+
`add-water` tool softens an edge, `hair-dryer` stops a spread, `set_canvas_tilt` makes a wash
|
|
57
|
+
run, `set_wet_settings` tunes `granulation`, `edgeDarkening` and `bloom` for the layer.
|
|
58
|
+
8. **Finish.** `dry_paint` everything; `render_preview` to look; export.
|
|
59
|
+
|
|
60
|
+
## Decision table
|
|
61
|
+
|
|
62
|
+
| Want | Approach |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| Soft sky, misty background | `wet_paper`, then `watercolor-wash`; drop colours in while wet |
|
|
65
|
+
| Crisp shapes, hard edges with a dark rim | Paint on dry paper |
|
|
66
|
+
| Deeper colour without mud | Dry, then glaze a second wash |
|
|
67
|
+
| A white highlight | Leave the paper; or `blot` while wet to lift |
|
|
68
|
+
| Light over dark | `gouache` (body 1) |
|
|
69
|
+
| Grainy, textured washes | `rough-watercolor` paper and `granulation` up in `set_wet_settings` |
|
|
70
|
+
| Fine lines and detail | `hot-pressed` paper, `watercolor-detail`, on dry paper |
|
|
71
|
+
| Cauliflower blooms | Add water into a drying wash; `bloom` up |
|
|
72
|
+
|
|
73
|
+
## Recipes
|
|
74
|
+
|
|
75
|
+
**Flat wash.** `set_brush` `watercolor-wash` → `set_color` → one `paint_stroke` zigzagging
|
|
76
|
+
across the area (rows about half the brush size apart) → `advance_wet_paint` `seconds` 2-5 →
|
|
77
|
+
`dry_paint`.
|
|
78
|
+
|
|
79
|
+
**Glaze.** On the dried wash, the same or a darker colour, painted only where it should deepen
|
|
80
|
+
→ `dry_paint`. Repeat for more depth; three glazes are usually plenty.
|
|
81
|
+
|
|
82
|
+
**Wet-in-wet sky.** `wet_paper` over the sky → blue wash along the top → while wet, a little
|
|
83
|
+
warm colour near the horizon → `advance_wet_paint` → `blot` a few clouds → `dry_paint`.
|
|
84
|
+
|
|
85
|
+
## Pitfalls
|
|
86
|
+
|
|
87
|
+
- **Glazing on wet paint** mixes the two washes instead of layering them; dry first.
|
|
88
|
+
- **Painting light over dark** does not work in transparent watercolour; plan the whites.
|
|
89
|
+
- **Overworking**: many strokes over a wet wash lift and muddy it; lay it and leave it.
|
|
90
|
+
- **Drawing-paper presets** (cartridge, smooth) do not behave like watercolour paper.
|
|
91
|
+
- **Oil and watercolour on one layer**: a layer keeps the first medium's wet settings; use
|
|
92
|
+
separate layers.
|
|
93
|
+
- **Nothing moves by itself** for an agent: without `advance_wet_paint` there is no flow, and
|
|
94
|
+
without `dry_paint` the next stroke paints into wet paint.
|
|
95
|
+
|
|
96
|
+
## Tools used
|
|
97
|
+
|
|
98
|
+
- `get_canvas_info`, `list_layers`, `render_preview`, `pick_color`: read the canvas and check colours
|
|
99
|
+
- `list_papers`, `set_paper`: the watercolour ground
|
|
100
|
+
- `add_layer`, `update_layer`: a layer per pass
|
|
101
|
+
- `set_brush`, `set_color`, `mix_colors`, `color_harmony`, `add_swatch`: brush and palette
|
|
102
|
+
- `paint_stroke`: washes, shapes and details, and the wet tools (water, dryer, blot)
|
|
103
|
+
- `wet_paper`, `advance_wet_paint`, `dry_paint`, `get_wet_paint`: wet-in-wet, flow, drying and checking
|
|
104
|
+
- `set_wet_settings`, `set_canvas_tilt`, `set_flow_map`: tune and steer the water
|
|
105
|
+
- `undo_paint`: take back a step
|
|
106
|
+
- `export_image`: deliver
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "The blue wash on this sheet is dry. Glaze a second wash of the same blue over the left half to deepen it, without lifting or muddying the first one.",
|
|
3
|
+
"fixture": {
|
|
4
|
+
"editor": "paint",
|
|
5
|
+
"width": 64,
|
|
6
|
+
"height": 64,
|
|
7
|
+
"setup": [
|
|
8
|
+
{ "tool": "set_brush", "args": { "id": "watercolor-wash" } },
|
|
9
|
+
{ "tool": "set_color", "args": { "color": "#6fa8dc" } },
|
|
10
|
+
{ "tool": "paint_stroke", "args": { "points": [{ "x": 0, "y": 10 }, { "x": 64, "y": 10 }, { "x": 64, "y": 32 }, { "x": 0, "y": 32 }, { "x": 0, "y": 54 }, { "x": 64, "y": 54 }] } },
|
|
11
|
+
{ "tool": "dry_paint" }
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
"checks": [
|
|
15
|
+
{ "why": "a second watercolour wash", "tool": "list_strokes", "expect": { "total": 2, "strokes": { "$every": { "brushId": { "$in": ["watercolor-round", "watercolor-wash", "gradient-wash", "watercolor-detail"] } } } } },
|
|
16
|
+
{ "why": "the left half is deeper (darker) than the paper-side right", "tool": "pick_color", "args": { "x": 10, "y": 32 }, "expect": { "color": { "$expr": "(([r, g, b]) => 0.3 * r + 0.59 * g + 0.11 * b < 170 && b > r + 15)([1, 3, 5].map((i) => parseInt(v.slice(i, i + 2), 16)))" } } },
|
|
17
|
+
{ "why": "the glaze is dry, so it stays put", "tool": "get_wet_paint", "expect": { "wet": false } }
|
|
18
|
+
],
|
|
19
|
+
"solution": [
|
|
20
|
+
{ "tool": "get_wet_paint" },
|
|
21
|
+
{ "tool": "paint_stroke", "args": { "points": [{ "x": 2, "y": 12 }, { "x": 26, "y": 12 }, { "x": 26, "y": 32 }, { "x": 2, "y": 32 }, { "x": 2, "y": 52 }, { "x": 26, "y": 52 }] } },
|
|
22
|
+
{ "tool": "dry_paint" }
|
|
23
|
+
]
|
|
24
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "I want a detailed botanical study in watercolour with crisp, fine lines. Set up the paper for that and paint the thin stem with a small detail brush, a green line from (32, 60) up to (32, 20).",
|
|
3
|
+
"fixture": { "editor": "paint", "width": 64, "height": 64 },
|
|
4
|
+
"checks": [
|
|
5
|
+
{ "why": "smooth hot-pressed paper for fine detail", "tool": "get_canvas_info", "expect": { "paper": { "preset": "hot-pressed" } } },
|
|
6
|
+
{ "why": "a fine watercolour detail brush", "tool": "list_strokes", "expect": { "strokes": { "$some": { "brushId": "watercolor-detail" } } } },
|
|
7
|
+
{ "why": "a green stem", "tool": "pick_color", "args": { "x": 32, "y": 40 }, "expect": { "color": { "$expr": "(([r, g, b]) => g > r + 10 && g > b)([1, 3, 5].map((i) => parseInt(v.slice(i, i + 2), 16)))" } } }
|
|
8
|
+
],
|
|
9
|
+
"solution": [
|
|
10
|
+
{ "tool": "set_paper", "args": { "preset": "hot-pressed" } },
|
|
11
|
+
{ "tool": "set_brush", "args": { "id": "watercolor-detail" } },
|
|
12
|
+
{ "tool": "set_color", "args": { "color": "#3f7d3a" } },
|
|
13
|
+
{ "tool": "paint_stroke", "args": { "points": [{ "x": 32, "y": 60 }, { "x": 32, "y": 40 }, { "x": 32, "y": 20 }] } },
|
|
14
|
+
{ "tool": "dry_paint" }
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "Paint a flat light-blue sky wash across the top third of the sheet in watercolour, and let it dry before anything else goes on.",
|
|
3
|
+
"fixture": { "editor": "paint", "width": 64, "height": 64, "setup": [{ "tool": "set_paper", "args": { "preset": "cartridge" } }] },
|
|
4
|
+
"checks": [
|
|
5
|
+
{ "why": "on watercolour paper", "tool": "get_canvas_info", "expect": { "paper": { "preset": { "$in": ["cold-pressed", "hot-pressed", "rough-watercolor"] } } } },
|
|
6
|
+
{ "why": "painted with a watercolour brush", "tool": "list_strokes", "expect": { "strokes": { "$length": { "$min": 1 }, "$every": { "brushId": { "$in": ["watercolor-round", "watercolor-wash", "gradient-wash", "watercolor-detail"] } } } } },
|
|
7
|
+
{ "why": "the sky is blue", "tool": "pick_color", "args": { "x": 32, "y": 6 }, "expect": { "color": { "$expr": "(([r, g, b]) => b > r + 15)([1, 3, 5].map((i) => parseInt(v.slice(i, i + 2), 16)))" } } },
|
|
8
|
+
{ "why": "the wash is dry", "tool": "get_wet_paint", "expect": { "wet": false } }
|
|
9
|
+
],
|
|
10
|
+
"solution": [
|
|
11
|
+
{ "tool": "set_paper", "args": { "preset": "cold-pressed" } },
|
|
12
|
+
{ "tool": "set_brush", "args": { "id": "watercolor-wash" } },
|
|
13
|
+
{ "tool": "set_color", "args": { "color": "#6fa8dc" } },
|
|
14
|
+
{ "tool": "paint_stroke", "args": { "points": [{ "x": 0, "y": 6 }, { "x": 64, "y": 6 }, { "x": 64, "y": 14 }, { "x": 0, "y": 14 }] } },
|
|
15
|
+
{ "tool": "advance_wet_paint", "args": { "seconds": 3 } },
|
|
16
|
+
{ "tool": "dry_paint" },
|
|
17
|
+
{ "tool": "get_wet_paint" }
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixerate-video-colour-grade
|
|
3
|
+
description: The colour grading workflow in the Pixerate video editor - correcting each shot first (exposure, contrast, white balance) so a scene matches, then one look over the whole piece on an adjustment clip, LUTs at a sensible strength with skin tones protected, masks for spot changes, and checking with scopes and frames. Use when asked to colour correct, colour grade, match shots, fix exposure or white balance in a video, add a look, a LUT, a film or cinematic look, warm or cool a video, or protect skin tones, or when update_video_clip grade, add_video_adjustment_clip, set_video_lut or get_video_scopes are available. Load with pixerate-video-editor, which lists every tool.
|
|
4
|
+
metadata:
|
|
5
|
+
kind: workflow
|
|
6
|
+
reference: pixerate-video-editor
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Grading a video
|
|
10
|
+
|
|
11
|
+
A grade has two passes. **Correction** makes each shot right and makes shots in a scene match:
|
|
12
|
+
exposure, contrast and white balance on the clip's own `grade`. **The look** is one creative
|
|
13
|
+
decision over everything: an adjustment clip above the timeline with its own grade or a LUT,
|
|
14
|
+
so it is changed in one place. Faces are the reference: people notice skin that is wrong before
|
|
15
|
+
anything else.
|
|
16
|
+
|
|
17
|
+
This skill is the method. `pixerate-video-editor` has the full tool reference.
|
|
18
|
+
|
|
19
|
+
## Goal and quality bar
|
|
20
|
+
|
|
21
|
+
- Shots in a scene match in brightness and colour; cuts between them do not jump.
|
|
22
|
+
- Corrections are moderate: exposure within about ±1 stop, contrast and saturation within
|
|
23
|
+
±0.3, white balance within ±0.3, unless a shot is badly off.
|
|
24
|
+
- One look, in one place: an adjustment clip over the whole timeline (or one per scene), not
|
|
25
|
+
the same settings pasted on every clip.
|
|
26
|
+
- Skin stays natural under strong looks (skin protection 0.5-0.8 on LUTs).
|
|
27
|
+
- The original corrections are not overwritten by the look.
|
|
28
|
+
|
|
29
|
+
## Inputs to confirm
|
|
30
|
+
|
|
31
|
+
- **The look:** natural, warm, cool, desaturated, high contrast, a named LUT; or a reference.
|
|
32
|
+
- **Which shot is the reference** for matching (the best-exposed, or the one the user likes).
|
|
33
|
+
- **Where the LUT file is** (a `.cube` path or URL the host can load).
|
|
34
|
+
|
|
35
|
+
## Working method
|
|
36
|
+
|
|
37
|
+
1. **Read.** `get_video_project` for clips and their `grade`; where the host has a preview,
|
|
38
|
+
`get_video_scopes` at a frame of each shot reads levels and colour in numbers.
|
|
39
|
+
**Check:** you know which shots are off and by how much.
|
|
40
|
+
2. **Correct the reference shot** (`update_video_clip` `set.grade`): exposure first, then
|
|
41
|
+
contrast, then white balance (`temperature`, `tint`). The grade object replaces the clip's
|
|
42
|
+
whole grade, so pass every setting you want to keep.
|
|
43
|
+
3. **Match the others to it.** A shot one stop under gets `exposure: 1`; a cooler shot more
|
|
44
|
+
`temperature`. `copy_video_grade` when shots from one camera setup need the same correction;
|
|
45
|
+
`apply_video_grade_preset` for a common starting point.
|
|
46
|
+
**Check:** the clip `grade` values; scopes or `get_video_frame` at both sides of each cut.
|
|
47
|
+
4. **The look over everything.** `add_video_track` at the top (`at: 0`) and
|
|
48
|
+
`add_video_adjustment_clip` on it from 0 for the whole duration with the look's `grade`
|
|
49
|
+
(`scope: "underneath"`).
|
|
50
|
+
**Check:** one adjustment clip covering the timeline; media clips keep their corrections.
|
|
51
|
+
5. **LUTs.** `set_video_lut` with `strength` 0.3-0.7 for a look (1 only for a technical
|
|
52
|
+
conversion LUT) and skin protection (`preserve_skin_tones: 0.7`, 0.5-0.8) when people are on screen;
|
|
53
|
+
`set_video_skin_protection` to change the protection later.
|
|
54
|
+
**Check:** each clip's `grade.lut` has the strength and protection you meant.
|
|
55
|
+
6. **Spot changes.** `set_video_clip_mask` on a duplicate clip or an adjustment clip for a sky,
|
|
56
|
+
a face or a vignette.
|
|
57
|
+
7. **Review.** `render_video_frame` with `times` across the piece for a contact sheet; fix any
|
|
58
|
+
shot that stands out.
|
|
59
|
+
|
|
60
|
+
## Decision table
|
|
61
|
+
|
|
62
|
+
| Problem | Fix |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| Shot too dark or bright | `grade.exposure` in stops (+1 doubles the light) |
|
|
65
|
+
| Flat, low contrast | `grade.contrast` +0.1-0.3 |
|
|
66
|
+
| Blue or orange cast | `grade.temperature` against it |
|
|
67
|
+
| Green or magenta cast | `grade.tint` against it |
|
|
68
|
+
| Same correction on many shots from one setup | `copy_video_grade` |
|
|
69
|
+
| One look for the whole piece | Adjustment clip on a top track |
|
|
70
|
+
| A LUT look | `set_video_lut`, strength 0.3-0.7 |
|
|
71
|
+
| Faces off under the look | Skin protection 0.5-0.8 (`set_video_lut` or `set_video_skin_protection`), or lower the strength |
|
|
72
|
+
| Change only part of the frame | `set_video_clip_mask` |
|
|
73
|
+
|
|
74
|
+
## Recipes
|
|
75
|
+
|
|
76
|
+
**Match an underexposed shot.** `update_video_clip` `{ clip, set: { grade: { exposure: 1 } } }`
|
|
77
|
+
for one stop under; check with scopes or frames on both sides of the cut.
|
|
78
|
+
|
|
79
|
+
**Warm, slightly desaturated look.** `add_video_track` `{ kind: "video", at: 0 }` →
|
|
80
|
+
`add_video_adjustment_clip` `{ track, start: 0, duration: <project duration>, grade:
|
|
81
|
+
{ temperature: 0.2, saturation: -0.15 } }`.
|
|
82
|
+
|
|
83
|
+
**Tame a LUT.** `set_video_lut` `{ clips, src, strength: 0.6, preserve_skin_tones: 0.7 }`.
|
|
84
|
+
|
|
85
|
+
## Pitfalls
|
|
86
|
+
|
|
87
|
+
- **Grading before correcting.** A look over unmatched shots makes the mismatch stronger.
|
|
88
|
+
- **Partial grade objects.** `set.grade` replaces the whole grade; read it first and include
|
|
89
|
+
the settings you keep.
|
|
90
|
+
- **The look on every clip.** Pasting it per clip means every change is many edits; use an
|
|
91
|
+
adjustment clip.
|
|
92
|
+
- **Full-strength creative LUTs** turn faces orange or green and crush detail.
|
|
93
|
+
- **ffmpeg and skin protection.** The export's `lut3d` cannot protect skin; the export notes
|
|
94
|
+
it, and the preview differs from the file. Lower the strength when that matters.
|
|
95
|
+
- **Judging on one frame.** Check several frames per shot; light changes within shots.
|
|
96
|
+
|
|
97
|
+
## Tools used
|
|
98
|
+
|
|
99
|
+
- `get_video_project`, `get_video_scopes`, `get_video_frame`, `render_video_frame`: read grades, measure and look
|
|
100
|
+
- `update_video_clip`: each shot's correction (`set.grade`)
|
|
101
|
+
- `copy_video_grade`, `apply_video_grade_preset`: match and start from a preset
|
|
102
|
+
- `add_video_track`, `add_video_adjustment_clip`: one look over the timeline
|
|
103
|
+
- `set_video_lut`, `remove_video_lut`, `set_video_skin_protection`: LUT looks and skin
|
|
104
|
+
- `set_video_clip_mask`, `remove_video_clip_mask`: spot changes
|
|
105
|
+
- `undo_video`: take back a step
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "Give the whole piece a warm, slightly desaturated look that I can tweak in one place later, on top of the shot corrections.",
|
|
3
|
+
"fixture": { "editor": "video", "setup": [{ "tool": "add_video_asset", "args": { "id": "a", "kind": "video", "src": "shot-a.mp4", "duration": 8000 } },
|
|
4
|
+
{ "tool": "add_video_asset", "args": { "id": "b", "kind": "video", "src": "shot-b.mp4", "duration": 8000 } },
|
|
5
|
+
{ "tool": "add_video_clip", "args": { "track": "v1", "clip": { "type": "media", "asset": "a", "id": "c1", "start": 0, "duration": 6000 } } },
|
|
6
|
+
{ "tool": "add_video_clip", "args": { "track": "v1", "clip": { "type": "media", "asset": "b", "id": "c2", "start": 6000, "duration": 6000 } } }] },
|
|
7
|
+
"checks": [
|
|
8
|
+
{ "why": "one adjustment clip over the whole timeline", "tool": "get_video_project", "expect": { "tracks": { "$some": { "clips": { "$some": { "type": "adjustment", "start": 0, "duration": { "$min": 12000 } } } } } } },
|
|
9
|
+
{ "why": "warm and a little desaturated", "tool": "get_video_project", "expect": { "tracks": { "$some": { "clips": { "$some": { "type": "adjustment", "grade": { "temperature": { "$min": 0.05, "$max": 0.5 }, "saturation": { "$min": -0.4, "$max": -0.02 } } } } } } } },
|
|
10
|
+
{ "why": "the shots' own grades are left alone", "tool": "get_video_project", "expect": { "tracks": { "$some": { "clips": { "$expr": "v.filter((c) => c.type === 'media').every((c) => !c.grade)" } } } } }
|
|
11
|
+
],
|
|
12
|
+
"solution": [
|
|
13
|
+
{ "tool": "add_video_track", "args": { "kind": "video", "id": "v0", "at": 0 } },
|
|
14
|
+
{ "tool": "add_video_adjustment_clip", "args": { "track": "v0", "start": 0, "duration": 12000, "grade": { "temperature": 0.2, "saturation": -0.15 } } }
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "The teal-and-orange LUT on both shots is too strong and turns the faces orange. Tone the look down to a moderate strength and keep the skin tones natural.",
|
|
3
|
+
"fixture": {
|
|
4
|
+
"editor": "video",
|
|
5
|
+
"setup": [
|
|
6
|
+
{
|
|
7
|
+
"tool": "add_video_asset",
|
|
8
|
+
"args": {
|
|
9
|
+
"id": "a",
|
|
10
|
+
"kind": "video",
|
|
11
|
+
"src": "shot-a.mp4",
|
|
12
|
+
"duration": 8000
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"tool": "add_video_asset",
|
|
17
|
+
"args": {
|
|
18
|
+
"id": "b",
|
|
19
|
+
"kind": "video",
|
|
20
|
+
"src": "shot-b.mp4",
|
|
21
|
+
"duration": 8000
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"tool": "add_video_clip",
|
|
26
|
+
"args": {
|
|
27
|
+
"track": "v1",
|
|
28
|
+
"clip": {
|
|
29
|
+
"type": "media",
|
|
30
|
+
"asset": "a",
|
|
31
|
+
"id": "c1",
|
|
32
|
+
"start": 0,
|
|
33
|
+
"duration": 6000
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"tool": "add_video_clip",
|
|
39
|
+
"args": {
|
|
40
|
+
"track": "v1",
|
|
41
|
+
"clip": {
|
|
42
|
+
"type": "media",
|
|
43
|
+
"asset": "b",
|
|
44
|
+
"id": "c2",
|
|
45
|
+
"start": 6000,
|
|
46
|
+
"duration": 6000
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"tool": "set_video_lut",
|
|
52
|
+
"args": {
|
|
53
|
+
"clips": [
|
|
54
|
+
"c1",
|
|
55
|
+
"c2"
|
|
56
|
+
],
|
|
57
|
+
"src": "data:text/plain,TITLE%20%22Teal%20orange%22%0ALUT_3D_SIZE%202%0A0%200.1%200.1%0A1%200.5%200.2%0A0%201%200.9%0A1%201%200.6%0A0%200.2%201%0A1%200.4%200.9%0A0%201%201%0A1%201%201%0A",
|
|
58
|
+
"strength": 1
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"checks": [
|
|
64
|
+
{
|
|
65
|
+
"why": "the LUT is still on both shots, at a moderate strength",
|
|
66
|
+
"tool": "get_video_project",
|
|
67
|
+
"expect": {
|
|
68
|
+
"tracks": {
|
|
69
|
+
"$some": {
|
|
70
|
+
"clips": {
|
|
71
|
+
"$length": 2,
|
|
72
|
+
"$every": {
|
|
73
|
+
"grade": {
|
|
74
|
+
"lut": {
|
|
75
|
+
"src": {
|
|
76
|
+
"$match": "^data:"
|
|
77
|
+
},
|
|
78
|
+
"strength": {
|
|
79
|
+
"$min": 0.3,
|
|
80
|
+
"$max": 0.85
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"why": "skin tones protected",
|
|
92
|
+
"tool": "get_video_project",
|
|
93
|
+
"expect": {
|
|
94
|
+
"tracks": {
|
|
95
|
+
"$some": {
|
|
96
|
+
"clips": {
|
|
97
|
+
"$every": {
|
|
98
|
+
"grade": {
|
|
99
|
+
"lut": {
|
|
100
|
+
"preserveSkinTones": {
|
|
101
|
+
"$min": 0.4
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"solution": [
|
|
113
|
+
{
|
|
114
|
+
"tool": "get_video_project"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"tool": "set_video_lut",
|
|
118
|
+
"args": {
|
|
119
|
+
"clips": [
|
|
120
|
+
"c1",
|
|
121
|
+
"c2"
|
|
122
|
+
],
|
|
123
|
+
"src": {
|
|
124
|
+
"$read": "get_video_project",
|
|
125
|
+
"path": "tracks.0.clips.0.grade.lut.src"
|
|
126
|
+
},
|
|
127
|
+
"strength": 0.6,
|
|
128
|
+
"preserve_skin_tones": 0.7
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "Shot two (c2) was filmed one stop underexposed compared with shot one. Match it to shot one without touching shot one.",
|
|
3
|
+
"fixture": { "editor": "video", "setup": [{ "tool": "add_video_asset", "args": { "id": "a", "kind": "video", "src": "shot-a.mp4", "duration": 8000 } },
|
|
4
|
+
{ "tool": "add_video_asset", "args": { "id": "b", "kind": "video", "src": "shot-b.mp4", "duration": 8000 } },
|
|
5
|
+
{ "tool": "add_video_clip", "args": { "track": "v1", "clip": { "type": "media", "asset": "a", "id": "c1", "start": 0, "duration": 6000 } } },
|
|
6
|
+
{ "tool": "add_video_clip", "args": { "track": "v1", "clip": { "type": "media", "asset": "b", "id": "c2", "start": 6000, "duration": 6000 } } }] },
|
|
7
|
+
"checks": [
|
|
8
|
+
{ "why": "c2 brought up by about one stop", "tool": "get_video_project", "expect": { "tracks": { "$some": { "clips": { "$some": { "id": "c2", "grade": { "exposure": { "$min": 0.8, "$max": 1.2 } } } } } } } },
|
|
9
|
+
{ "why": "shot one is untouched", "tool": "get_video_project", "expect": { "tracks": { "$some": { "clips": { "$some": { "id": "c1", "$expr": "!v.grade || Object.values(v.grade).every((x) => x === 0)" } } } } } }
|
|
10
|
+
],
|
|
11
|
+
"solution": [
|
|
12
|
+
{ "tool": "update_video_clip", "args": { "clip": "c2", "set": { "grade": { "exposure": 1 } } } }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -33,6 +33,9 @@ the pitfalls, and uses the tools below.
|
|
|
33
33
|
|
|
34
34
|
- `pixerate-talking-head-edit`: dialogue cleanup by transcript: fillers, pauses, stutters.
|
|
35
35
|
- `pixerate-bgm-alignment`: cutting to the beat, ducking music under speech, loudness.
|
|
36
|
+
- `pixerate-video-social-cut`: vertical reframes, the hook first, platform lengths, titles in the safe area.
|
|
37
|
+
- `pixerate-video-colour-grade`: correct and match shots, one look on an adjustment clip, LUTs and skin.
|
|
38
|
+
- `pixerate-video-montage`: selects on the beat, pacing, transitions, music and the ending.
|
|
36
39
|
|
|
37
40
|
## Working method
|
|
38
41
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixerate-video-montage
|
|
3
|
+
description: The montage workflow in the Pixerate video editor - choosing selects and their best moments, assembling them on beats or a rhythm, varying shot length for pacing, cutting on action, short transitions where they help, music under the whole sequence, and a clean start and end. Use when asked to make a montage, a highlight reel, a sizzle reel, a recap, a music video edit, a slideshow of clips or photos, or to cut a set of clips to music or a rhythm, or when edit_video, add_video_marker, set_video_transition or find_video_gaps are available. Load with pixerate-video-editor, which lists every tool.
|
|
4
|
+
metadata:
|
|
5
|
+
kind: workflow
|
|
6
|
+
reference: pixerate-video-editor
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Cutting a montage
|
|
10
|
+
|
|
11
|
+
A montage tells its story through rhythm: the best moment of each shot, in an order that
|
|
12
|
+
builds, cut to a beat. The work is choosing (selects and their best seconds), then placing
|
|
13
|
+
(on the beat, with shot lengths that breathe and quicken), then finishing (transitions only
|
|
14
|
+
where they help, music under everything, a clear ending).
|
|
15
|
+
|
|
16
|
+
This skill is the method. `pixerate-video-editor` has the full tool reference; for beats in a
|
|
17
|
+
music track and cutting to them, see `pixerate-bgm-alignment`.
|
|
18
|
+
|
|
19
|
+
## Goal and quality bar
|
|
20
|
+
|
|
21
|
+
- Each shot is its best moment: taken from the middle of the action, not its first frames
|
|
22
|
+
(`in` past the camera's settle).
|
|
23
|
+
- Cuts land on beats or on action, on frame boundaries, with no gaps (`find_video_gaps` empty).
|
|
24
|
+
- Pacing varies: longer shots to establish, shorter to build, a held shot to land.
|
|
25
|
+
- Straight cuts by default; short crossfades (300-600 ms) or dips only for a reason (time
|
|
26
|
+
passing, a change of section), each with enough media on both sides (no handle errors).
|
|
27
|
+
- Music runs under the whole sequence and ends with it (a fade out or a musical ending), and
|
|
28
|
+
the picture ends cleanly (a fade to black or a held final frame).
|
|
29
|
+
|
|
30
|
+
## Inputs to confirm
|
|
31
|
+
|
|
32
|
+
- **Selects and order:** which clips, in what order (story, chronology, energy).
|
|
33
|
+
- **Rhythm:** music with beats, markers, or a shot length (e.g. 1 s per shot).
|
|
34
|
+
- **Length** of the finished piece.
|
|
35
|
+
|
|
36
|
+
## Working method
|
|
37
|
+
|
|
38
|
+
1. **Read.** `get_video_project`: assets (with durations), markers (beats), music.
|
|
39
|
+
With music, `find_video_beats` (`pixerate-bgm-alignment`) marks the beats.
|
|
40
|
+
**Check:** you have a beat grid or a shot length, and each select's usable range.
|
|
41
|
+
2. **Pick the moments.** For each select, the `in` point of its best stretch (skip the first
|
|
42
|
+
second or two, where the camera settles).
|
|
43
|
+
3. **Assemble in one batch.** `edit_video` with one add-clip op per shot (`asset`, `id`, `in`,
|
|
44
|
+
`start` on a beat, `duration` to the next beat), `dry_run: true` first.
|
|
45
|
+
**Check:** the clips are in order, each `start` on a beat; `find_video_gaps` is empty.
|
|
46
|
+
4. **Refine the rhythm.** `roll_video_edit` to move a cut to a beat or onto action without
|
|
47
|
+
shifting anything else; `slip_video_clip` to change what a shot shows without moving it.
|
|
48
|
+
Vary lengths: build up with shorter shots before the peak.
|
|
49
|
+
5. **Transitions, sparingly.** `set_video_transition` `crossfade` 300-600 ms (or `dip` for a
|
|
50
|
+
section change); every type but dip needs half its length in media past the cut on both sides.
|
|
51
|
+
**Check:** `check_video_project` has no errors.
|
|
52
|
+
6. **Music and ending.** The music clip on an audio track from 0 for the whole duration, with a
|
|
53
|
+
`fadeOut` of 1-3 s (or cut on its last beat); the last picture clip `fadeOut` 300-1000 ms to
|
|
54
|
+
black.
|
|
55
|
+
**Check:** `get_video_project` shows both, ending together.
|
|
56
|
+
7. **Review.** `render_video_frame` with `times` at each cut for a contact sheet; watch the
|
|
57
|
+
rhythm in the preview where available.
|
|
58
|
+
|
|
59
|
+
## Decision table
|
|
60
|
+
|
|
61
|
+
| Want | Approach |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| Energy, a build | Shorter shots toward the peak, cuts on every beat |
|
|
64
|
+
| Calm, reflective | Longer shots, cuts every 2-4 beats, crossfades |
|
|
65
|
+
| Time passing | Crossfade or dip between shots |
|
|
66
|
+
| A section change | Dip to black or a held shot, then a new rhythm |
|
|
67
|
+
| Continuity of motion | Cut on action (`roll_video_edit` onto the movement) |
|
|
68
|
+
| Photos in a slideshow | Image assets, a slow push-in (`set_video_keyframes` scale 1 to 1.08) |
|
|
69
|
+
|
|
70
|
+
## Recipes
|
|
71
|
+
|
|
72
|
+
**On the beat.** Beats every `b` ms from 0: `edit_video` with `{ op: "add_clip", track: "v1", clip:
|
|
73
|
+
{ type: "media", asset, id, in, start: k * b, duration: b } }` for each shot `k`; then `find_video_gaps`.
|
|
74
|
+
|
|
75
|
+
**Crossfades.** `edit_video` with `{ op: "set_transition", clip, transition: { type: "crossfade",
|
|
76
|
+
duration: 400 } }` for every clip after the first; then `check_video_project`.
|
|
77
|
+
|
|
78
|
+
**Music and fade-out.** `add_video_clip` on the audio track `{ type: "media", asset: music,
|
|
79
|
+
start: 0, duration: <sequence>, fadeOut: 2000 }`; `update_video_clip` on the last shot
|
|
80
|
+
`{ set: { fadeOut: 500 } }`.
|
|
81
|
+
|
|
82
|
+
## Pitfalls
|
|
83
|
+
|
|
84
|
+
- **First frames of a clip** are often the camera settling; take `in` later.
|
|
85
|
+
- **Transitions everywhere** soften the rhythm and look dated; cut straight by default.
|
|
86
|
+
- **Missing handles.** A transition needs media past the cut on both sides; trimmed-to-the-edge
|
|
87
|
+
clips fail `check_video_project`.
|
|
88
|
+
- **Music that stops dead** at the end of the picture; fade it or end on a musical phrase.
|
|
89
|
+
- **Uniform shot lengths** for a long montage feel mechanical; vary them.
|
|
90
|
+
|
|
91
|
+
## Tools used
|
|
92
|
+
|
|
93
|
+
- `get_video_project`, `find_video_gaps`, `check_video_project`, `render_video_frame`: read and check
|
|
94
|
+
- `add_video_marker`: beats and sections
|
|
95
|
+
- `edit_video`, `add_video_clip`: assemble in one batch
|
|
96
|
+
- `roll_video_edit`, `slip_video_clip`, `trim_video_clip`, `close_video_gaps`: refine the rhythm
|
|
97
|
+
- `set_video_transition`: crossfades and dips
|
|
98
|
+
- `update_video_clip`, `set_video_keyframes`: fades, volume and push-ins
|
|
99
|
+
- `undo_video`: take back a step
|