@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,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pixerate-video-social-cut
|
|
3
|
+
description: The social video workflow in the Pixerate video editor - reframing for vertical (9:16) or square, opening on the hook in the first seconds, cutting to platform length, titles and captions inside the safe area, pacing for the feed, loudness for mobile and an export for Reels, TikTok, Shorts or a feed post. Use when asked to make a social cut, a vertical, Reels, TikTok, Shorts or story version, a teaser or trailer for social, a short clip from a longer video, or to reframe, caption or title a video for social, or when set_video_settings, update_video_clip and add_video_marker 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 for social
|
|
10
|
+
|
|
11
|
+
A social cut is watched on a phone, often without sound, by someone who decides in the first
|
|
12
|
+
second or two whether to stay. So the frame is vertical or square and filled, the strongest
|
|
13
|
+
moment comes first, every shot earns its place, and words are on screen. Build it as its own
|
|
14
|
+
project or sequence from the long edit, never by damaging the original.
|
|
15
|
+
|
|
16
|
+
This skill is the method. `pixerate-video-editor` has the full tool reference; for music and
|
|
17
|
+
loudness see `pixerate-bgm-alignment`.
|
|
18
|
+
|
|
19
|
+
## Goal and quality bar
|
|
20
|
+
|
|
21
|
+
- The frame suits the platform: 1080 × 1920 (9:16) for Reels, TikTok, Shorts and stories;
|
|
22
|
+
1080 × 1080 or 1080 × 1350 for a feed post. The picture fills it (no black bars).
|
|
23
|
+
- The hook plays in the first 1-3 seconds: the most striking image or line, not a logo or a
|
|
24
|
+
slow build.
|
|
25
|
+
- The length fits the platform and the content: 7-15 s for a loop or teaser, up to 60 s for
|
|
26
|
+
most short-form, cut tight (no dead air, `find_video_gaps` empty).
|
|
27
|
+
- Text is readable without sound: titles and captions large, high-contrast, inside the safe
|
|
28
|
+
area (away from the top 250 px and bottom 350 px of a 1920-high frame, where the app's
|
|
29
|
+
interface sits).
|
|
30
|
+
- `check_video_project` has no errors; the mix is at the delivery loudness (-14 LUFS).
|
|
31
|
+
|
|
32
|
+
## Inputs to confirm
|
|
33
|
+
|
|
34
|
+
- **Platform(s)** and so the frame and length.
|
|
35
|
+
- **The hook:** a moment, a line or a marker; ask when nothing in the footage stands out.
|
|
36
|
+
- **Words on screen:** captions of the speech, a title, a call to action.
|
|
37
|
+
|
|
38
|
+
## Working method
|
|
39
|
+
|
|
40
|
+
1. **Read.** `get_video_project`: frame size, clips, markers (a "Hook" marker or the user's
|
|
41
|
+
notes), duration. With speech, `get_video_transcript` to find the best lines.
|
|
42
|
+
**Check:** you know where the hook is in the source and how long the cut should be.
|
|
43
|
+
2. **Set the frame.** `set_video_settings` `width` / `height`; then each clip `fit: "cover"`
|
|
44
|
+
(`update_video_clip`), and `transform` `x` to keep the subject in frame when it is off-centre.
|
|
45
|
+
**Check:** `get_video_project` frame size; `get_video_frame` at a few times shows the subject.
|
|
46
|
+
3. **Open on the hook.** Trim and move so the first clip's `in` is at the hook (`edit_video`
|
|
47
|
+
with its trim and move ops, or `extract_video_range` for what goes). Then the context, then
|
|
48
|
+
the payoff.
|
|
49
|
+
**Check:** the clip at 0 starts at the hook's source time.
|
|
50
|
+
4. **Cut to length.** Remove everything that does not move the story: `remove_video_ranges` for
|
|
51
|
+
pauses and fillers (`pixerate-talking-head-edit`), `extract_video_range` for whole passages.
|
|
52
|
+
Keep shots short (1-3 s for montage, as long as the line for speech).
|
|
53
|
+
**Check:** `get_video_project` `duration` is in range; `find_video_gaps` is empty.
|
|
54
|
+
5. **Words.** A video track above the footage (`add_video_track` with `at: 0`), then text clips
|
|
55
|
+
(`add_video_clip` `type: "text"`) with `transform.y` in the upper or lower safe area,
|
|
56
|
+
`animateIn` / `animateOut` for motion. Captions follow the transcript's sentences.
|
|
57
|
+
**Check:** text clips are on the top track and inside the safe area.
|
|
58
|
+
6. **Sound.** Music under, dialogue on top (`pixerate-bgm-alignment`); the first second should
|
|
59
|
+
work without sound and with it.
|
|
60
|
+
7. **Check and export.** `check_video_project`; `export_video_ffmpeg` with the loudness target.
|
|
61
|
+
|
|
62
|
+
## Decision table
|
|
63
|
+
|
|
64
|
+
| Platform | Frame | Length |
|
|
65
|
+
| --- | --- | --- |
|
|
66
|
+
| Reels, TikTok, Shorts, stories | 1080 × 1920 | 7-60 s; under 15 s loops |
|
|
67
|
+
| Feed post | 1080 × 1350 or 1080 × 1080 | 15-60 s |
|
|
68
|
+
| Landscape (YouTube, web) | 1920 × 1080 | The content's length |
|
|
69
|
+
|
|
70
|
+
| Source | Reframe |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| Subject centred | `fit: "cover"` |
|
|
73
|
+
| Subject off-centre | `fit: "cover"` plus `transform.x` toward the subject |
|
|
74
|
+
| Subject moves across the frame | Keyframe `transform.x` (`set_video_keyframes`), or split and reposition per shot |
|
|
75
|
+
| Wide shot that loses everything when cropped | A blurred, scaled copy behind a `contain` copy, or choose another shot |
|
|
76
|
+
|
|
77
|
+
## Recipes
|
|
78
|
+
|
|
79
|
+
**Vertical from landscape.** `set_video_settings` `{ width: 1080, height: 1920 }` → for each
|
|
80
|
+
picture clip `update_video_clip` `{ set: { fit: "cover" } }` → `get_video_frame` to check.
|
|
81
|
+
|
|
82
|
+
**Hook first.** Source hook at `h` ms: `edit_video` `[{ op: "trim_clip", clip, edge: "start",
|
|
83
|
+
to: h }, { op: "trim_clip", clip, edge: "end", to: h + length }, { op: "move_clip", clip,
|
|
84
|
+
start: 0 }]`.
|
|
85
|
+
|
|
86
|
+
**Opening title.** `add_video_track` `{ kind: "video", at: 0 }` → `add_video_clip` on it with
|
|
87
|
+
`{ type: "text", text, start: 0, duration: 3000, transform: { y: -600 } }`.
|
|
88
|
+
|
|
89
|
+
## Pitfalls
|
|
90
|
+
|
|
91
|
+
- **Letterboxing.** A landscape clip in a vertical frame with `contain` shows black bars.
|
|
92
|
+
- **Slow openings.** A logo, a fade-in or a wide establishing shot loses the viewer.
|
|
93
|
+
- **Text in the interface zones** is covered by captions, buttons and the username.
|
|
94
|
+
- **Relying on sound.** Most feeds autoplay muted; put the message on screen too.
|
|
95
|
+
- **Editing the master.** Make the social cut separately so the long version stays intact.
|
|
96
|
+
|
|
97
|
+
## Tools used
|
|
98
|
+
|
|
99
|
+
- `get_video_project`, `get_video_transcript`, `get_video_frame`, `find_video_gaps`, `check_video_project`: read and check
|
|
100
|
+
- `set_video_settings`: the frame size
|
|
101
|
+
- `update_video_clip`, `set_video_keyframes`: fit, reframe and move the picture
|
|
102
|
+
- `edit_video`, `trim_video_clip`, `move_video_clip`, `extract_video_range`, `remove_video_ranges`: cut to the hook and to length
|
|
103
|
+
- `add_video_track`, `add_video_clip`: titles and captions on a track above
|
|
104
|
+
- `add_video_marker`: mark the hook and beats
|
|
105
|
+
- `export_video_ffmpeg`: deliver
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "Cut this interview down to a 15-second clip for social that opens on the moment marked 'Hook' and runs on from there. No gaps.",
|
|
3
|
+
"fixture": { "editor": "video", "setup": [{ "tool": "add_video_asset", "args": { "id": "interview", "kind": "video", "src": "interview.mp4", "duration": 40000, "width": 1920, "height": 1080 } },
|
|
4
|
+
{ "tool": "add_video_clip", "args": { "track": "v1", "clip": { "type": "media", "asset": "interview", "id": "c1", "start": 0, "duration": 40000 } } }, { "tool": "add_video_marker", "args": { "time": 22000, "label": "Hook" } }] },
|
|
5
|
+
"checks": [
|
|
6
|
+
{ "why": "about 15 seconds long", "tool": "get_video_project", "expect": { "duration": { "$min": 12000, "$max": 15500 } } },
|
|
7
|
+
{ "why": "the first frame is the hook", "tool": "get_video_project", "expect": { "tracks": { "$some": { "id": "v1", "clips": { "$some": { "start": 0, "in": { "$min": 21500, "$max": 22500 } } } } } } },
|
|
8
|
+
{ "why": "no gaps", "tool": "find_video_gaps", "expect": { "gaps": { "$length": 0 } } }
|
|
9
|
+
],
|
|
10
|
+
"solution": [
|
|
11
|
+
{ "tool": "get_video_project" },
|
|
12
|
+
{ "tool": "edit_video", "args": { "ops": [
|
|
13
|
+
{ "op": "trim_clip", "clip": "c1", "edge": "start", "to": 22000 },
|
|
14
|
+
{ "op": "trim_clip", "clip": "c1", "edge": "end", "to": 37000 },
|
|
15
|
+
{ "op": "move_clip", "clip": "c1", "start": 0 }
|
|
16
|
+
] } },
|
|
17
|
+
{ "tool": "find_video_gaps" }
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "Add a title saying 'New drop Friday' over the first three seconds, in the upper part of the frame, on top of the video.",
|
|
3
|
+
"fixture": { "editor": "video", "setup": [{ "tool": "add_video_asset", "args": { "id": "interview", "kind": "video", "src": "interview.mp4", "duration": 40000, "width": 1920, "height": 1080 } },
|
|
4
|
+
{ "tool": "add_video_clip", "args": { "track": "v1", "clip": { "type": "media", "asset": "interview", "id": "c1", "start": 0, "duration": 40000 } } }] },
|
|
5
|
+
"checks": [
|
|
6
|
+
{ "why": "a text clip with the words, from 0 for about 3 s", "tool": "get_video_project", "expect": { "tracks": { "$some": { "clips": { "$some": { "type": "text", "text": { "$match": ["new drop friday", "i"] }, "start": 0, "duration": { "$min": 2500, "$max": 4000 } } } } } } },
|
|
7
|
+
{ "why": "in the upper part of the frame", "tool": "get_video_project", "expect": { "tracks": { "$some": { "clips": { "$some": { "type": "text", "transform": { "y": { "$max": -100 } } } } } } } },
|
|
8
|
+
{ "why": "on a video track above the footage (tracks are listed top first)", "tool": "get_video_project", "expect": { "tracks": { "$expr": "(() => { const t = v.findIndex((tr) => tr.clips.some((c) => c.type === 'text')); const m = v.findIndex((tr) => tr.clips.some((c) => c.id === 'c1')); return t >= 0 && t < m; })()" } } }
|
|
9
|
+
],
|
|
10
|
+
"solution": [
|
|
11
|
+
{ "tool": "add_video_track", "args": { "kind": "video", "id": "v2", "at": 0 } },
|
|
12
|
+
{ "tool": "add_video_clip", "args": { "track": "v2", "clip": { "type": "text", "text": "New drop Friday", "start": 0, "duration": 3000, "transform": { "y": -600 } } } }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prompt": "Make this a vertical video for Reels and TikTok: 1080 by 1920, with the picture filling the whole frame (no black bars).",
|
|
3
|
+
"fixture": { "editor": "video", "setup": [{ "tool": "add_video_asset", "args": { "id": "interview", "kind": "video", "src": "interview.mp4", "duration": 40000, "width": 1920, "height": 1080 } },
|
|
4
|
+
{ "tool": "add_video_clip", "args": { "track": "v1", "clip": { "type": "media", "asset": "interview", "id": "c1", "start": 0, "duration": 40000 } } }] },
|
|
5
|
+
"checks": [
|
|
6
|
+
{ "why": "a 9:16 frame at 1080 × 1920", "tool": "get_video_project", "expect": { "width": 1080, "height": 1920 } },
|
|
7
|
+
{ "why": "the picture covers the frame", "tool": "get_video_project", "expect": { "tracks": { "$some": { "clips": { "$some": { "id": "c1", "$expr": "v.fit === 'cover' || (v.transform && v.transform.scale >= 3.15)" } } } } } },
|
|
8
|
+
{ "why": "no errors", "tool": "check_video_project", "expect": { "errors": 0 } }
|
|
9
|
+
],
|
|
10
|
+
"solution": [
|
|
11
|
+
{ "tool": "set_video_settings", "args": { "width": 1080, "height": 1920 } },
|
|
12
|
+
{ "tool": "update_video_clip", "args": { "clip": "c1", "set": { "fit": "cover" } } },
|
|
13
|
+
{ "tool": "check_video_project" }
|
|
14
|
+
]
|
|
15
|
+
}
|