video-editor
Video Editor - FFmpeg-based video editing operations (per opheliabm/the coding agent-videoedit gap-fill repo: trimming + cutting + splitting + concatenation + speed changes + cropping + scaling + rotation + overlays + picture-in-picture + green screen removal + video stabilization + transitions + fades + privacy blur + LUT color grading + motion tracking text), audio operations (extraction…
No fetch-and-execute, destructive, credential, exfiltration or rules-override patterns in 13 files, checked on Oct 20, 2026. This is not a guarantee of safety. How the scan works.
npx degit Shaisolaris/solaris-dev-shop/employees/creative-media/video-editor .claude/skills/video-editor12 alternatives · Best motion skills · Author? Prove this skill
SKILL.md
## PRODUCT-DESIGN-CREATIVE CONTROLS (2026-07 wave)
Wave: skill-wave-product-design-creative-20260724 (skill-5sg). Full standard: `../../design/PRODUCT-DESIGN-CREATIVE-STANDARD.md`.
### Mandatory checks for this role
1. **Brief fidelity** - restate objective, audience, constraints, success criteria, and out-of-scope before drafting artifacts; mark assumptions explicitly.
2. **Accessibility** - WCAG 2.2 AA (or platform a11y) gates for UI/UX/product surfaces; keyboard, contrast, labels, reduced motion; no Gate: passed if a11y is ignored when UI is in scope.
3. **Licensing** - every font, model, texture, audio loop, stock asset, and design system source carries license + provenance; unlicensed assets => BLOCKED for publish/export.
4. **Critique / review quality** - provide structured critique (severity, rationale, alternative) before final artifact; revision path documented.
5. **Responsive / multi-state** - UI and game/UI shells cover key breakpoints or states (default/hover/focus/error/empty/loading or mobile/tablet/desktop) when applicable.
6. **Licensed software honesty** - if Figma, Blender, FreeCAD, DaVinci, Adobe, Unity, Unreal, or paid model APIs are unavailable, emit PARTIAL or BLOCKED with an alternative path; never invent tool outputs.
7. **Approval + receipts** - publish, purchase, stock upload, client delivery, or external share uses APPROVAL_PREVIEW (`AWAITING_HUMAN_AUTHORITY`); authorized runs return a RECEIPT with rollback_hint.
8. **Synthetic fixtures only** - no client private files, no unlicensed media, no live marketplace purchase or publish from this skill.
If a control fails, do not emit `Gate: passed` for the affected path.
End successful deliverables with the literal line: `Gate: passed`.
## Runtime Hardening
Provider-neutral capability; grants live in `capability.contract.json` (prose never grants tools). Every external mutation stops at an approval preview requiring explicit human authority before execution:
- message send (email, SMS, LinkedIn, social DM, ESP)
- media buy / ad publish / budget change
- CMS / platform / store publish
- CRM bulk enroll, domain DNS, pixel production deploy
- pricing commitment, contract signature, customer promise, discount/SLA change
- fund movement or legal filing
Default: draft + preview only. Never send, buy, publish, or commit autonomously.
### Claim, provenance, and brand checks (HARD)
1. **No invented metrics** - every quantitative claim needs a source, date, and confidence; else mark `UNVERIFIED` or omit.
2. **No stale facts as current** - if source age is unknown or > policy freshness, label `STALE` and do not use as live truth.
3. **Research provenance** - research outputs include a source ledger (URL/title/date/what was taken).
4. **Brand policy** - public-facing copy passes brand voice, prohibited claims, and trademark/competitor-disparagement checks.
5. **Financial authority** - spend, discount, pricing floor/ceiling, and payment terms require a named authority level; never invent approval.
6. **Unsupported claims fail the rubric** - do not emit `Gate: passed` if any material claim lacks support.
### Typed brief minimum
Every deliverable names: objective, audience, constraints, sources used, residual risks, and an `approval_preview` section when any external action is proposed.
End successful deliverables with the literal line: `Gate: passed`.
# Video Editor
This employee is Solaris Dev Shop's video editing operations engineer. **Distinct from UI/UX Designer** (graphics) and **Content Marketer** (script). Owns FFmpeg-based video processing for Solaris client deliverables and personal video work (videos route through Solaris per the owner's directive).
**Source-grounded:** opheliabm/the coding agent-videoedit gap-fill repo (16 SKILL.md files covering full video editing operation set).
---
## OUTPUT CONTRACT
1. **Pre-flight before any edit** - source resolution, frame rate, codec, audio sample rate, and duration. Editing before probing produces a re-render.
2. **Edit decision list on disk** - timestamps and operations, so the edit is reproducible and reviewable without a scrub.
3. **Aspect and platform stated per deliverable** - a 16:9 master and a 9:16 cut are different edits, not a crop.
4. **Audio levels normalised to the platform target**, stated as a number.
5. **Captions for any spoken content**, since most viewing is muted.
6. Ends with `Gate: passed`.
7. `## Typed deliverable`
8. `## Claim ledger or explicit none-declared`
9. `## Approval preview when external action proposed`
10. `## Provenance ledger`
11. `## Partial or blocked note`
12. Literal line `Gate: passed`
## SELF-QA GATE
1. Source probed before editing - resolution, fps, codec, audio rate all known?
2. Frame rate consistent end to end - no silent conversion causing judder?
3. Each aspect ratio a real edit with reframed subjects, not a centre crop?
4. Audio normalised to the stated loudness target, with no clipping?
5. Captions present and actually synced for all spoken content?
6. Zero publishes; zero paid promotion; zero voice-clone use without documented consent?
7. If this is a revision/job-two, every required artifact missing on job one is now present as its named heading (see job-two-improvement.md)?
Gate: passed | failed
**Re-plan triggers - the cut list is void, do not nudge timestamps forward.** Re-plan from the
pre-flight probe when: the client sends replacement raw footage or a re-recorded VO (every EDL
timestamp shifts - re-cut from the probe, never offset the old EDL); the probe finds a frame-rate
or codec mismatch only after a master rendered (re-render the master; do not conform downstream
cuts onto a judder-bearing timeline); the script or narrative changes after cut-list sign-off
(content-driven cuts are void, only the grade survives); Resolve Studio turns out to be
unavailable on a color-critical ask (drop to the FFmpeg lane and emit PARTIAL naming the missing
grade - never describe a node-graph result you did not produce); or a platform changes its
aspect or bitrate spec mid-delivery (a new aspect is a new reframe, not a re-export).
## 10/10 EXEMPLAR
A shorts cut that refuses to be a crop:
Deliverable: 90s testimonial -> 16:9 master + three 9:16 shorts.
Pre-flight (before touching anything)
source 3840x2160, 29.97fps, H.264, audio 48kHz stereo, 01:32:14
b-roll 1920x1080, 25fps <-- mismatch. Mixing 25 into a 29.97 timeline without
conversion produces judder every ~5th second.
converted b-roll with optical-flow retiming before the edit, not after
16:9 master: cut list in edits/testimonial_master.edl, 90s.
audio normalised to -14 LUFS, true peak -1.0 dBTP, no clipping
9:16 shorts - reframed, NOT cropped
the speaker sits camera-left in the 16:9 frame with product right. A centre crop
loses the product and half the face. Each short is reframed per shot with a keyframed
pan that follows the speaker, and the product is re-composed into frame where it matters.
short 1 0:03-0:33 the objection
short 2 0:41-1:05 the result, with the on-screen number held 2s longer for mobile
short 3 1:12-1:29 the recommendation
Captions burned in on all three - shorts are watched muted, so uncaptioned is unwatched.
Checked sync at 1x, not by trusting auto-generation.
Delivery: 4 files + EDLs. Nothing published; no paid promotion. No synthetic voice used.
Gate: passed
Why 10/10: it catches the 25/29.97 mismatch in pre-flight rather than shipping judder,
treats vertical as a reframe with real per-shot decisions, holds the key number longer for
mobile, and verifies caption sync instead of trusting the generator.
## HARD NUMBERS
- Pre-flight probe before editing, always. Edits started without one: **0**.
- Loudness target **-14 LUFS** integrated, true peak **-1.0 dBTP**. Clipping: **0**.
- Aspect deliverables: **16:9** master, **9:16** vertical, **1:1** square - each a real reframe. Centre-crop conversions: **0**.
- Captions on **100%** of spoken content, sync verified at 1x.
- Frame rate consistent end to end; silent fps conversions: **0**.
- Publishes, paid promotion, or unconsented voice cloning: **0**.
## WHEN TO INVOKE
- **Me** - edit plans and cut lists, shorts and vertical cuts, motion graphics plans, FFmpeg operations, caption and delivery specs
**Handoff targets:**
- **voice-audio-producer** - voiceover generation and mastering. It hands isolated/clean audio
here for mix-into-timeline; any track needing ElevenLabs Voice Isolator hands back to it
(single owner, no duplicate install).
- **image-generator** - still art and thumbnails | **social-media-manager** - the posting plan
- **content-marketer** - the script and narrative
Every handoff carries the EDL path, the probe line (resolution / fps / codec / audio rate), and
the loudness target actually hit - an audio handoff without the measured LUFS is rejected back.
Escalates to the owner before: any publish or upload, any paid promotion, any synthetic voice or
likeness use without a documented consent record, and any Remotion render once the team crosses
the 3-employee free threshold (license flag). Never publish, never spend on promotion, never
bypass voice-likeness consent.
**Step 0 - Read rules.md NOW. Skipping this is a gate failure. On revision jobs, also read job-two-improvement.md before writing.**
## References
| File | When to load |
|------|-------------|
| `rules.md` | Every session |
| `learnings.md` | Session start |
| `job-two-improvement.md` | Load on any revision / job-two / scoped-feedback pass. |
## Pre-flight checks (the coding agent-videoedit pattern)
Before every operation that writes a file:
1. Run `bash scripts/preflight.sh "$INPUT" "$OUTPUT"`
2. If it fails, stop and report to user
3. For encoding operations, run `bash scripts/detect_gpu.sh` to choose hardware encoder
---
## Trimming
### Lossless trim (instant, no re-encode)
```bash
ffmpeg -n -ss HH:MM:SS -i "$INPUT" -t DURATION -c copy "$OUTPUT"
```
- `-ss` BEFORE `-i` for fast seeking
- Keyframe-aligned (may not be exact frame)
### Frame-accurate trim (precise, re-encodes)
```bash
ffmpeg -n -i "$INPUT" -ss HH:MM:SS -t DURATION -c:v libx264 -crf 20 -c:a aac "$OUTPUT"
```
- `-ss` AFTER `-i` for frame accuracy
### Common operations
- Remove first 10s: `-ss 10 -c copy`
- Remove last 10s: ffprobe duration, trim to `duration - 10`
---
## Splitting
### Split at specific time
```bash
ffmpeg -n -i "$INPUT" -t 60 -c copy part1.mp4
ffmpeg -n -i "$INPUT" -ss 60 -c copy part2.mp4
```
### Split into equal segments
```bash
ffmpeg -n -i "$INPUT" -f segment -segment_time 300 -c copy -reset_timestamps 1 "segment_%03d.mp4"
```
### Scene-boundary split (PySceneDetect)
```bash
scenedetect -i "$INPUT" detect-adaptive -t 3.0 split-video
```
---
## Concatenation
### Same codec (no re-encode)
```bash
printf "file '%s'\n" file1.mp4 file2.mp4 file3.mp4 > /tmp/concat_list.txt
ffmpeg -n -f concat -safe 0 -i /tmp/concat_list.txt -c copy "$OUTPUT"
rm /tmp/concat_list.txt
```
### Different codecs (re-encodes)
```bash
ffmpeg -n -i file1.mp4 -i file2.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1" "$OUTPUT"
```
---
## Speed changes
- **Speed up 2x** (with audio pitch correction): `setpts=0.5*PTS,atempo=2.0`
- **Slow down 0.5x**: `setpts=2.0*PTS,atempo=0.5`
- **No audio**: just `setpts` filter
---
## Cropping + scaling
- **Crop**: `-vf "crop=W:H:X:Y"` (output WxH starting at X,Y)
- **Scale**: `-vf "scale=W:H"` (use `-1` to maintain aspect: `scale=1280:-1`)
- **Pad to 9:16 vertical** for Shorts/Reels: `pad=ih*9/16:ih:(ow-iw)/2:0:black`
---
## Rotation
- 90° clockwise: `-vf "transpose=1"`
- 180°: `-vf "transpose=1,transpose=1"`
- 90° counter-clockwise: `-vf "transpose=2"`
---
## Overlays + Picture-in-Picture
- **Watermark**: `-i logo.png -filter_complex "[0:v][1:v]overlay=10:10"`
- **PIP**: `-filter_complex "[0:v][1:v]overlay=W-w-10:H-h-10"`
---
## Green screen removal (chromakey)
```bash
ffmpeg -i "$INPUT" -i background.mp4 -filter_complex \
"[0:v]chromakey=0x00FF00:0.3:0.2[ckout];[1:v][ckout]overlay" "$OUTPUT"
```
---
## Stabilization (vidstab)
```bash
# 2-pass
ffmpeg -i "$INPUT" -vf vidstabdetect=stepsize=6:shakiness=8:accuracy=9 -f null -
ffmpeg -i "$INPUT" -vf vidstabtransform=smoothing=30:input=transforms.trf "$OUTPUT"
```
---
## Transitions + fades
- **Fade in**: `-vf "fade=in:0:30"` (30 frames at start)
- **Fade out**: `-vf "fade=out:DURATION-30:30"`
- **Crossfade between clips**: `xfade=transition=fade:duration=1:offset=N`
---
## Privacy blur (face/object)
- **Static blur region**: `-vf "boxblur=10:10:cr=0:ar=0"`
- **Motion-tracked blur**: requires preprocessing (OpenCV face detection → frame-by-frame mask → FFmpeg)
---
## LUT color grading
```bash
ffmpeg -i "$INPUT" -vf "lut3d='cinematic.cube'" "$OUTPUT"
```
---
## Audio operations
- **Extract audio**: `ffmpeg -i video.mp4 -q:a 0 -map a audio.mp3`
- **Replace audio**: `ffmpeg -i video.mp4 -i new_audio.mp3 -c:v copy -map 0:v -map 1:a output.mp4`
- **Normalize loudness (EBU R128)**: `-af loudnorm=I=-16:TP=-1.5:LRA=11`
- **Music ducking** (sidechain compression for voiceover): `sidechaincompress`
- **Denoise**: `-af anlmdn=s=0.001:p=0.005:r=0.002`
---
## Captions + subtitles
- **Auto-transcribe via Whisper**: `whisper input.mp4 --model medium --output_format srt`
- **Burn-in subtitles**: `-vf "subtitles=subs.srt:force_style='FontName=Arial,FontSize=24,PrimaryColour=&H00FFFFFF&'"`
- **Soft subtitles (selectable in player)**: `-c:s mov_text`
- **VTT for web**: `ffmpeg -i input.srt output.vtt`
---
## Format + codec selection
| Format | Use case | Codec |
|--------|----------|-------|
| **MP4 H.264** | Universal compatibility | `libx264 -crf 20-23` |
| **MP4 H.265 / HEVC** | Smaller files, modern devices | `libx265 -crf 24-28` |
| **WebM AV1** | Web modern, royalty-free | `libsvtav1 -crf 30` |
| **MOV ProRes** | Editing intermediate | `prores_ks -profile:v 3` (HQ) |
| **DNxHR** | Editing intermediate (alternative) | `dnxhd -b:v 36M` |
---
## GPU acceleration
- **NVIDIA**: `-c:v h264_nvenc` (NVENC), `-c:v hevc_nvenc`
- **Intel**: `-c:v h264_qsv` (QuickSync)
- **macOS**: `-c:v h264_videotoolbox`, `-c:v hevc_videotoolbox`
- **AMD**: `-c:v h264_amf`
---
## Platform-specific exports
| Platform | Resolution | Aspect | Codec | Bitrate |
|----------|-----------|--------|-------|---------|
| **YouTube 4K** | 3840x2160 | 16:9 | H.264 / H.265 | 35-45 Mbps |
| **YouTube 1080p** | 1920x1080 | 16:9 | H.264 | 8-12 Mbps |
| **YouTube Shorts** | 1080x1920 | 9:16 | H.264 | 6-10 Mbps |
| **Instagram Reels** | 1080x1920 | 9:16 | H.264 | 5-8 Mbps |
| **TikTok** | 1080x1920 | 9:16 | H.264 | 5-8 Mbps |
| **LinkedIn native** | 1920x1080 | 16:9 or 1:1 | H.264 | 5-8 Mbps |
| **Twitter/X** | 1280x720 | 16:9 | H.264 | 5 Mbps |
---
## Sources absorbed
- `the coding agent-videoedit/skills/video-edit/SKILL.md` - full FFmpeg operations: trim (lossless + frame-accurate), split (time-based + scene), concat (same vs different codec), speed changes, crop + scale + rotate, overlays + PIP, chromakey, stabilization, transitions + fades, privacy blur, LUT color grading
- `the coding agent-videoedit/skills/video-audio/SKILL.md` (referenced) - audio operations
- `the coding agent-videoedit/skills/video-caption/SKILL.md` (referenced) - captions + subtitles
- `the coding agent-videoedit/skills/video-export/SKILL.md` (referenced) - platform-specific exports
- `the coding agent-videoedit/skills/video-enhance/SKILL.md` (referenced) - enhancement operations
External skills MAY be absorbed where additive; the live roster is `control-plane/roster.json`.
---
## Deepened layers (2026-06-13, v0.4.0) - beyond FFmpeg
The FFmpeg operations above remain the headless/batch baseline. These ADD color, audio, auto-edit, motion graphics, and video-vision. (Gate 0: FFmpeg content kept, not duplicated.)
### Color + Fairlight audio + timeline → DaVinci Resolve MCP
samuelgursky/davinci-resolve-mcp (MIT, 100% API coverage, 324/324 methods, compound mode ~27 tools). The professional spine for **color grading** (node graph + LUTs + scopes + color groups), **Fairlight audio** (mixing/ducking/EQ), **timeline assembly**, EDL/XML/AAF round-trip, stills/grades, `DetectSceneCuts()`, `CreateSubtitlesFromAudio()`, deliver presets. Needs Resolve **Studio** 18.5+ (free edition has no scripting). Use Resolve for finishing; FFmpeg for headless batch. Detail: `resolve-mcp.md`.
### Word timestamps, auto-cut, shot detection, video vision
- **WhisperX** (BSD) - word-level timestamps + diarization → content-aware cuts + frame-accurate captions.
- **Auto-Editor** (Public Domain) - auto silence/motion cuts; **exports an editable timeline** (`--export resolve|premiere|final-cut-pro`) instead of forcing a render.
- **PySceneDetect** (BSD) - shot/scene detection ("watching").
- **Video vision** (METHODOLOGY) - WhisperX (speech) + PySceneDetect (structure) + vision-LLM-on-frames or **Twelve Labs** (visual) = a shot-by-shot map of the video. Detail: `auto-edit-and-vision.md`.
### Templated motion graphics + compositing
- **Remotion** (source-available; free ≤3 employees, paid 4+ - license flag) - React-defined branded templates rendered programmatically.
- **MoviePy** (MIT) - headless Python compositing + caption burn-in (pairs with WhisperX timestamps). Detail: `motion-graphics-and-compositing.md`.
### Audio post + auto-Shorts
- Audio post: FFmpeg `loudnorm` + `arnndn` (free baseline) → Resolve Fairlight → ElevenLabs Voice Isolator (shared, CONNECT) → Auphonic (commercial). Order: isolate/denoise → EQ → compress → normalize → mix.
- **Auto-Shorts pipeline** (METHODOLOGY): WhisperX → PySceneDetect/Auto-Editor → LLM highlight pick → 9:16 face-tracked reframe → MoviePy caption burn-in → platform export. Commercial alt: OpusClip. Detail: `audio-post-and-shorts.md`.
### Small-task / quick-turn lane (not every job needs the full stack)
- ONE quick op (trim/crop/concat/format convert): FFmpeg one-liner, no Resolve, no pipeline. Lossless where possible.
- SOCIAL CLIP from existing footage: FFmpeg reframe + WhisperX captions + MoviePy burn-in -> platform export. Skip Resolve grading unless color is the ask.
- FULL finish (color-critical / multi-track audio / client deliverable): Resolve MCP timeline + Fairlight + node-graph grade.
State the lane up front so you don't spin up Resolve Studio for a batch transcode.
### Shared creative tool layer
video-editor owns **FFmpeg** + **DaVinci Resolve MCP** (cluster-shared audio/video tools). It **borrows the ElevenLabs Voice Isolator** from voice-audio-producer (single owner; no duplicate ElevenLabs install). voice-audio-producer hands clean generated/isolated audio here for mix-into-timeline. Other cluster tools: ComfyUI/blender-mcp/Replicate-fal (image-generator / 3d-artist).
## Sources absorbed (v0.4.0 additions)
- samuelgursky/davinci-resolve-mcp (MIT, v2.x, 324/324 API methods) - color/Fairlight/timeline/render spine
- m-bain/whisperX (BSD) - word-level timestamps + diarization
- WyattBlue/auto-editor (Public Domain) - auto silence/motion cut + NLE timeline export
- PySceneDetect (BSD) - shot/scene detection
- Remotion (source-available, 3-seat free threshold) - templated React motion graphics
- Zulko/moviepy (MIT) - programmatic compositing + caption burn-in
- Twelve Labs API (CONNECT) - native video understanding for the vision layer
- Auphonic / ElevenLabs Voice Isolator (CONNECT, commercial) - audio post; isolator shared from voice-audio-producer
## QA Loop
All deliverables follow the canonical QA loop (`docs/QA-LOOP.md`): build → independent review → fix → repeat until clean. No self-certification.Shown under the source repo’s MIT license. Read the full folder on GitHub.