#293 by GitHub stars
kajisho5/ffmpeg-skill
Edit video and audio with local FFmpeg: cut, join, reframe, speed, captions, overlays, silence removal, sync, loudness, HDR to SDR, platform exports and checks. Use whenever the user mentions a video or audio file (mp4, mov, wav, m4a), footage, captions, a reel or short, YouTube/TikTok delivery, LUF
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
SKILL.md
Week of Nov 2, 2026 · +177 / −188 lines
Before Network or broad shell → After Network or broad shell
1ae1bdf1ca0a → 1ce2c186bf1d
- 3 description: 'Edit video and audio with local FFmpeg from natural-language requests: cut, trim, join, resize/reframe (9:16, 1:1), speed change, captions and subtitles (SRT/ASS, animated, karaoke), logos and text overlays, lower-thirds and titles, silence removal, multicam and external-mic sync, loudness normalisation, HDR/Dolby Vision to SDR, LUTs, background music with ducking, platform exports (YouTube, Reels, TikTok, X), compliance checks, scene detection and highlight reels, contact sheets to inspect results, and whole-edit project files. Use this skill whenever the user mentions a video or audio file (mp4, mov, mkv, wav, m4a), footage, a clip, captions, subtitles, a reel or short, YouTube/Instagram/TikTok delivery, LUFS, sync, transcoding, ffmpeg, or asks to make something "60 seconds", "vertical", "louder", "captioned" — even when they do not say "edit". Python 3.10+ standard library only (3.9 deprecated), no cloud, no API keys.'
+ 3 description: 'Edit video and audio with local FFmpeg: cut, join, reframe, speed, captions, overlays, silence removal, sync, loudness, HDR to SDR, platform exports and checks. Use whenever the user mentions a video or audio file (mp4, mov, wav, m4a), footage, captions, a reel or short, YouTube/TikTok delivery, LUFS or ffmpeg, even without saying "edit". Needs FFmpeg 6.1+ and Python 3.10+; stdlib only, no cloud.'
- 8 Scripts live in `scripts/` next to this file; run them with `python3 <skill-dir>/scripts/<name>.py`, and delivery templates in `templates/`. This file is enough to do a job: the table below routes the request, and `--help` on the script about to run is the cheapest full flag list. A reference file costs as much as this one; open one only for a question you have: `references/scripts.md` (every flag of all 42 scripts), `references/devices.md` (iPhone HDR, GoPro, DJI, screen recordings, Zoom), `references/gotchas.md` (the long form of the one-line rules at the end). MCP: `tools/list` shows only the core 12 by default; the other 30 (per this table) stay callable by name via `tools/call`, described by `contract --json`; set `FFMPEG_SKILL_MCP_FULL=1` for all 42.
- 9
- 10 Shared flags (every script): `--dry-run`; `--json` (output path, its probe, the commands run); `--json-brief` (status/output/verified + a `summary`; prefer on writing steps); `--fast` (preview quality); `--progress` (percent/ETA); `--timeout SECONDS` (`kind: timeout`, default 1800; `0` for hour-long encodes); `--overwrite` (step 7); `--plan FILE` (a dry run `render.py FILE` runs later; refuses if an input changed). Re-encoding tools also take `--hw` (Apple Silicon GPU, big files; `FFMPEG_SKILL_HW=1` = default, not export), `--codec h264|hevc|av1|prores` and `--quality N`: unset, SDR is x264 (`cut.py --keep-hevc`: HEVC source stays HEVC), HDR is x265 Main10; `prores` needs `-o NAME.mov`, `h264` refuses HDR (`color.py --to-sdr` first).
- 11
- 12 Writing tools run nothing under `--dry-run`; the measuring tools (`probe`, `check`, `sync`, `multicam`, `scenes`, `cropdetect`, `report`, `silence`, `loudness`, `stabilize`; `overlay` for a multi-line `--text` on FFmpeg 8.0-8.1.0) may still run ffmpeg/ffprobe, skipping artifacts/side files (`--edl`, `--sheet`, a generated `.ass`); `verify` ignores the flag. Per tool: `contract --json` `dry_run`.
+ 8 ## Quick start
+ 9
+ 10 Run `python3 <skill-dir>/scripts/<name>.py`; the table below routes requests, `--help` lists every flag.
+ 11 MCP `tools/list` shows the core 12; the other 30 of the 42 tools stay callable by name.
+ 12
+ 13 Shared flags (the rest, codec defaults and `--hw`: `references/flags.md`):
+ 14 `--dry-run` (plan, write nothing), `--json` (output, probe, commands), `--json-brief` (status + `summary`),
+ 15 `--overwrite` (step 7), `--timeout SECONDS` (default 1800, `0` = none; `kind: timeout`).
+ 16
+ 17 Writing tools run nothing under `--dry-run`; the measuring tools (`probe`, `check`, `sync`, `multicam`,
+ 18 `scenes`, `cropdetect`, `report`, `silence`, `loudness`, `stabilize`, `overlay`) may still run
+ 19 ffmpeg/ffprobe without writing artifacts; `verify` ignores the flag. Per tool: `contract --json` `dry_run`.
+ 20
+ 21 Audio-only files work in the audio tools; picture tools refuse them (`references/workflow.md#audio-only-files`).
- 16 0. **Environment, only on failure.** Never start a job with `doctor`: a broken machine fails with `kind: missing_tool` or an ffmpeg error naming the filter/encoder. Run `python3 <skill-dir>/scripts/_contract.py doctor` (or `npx ffmpeg-skill doctor`) after such a failure, or when asked what the machine can do: read `ok`/`usable`, report the missing capability. `contract --json`'s tool schema is for a *planning* agent, not this workflow.
- 17 1. **Probe what you must plan from.** Run `probe.py` on each input you plan from — duration, fps, resolution, codecs, channels, `variable_frame_rate_suspected` — and whenever the user asks about a file. No separate probe before every edit: every writing tool's `--json` already carries its input and a probe of the output. Plan from real numbers, never assumptions.
- 18 2. **Prefer lossless.** If the request can be met without re-encoding (plain cuts on keyframes, remuxing, audio-only changes), do not re-encode. `cut.py` and `loudness.py` stream-copy video by default; `--accurate` on `cut.py` only for frame-exact cuts.
- 19 3. **Plan with `--dry-run --json`, then execute.** Trust `--json`, not a dry run's summary line, for any number in the plan (a dimension there can be a placeholder). Use before long encodes, to report facts. Never point `-o` at a file you did not create in this job unless the user asked for it to be replaced; pass `--overwrite` only then.
- 20 4. **Chain in a sensible order.** A delivery request with no other editing is one template run (`render.py --template NAME INPUT`), not a hand-built chain. Otherwise: colour (HDR→SDR / LUT) → cut → join → silence → fit → caption/overlay → sync → audio → loudness → export. Frame changes before captions, so text is sized for the final frame. Re-encode as few times as possible: intermediates at CRF 18, `export.py` last. **Three or more steps: `render.py` with a project.json.**
- 21 5. **Check the deliverable.** Before reporting, run `check.py OUTPUT --platform X` for the destination named (a template run already does). Format rows (codec, pixel format, size, true peak, colour tags, VFR) are safe to fix. Judgement rows change content: duration (cut loses material), aspect (crop loses edges), fps (drops motion), loudness (ambience must not be boosted) — fix only when the request implies the answer, else state the choice and its cost. Mention WARNs; do not chase them.
- 22 6. **Verify the output.** Confirm duration, resolution, fps and audio match the request, from the writing tool's `--json`/`--json-brief` probe or `probe.py`, and report those numbers ("final.mp4: 59.98 s, 1080x1920, 30 fps, AAC stereo"). A step is done only when the script exited 0 and the output probes as expected: a non-zero exit, a missing or empty file, or a probe that contradicts the request is a failure reported with the script's error message.
- 23 7. **Keep the user's originals.** Never overwrite the source; write new files next to input or where asked. An existing output path is refused (`kind: input`); `--overwrite` is the one way to say "yes, replace it".
- 24 8. **Look at the picture.** Whenever the picture changed (captions, overlays, graphics, crop/pad, resize, colour, transitions, a `join.py` scaling a clip to the first clip's frame, `color.py --to-sdr`) run `look.py OUTPUT --tiles 3x2` (or `--at T` for one frame) and view the PNG (4x3 for whole-clip layout). Not finished until `Look:` names that PNG — a probe cannot see a caption on a face. Audio-only: `Look: not needed`. What to look for splits like `check.py`'s rows in step 5:
- 25 - **Mechanical (this skill's own job to verify and report):** the specified text/logo is at the specified position, subtitles appear at the specified timestamps, dimensions are even. Letterboxing from `fit.py --fit pad` is the *correct* result of that mode, never a defect to flag.
- 26 - **Judgement (report it, don't silently pass or fail):** whether a subject or face is cut off, text sits over a face, colours look washed out, a transition lands. These need deciding what the subject *is*, the calling agent's call — say what you see in one line; they judge.
- 27 With no vision capability, write `Look: PATH (pixels not inspected; agent has no image view)` — never claim a picture was inspected when it wasn't, without stalling for a capability that isn't there.
+ 25 Every step in full: `references/workflow.md`.
+ 26
+ 27 0. **Environment, only on failure:** after `kind: missing_tool` or an ffmpeg error, run
+ 28 `scripts/_contract.py doctor` and report what is missing. Never start with it;
+ 29 `contract --json` is for planners.
+ 30 1. **Probe what you plan from** (`probe.py`); plan from real numbers, never assumptions.
+ 31 2. **Prefer lossless:** no re-encode when a cut, remux or audio-only change suffices.
+ 32 3. **Plan with `--dry-run --json`, then run.** Trust `--json` numbers, not the summary line.
+ 33 4. **Chain:** colour → cut → join → silence → fit → caption/overlay → sync → audio → loudness → export.
+ 34 A delivery request is one `render.py --template`; three or more steps: a `render.py` project.
+ 35 5. **Check** with `check.py OUTPUT --platform X --expect-identity S:M` (the writer's `output_identity`):
+ 36 fix format rows; fix duration, aspect, fps or loudness only when the request implies it. Mention WARNs.
+ 37 6. **Verify** from the writer's `--json` probe or `probe.py`: exit 0 and the requested numbers, or it failed.
+ 38 7. **Keep originals:** never overwrite a source; `--overwrite` only for this job's files or ones the user
+ 39 asked to replace.
+ 40 8. **Look** after any picture change: `look.py OUTPUT --tiles 3x2`, view the PNG, name it in `Look:`;
+ 41 flag judgement issues in one line. No vision: say the pixels were not inspected.
- 31 Ask a short question only when the answer changes the output materially and the request does not imply it. When several things are open at once (a vague "make it for social media" leaves destination, aspect, length and captions open), don't ask one per turn: propose one bundle with your defaults and let the user change any part ("Reels: 9:16 padded, 60 s, -14 LUFS, no captions — OK?"). One question, one answer, then the run. Never ask for what `probe.py` can tell you.
- 32
- 33 - **Destination** decides aspect, length limit, loudness and codec; "for Reels" answers all four and names a template. No destination and a plain cut/caption: keep the source format and say so. If the user says "export", "post" or "deliver", ask where.
- 34 - **Duration** ("make it 60 s") without a method: speed up for ≤1.5× changes, trim otherwise, say which. Ask when the content is a talk (trimming loses words) and the change is large.
- 35 - **Captions** without a text source: `--transcribe` if a local engine exists, else ask for the text or a timed file; never invent dialogue.
- 36 - **Fonts and brand**: if the user mentions a brand, colours or "our font", ask for or create `brand.json` once, reuse it.
- 37 - **CJK / non-Latin text**: let the tool pick the font by script (`--font` turns it off); `--lang ja|ko` for Han-only text. `doctor --json` `.fonts.scripts` says what renders here. Tofu is a failed job.
- 38 - **Crop position** for `--fit crop`: centre by default, but when the request or the source names an off-centre subject ("keep the product on the right", someone visibly off-centre in the sheet) use `--crop-x`/`--crop-y` (0=left/top, 1=right/bottom) instead of guessing centre, or ask which edge to keep.
- 39 - Anything else (transition type, caption style): pick the conventional default, say what you picked, offer the alternative in one line.
+ 45 Ask only when the answer changes the output and the request does not imply it; bundle open choices
+ 46 into one proposal ("Reels: 9:16 padded, 60 s, -14 LUFS, no captions — OK?"). Never ask what a probe tells.
+ 47
+ 48 - **Destination** sets aspect, length, loudness, codec; "export/post/deliver" with none named: ask.
+ 49 - **Duration** without a method: speed for ≤1.5×, else trim; ask for a talk with a large change.
+ 50 - **Captions** without text: `--transcribe` if an engine exists, else ask; never invent dialogue.
+ 51 - **Brand, CJK text, crop position:** `references/workflow.md` (ask/assume section).
+ 52 - Anything else: pick the conventional default, say so, offer the alternative in one line.
- 43 This skill cuts, joins, measures, syncs, exports and checks files — it executes an edit, it does not decide one. What belongs to the human, the calling agent or another skill:
- 44
- 45 - **Which cut is right, or whether a deliverable is approvable** — this skill measures and reports (`check.py`'s PASS/WARN/FAIL, `cut.py`'s duration error); the user or production agent decides whether that ships.
- 46 - **What makes a highlight interesting** — `scenes.py --highlights` ranks by a measured proxy (audio energy, duration): candidates, not a verdict.
- 47 - **Thumbnail or cover composition** — a design decision, not measurement.
- 48 - **Understanding what a video is *about*** — there is no vision here beyond `look.py`'s contact sheets, for the calling agent's eyes, not for this skill to interpret.
- 49 - **Judging what looks good** — "apply this LUT", "correct exposure by +0.3 stops" (`color.py`) is mechanical; "grade this scene to look cinematic" belongs to a colour-grading skill ([`color-grading-skill`](https://github.com/kajisho5/color-grading-skill)) that decides the parameters, then calls `color.py`.
- 50 - **The words in a caption** — cue text is burned as written. Too long for the frame means a smaller size, `--max-lines`, or the user's own edit; never rewrite, shorten or paraphrase it, even when asked to "make it fit" — say so, offer `--max-lines 1` at a smaller size.
- 51 - **Picking a subject or region you were not given** — "crop to x=200,y=0" is mechanical once the box is known; "crop to keep the speaker in frame" needs deciding *what* the speaker is, a judgement for the calling agent (from a `look.py` sheet).
- 52
- 53 The line: same input + same explicit parameters always producing the same verifiable output belongs here; anything depending on taste, understanding or what looks or sounds good belongs to whoever makes that judgement.
- 54
- 55 If a request needs an FFmpeg feature none of the 42 scripts expose, say so and name the closest built-in option — never guess a raw `ffmpeg`/`ffprobe` invocation outside `scripts/*.py`. It bypasses every guarantee this skill makes, so it is never a fallback.
- 56
- 57 ## Request → script
- 58
- 59 This table and `doctor --json`'s `tools` list are the source of truth for what exists: name only a script you have seen in one of them (there is no `doctor.py`, no `trim.py`, no `subtitle.py`).
- 60
- 61 Timestamp flags (`--start`, `--end`, `--at`, `--from`, `--duration`, `--offset`, and the times in cue and chapter files) take seconds, `mm:ss(.fff)`, `hh:mm:ss(.fff)` or SMPTE `hh:mm:ss:ff` with `@fps` (`00:01:02:15@29.97`) — paste an NLE cue sheet as-is; length flags (`--min-silence`, `--margin`, `--fade`) are plain seconds.
- 62
- 63 | User says | Do |
- 64 |-----------|----|
- 65 | "cut from 1:20 to 2:05", "trim the first 10 s" | `cut.py input.mp4 --start 1:20 --end 2:05` |
- 66 | "keep only these parts", "remove the middle" | `cut.py input.mp4 --segments 0-1:00,1:30-2:00` |
- 67 | "make it exactly 60 seconds" | `fit.py input.mp4 --duration 60` (speed) or `--method trim` |
- 68 | "cut this and make it HEVC / AV1 / ProRes" (output codec named) | `cut.py input.mp4 --start 0:10 --end 0:40 --codec hevc` (ProRes needs `-o NAME.mov`) |
- 69 | "cut out the pauses", "jump cuts" | `silence.py input.mp4 [--threshold -40 --min-silence 0.8]` |
- 70 | "cut the ums and uhs", "remove the filler words" | `silence.py input.mp4 --filler --words words.json` (measured word timings; `--transcribe` makes them) |
- 71 | "don't cut inside a sentence, just the real pauses" | `silence.py input.mp4 --speech-aware` — a breath under `--min-silence` inside a sentence is kept, only sentence-boundary pauses cut; composes with `--filler` into one list |
- 72 | "a 60 s highlight from this hour" | `scenes.py long.mp4 --highlights 6 --target 60 --edl picks.txt` → `cut.py --segments` |
- 73 | "cut on the beat", "edit it to the music" | `scenes.py track.mp4 --beats --json > beats.json`, then `cut.py input.mp4 --segments ... --snap beats --snap-source beats.json` (`--snap-source` carries the measured grid over) |
- 74 | "speed up here, slow-mo there" (known segments) | `speedramp.py action.mp4 --segment 0-3:1.0 --segment 3-4:0.25 --segment 4-8:2.0` |
- 75 | "hold on this frame", "freeze the last frame" | `freeze.py clip.mp4 --hold 2` |
- 76 | "smooth slow motion", "half speed but fluid" | `fit.py input.mp4 --duration 2x --smooth interpolate` (slow) or `--smooth blend` |
- 77 | "reverse this clip" | `reverse.py input.mp4` |
- 78 | "loop this clip to fill 30 seconds" | `loop.py bg_loop.mp4 --duration 30` |
- 79 | "make it vertical / 9:16 / square" | `fit.py input.mp4 --aspect 9:16 --fit pad` (or `--fit crop`; `--pad-fill blur` for blurred bars) |
- 80 | "resize to a height/width" | `fit.py input.mp4 --height 1080` (or `--width`, or both for an exact frame) |
- 81 | "crop to this exact box" (known x/y/w/h) | `crop.py input.mp4 --x 100 --y 0 --width 1080 --height 1920` |
- 82 | "blurred background instead of black bars" | `fit.py input.mp4 --aspect 9:16 --fit blur` (whole picture kept, borders a blurred, darkened copy) |
- 83 | "rotate 90 degrees", "mirror it" | `fit.py input.mp4 --rotate 90` / `fit.py input.mp4 --flip h` |
- 84 | "the horizon is tilted" (known degrees) | `straighten.py tilted.mp4 --degrees -2.5` |
- 85 | "flat view out of this 360 video" (known yaw/pitch/fov) | `sphere.py insta360.mp4 --yaw 90 --pitch 0 --h-fov 100 --v-fov 70` |
- 86 | "this old footage is interlaced" | `deinterlace.py input.mp4` |
- 87 | "it's grainy/noisy, clean it up" | `denoise.py input.mp4 --strength medium` |
- 88 | "blur/pixelate this face/plate" (known box) | `redact.py input.mp4 --x 820 --y 140 --width 240 --height 240 --mode pixelate` |
- 89 | "remove this fixed logo" (known box) | `redact.py input.mp4 --x 40 --y 20 --width 180 --height 60 --mode delogo` |
- 90 | "stabilize this shaky footage" | `stabilize.py input.mp4` |
- 91 | "are there black bars on this?" | `cropdetect.py input.mp4` |
- 92 | "iPhone Dolby Vision clip looks wrong" | `color.py clip.mov --to-sdr` or `--strip-dovi` (keep HDR, drop the DV layer) |
- 93 | "the colours look washed out / iPhone HDR" | `color.py input.mov --to-sdr` (probe shows `hdr: true`) |
- 94 | "apply this LUT", "convert the S-Log footage" | `color.py input.mp4 --lut grade.cube [--lut-strength 0.7]` |
- 95 | "the colours are tagged wrong" | `color.py input.mp4 --retag bt709` (stream copy; re-encodes only if the copy can't carry it — see `reencoded`) |
This preview is limited. See the complete change on GitHub.
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → 1ae1bdf1ca0a
No earlier version was observed for comparison.
Verified commit 1ce2c186bf1dba96132d87274eee46df4f537e0e
git clone --filter=blob:none --no-checkout https://github.com/kajisho5/ffmpeg-skill.git .hotskills/kajisho5-ffmpeg-skill && git -C .hotskills/kajisho5-ffmpeg-skill checkout --detach 1ce2c186bf1dba96132d87274eee46df4f537e0e
# Copy each selected skill directory from .hotskills/kajisho5-ffmpeg-skill into .claude/skills/<skill-name>/git clone --filter=blob:none --no-checkout https://github.com/kajisho5/ffmpeg-skill.git .hotskills/kajisho5-ffmpeg-skill && git -C .hotskills/kajisho5-ffmpeg-skill checkout --detach 1ce2c186bf1dba96132d87274eee46df4f537e0e
# Copy each selected skill directory from .hotskills/kajisho5-ffmpeg-skill into .agents/skills/<skill-name>/Heat
8.4- Star growth, last 7 daysAhead of 99% of tracked repositories
- Star growth, last 24 hoursAhead of 99% of tracked repositories
- Rank movement, last 7 daysAhead of 90% of tracked repositories
- Commits, last 30 daysAhead of 95% of tracked repositories
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekAhead of 0% of tracked repositories
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
Individual skills in this repository
How it works
ffmpeg-skill
When your agent uses it
Edit video and audio with local FFmpeg: cut, join, reframe, speed, captions, overlays, silence removal, sync, loudness, HDR to SDR, platform exports and checks. Use whenever the user mentions a video or audio file (mp4, mov, wav, m4a), footage, captions, a reel or short, YouTube/TikTok delivery, LUFS or ffmpeg, even without saying "edit". Needs FFmpeg 6.1+ and Python 3.10+; stdlib only, no cloud.
What it loads into context
Frontmatter
122 tokensAlways available to the agent
SKILL.md
4,608 tokensWhen the skill is activated
Reference documents
347,103 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Quick start
- Workflow (in this order)
- Before you run anything: what to ask, what to assume
- What this skill does and does not decide
- Report format
- Request → script
- Things that look right but are wrong
- References
Scripts executed separately
.github/scripts/build_pages.py.github/scripts/bump_contract_md.py.github/scripts/bump_roadmap_md.py.github/scripts/design_decisions_index.py.github/scripts/resolve_version.pybin/install.jsdemos/build.pydemos/pages_videos.pyevals/contract/check.pyevals/grade_runs.pyevals/grade_runs_24.pyevals/grade_runs_25.pyevals/run.pyevals/run_agents_25.shevals/write_fixtures.pyexamples/make_demo.shmcp/server.pypackage.jsonscripts/_ass_overlay.pyscripts/_common/__init__.pyscripts/_common/asr.pyscripts/_common/color.pyscripts/_common/decision.pyscripts/_common/drawtext.pyscripts/_common/emit.pyscripts/_common/emoji.pyscripts/_common/fonts.pyscripts/_common/probe.pyscripts/_common/runner.pyscripts/_common/text.pyscripts/_common/timeline.pyscripts/_common/wrap.pyscripts/_contract.pyscripts/_platforms.pyscripts/audio.pyscripts/background.pyscripts/batch.pyscripts/broll.pyscripts/caption.pyscripts/check.pyscripts/color.pyscripts/crop.pyscripts/cropdetect.pyscripts/cut.pyscripts/deinterlace.pyscripts/denoise.pyscripts/export.pyscripts/fit.pyscripts/freeze.pyscripts/graphics.pyscripts/grid.pyscripts/insert.pyscripts/join.pyscripts/look.pyscripts/loop.pyscripts/loudness.pyscripts/metadata.pyscripts/multicam.pyscripts/overlay.pyscripts/pad.pyscripts/probe.pyscripts/proxy.pyscripts/redact.pyscripts/render.pyscripts/report.pyscripts/reverse.pyscripts/scenes.pyscripts/sequence.pyscripts/silence.pyscripts/speedramp.pyscripts/sphere.pyscripts/stabilize.pyscripts/straighten.pyscripts/sync.pyscripts/verify.pyscripts/waveform.pytests/_fixtures.pytests/bench_scenes.pytests/bench_silence.pytests/bench_sync.pytests/bench_vt.pytests/corpus.pytests/release_check.shtests/run_parallel.pytests/test_accel.pytests/test_all.pytests/test_analysis.pytests/test_asr.pytests/test_audio.pytests/test_contract.pytests/test_cut_copy.pytests/test_delivery.pytests/test_editing.pytests/test_orchestration.pytests/test_picture.py
Files
.claude-plugin/marketplace.jsonasset485 bytes.claude-plugin/plugin.jsonasset897 bytes.claude/settings.jsonasset429 bytes.claude/skills/build-artifacts/SKILL.mddoc8,443 bytes.claude/skills/ci-pipeline-synthesizer/SKILL.mddoc4,533 bytes.claude/skills/ci-pipeline-synthesizer/assets/github-actions-go.ymlasset635 bytes.claude/skills/ci-pipeline-synthesizer/assets/github-actions-nodejs.ymlasset644 bytes.claude/skills/ci-pipeline-synthesizer/assets/github-actions-python.ymlasset726 bytes.claude/skills/ci-pipeline-synthesizer/assets/github-actions-rust.ymlasset1,147 bytes.claude/skills/code-review/SKILL.mddoc9,074 bytes.claude/skills/code-review/references/result-honesty.mddoc4,942 bytes.claude/skills/code-review/references/review-checklist.mddoc3,530 bytes.claude/skills/code-review/references/surfaces.mddoc3,352 bytes.claude/skills/concurrent-branches/SKILL.mddoc11,268 bytes.claude/skills/cross-surface-changes/SKILL.mddoc11,903 bytes.claude/skills/defect-reports/SKILL.mddoc12,200 bytes.claude/skills/destructive-operations/SKILL.mddoc10,543 bytes.claude/skills/git-hygiene/SKILL.mddoc8,508 bytes.claude/skills/github-actions/SKILL.mddoc13,202 bytes.claude/skills/mcp-server-design/SKILL.mddoc12,922 bytes.claude/skills/release-management/SKILL.mddoc4,253 bytes.claude/skills/reproducing-ci-locally/SKILL.mddoc11,440 bytes.claude/skills/verifying-external-behavior/SKILL.mddoc10,913 bytes.github/FUNDING.ymlasset17 bytes.github/ISSUE_TEMPLATE/bug_report.mddoc791 bytes.github/ISSUE_TEMPLATE/config.ymlasset245 bytes.github/ISSUE_TEMPLATE/feature_request.mddoc515 bytes.github/dependabot.ymlasset574 bytes.github/pull_request_template.mddoc415 bytes.github/release-drafter.ymlasset2,540 bytes.github/scripts/build_pages.pyruns8,192 bytes.github/scripts/bump_contract_md.pyruns2,052 bytes.github/scripts/bump_roadmap_md.pyruns2,298 bytes.github/scripts/design_decisions_index.pyruns2,581 bytes.github/scripts/pages_layout.htmlasset3,362 bytes.github/scripts/resolve_version.pyruns5,433 bytes.github/workflows/ci.ymlasset8,481 bytes.github/workflows/codeql.ymlasset1,408 bytes.github/workflows/dependabot-auto-merge.ymlasset1,513 bytes.github/workflows/pages.ymlasset1,369 bytes.github/workflows/release-drafter.ymlasset2,449 bytes.github/workflows/release.ymlasset17,613 bytes.gitignoreasset379 bytes.npmignoreasset494 bytes.snykasset479 bytesAGENTS.mddoc949 bytesCHANGELOG.mddoc334,590 bytesCODE_OF_CONDUCT.mddoc507 bytesCONTRIBUTING.mddoc6,372 bytesLICENSEasset1,065 bytesREADME.mddoc103,296 bytesSECURITY.mddoc1,060 bytesSKILL.mdcore15,509 bytesSKILL.mdcore15,509 bytesSKILL.mdcore15,509 bytesassets/demo.gifasset1,647,658 bytesassets/icon.pngasset592,660 bytesassets/logo.pngasset374,426 bytesassets/social-preview.pngasset632,619 bytesbin/install.jsruns10,555 bytesbrand/app-icon-dark.pngasset65,439 bytesbrand/app-icon.pngasset64,805 bytesbrand/ffmpeg-skill.icon/Assets/in-out.svgasset372 bytesbrand/ffmpeg-skill.icon/Assets/playhead.svgasset359 bytesbrand/ffmpeg-skill.icon/icon.jsonasset1,753 bytesbrand/logo/ffmpeg-skill-wordmark-black.svgasset4,216 bytesbrand/logo/ffmpeg-skill-wordmark-white.svgasset4,216 bytesdemos/CI.mddoc6,513 bytesdemos/build.pyruns105,471 bytesdemos/footage/README.mddoc620 bytesdemos/footage/ai_talk.mp4asset227,690 bytesdemos/footage/ai_talk_en.mp4asset673,832 bytesdemos/footage/ai_talk_en.words.jsonasset1,113 bytesdemos/pages_videos.pyruns2,782 bytesdocs/contract.mddoc104,572 bytesdocs/demos.mddoc39,107 bytesdocs/demos/audiogram.gifasset195,129 bytesdocs/demos/beats_snap.gifasset10,384 bytesdocs/demos/bgm_ducking.gifasset14,755 bytesdocs/demos/broll_cutaway.gifasset217,470 bytesdocs/demos/captions_ar.gifasset246,564 bytesdocs/demos/captions_emoji.gifasset219,624 bytesdocs/demos/captions_en.gifasset216,723 bytesdocs/demos/captions_fitsize.gifasset142,056 bytesdocs/demos/captions_ja.gifasset200,664 bytesdocs/demos/captions_ko.gifasset255,794 bytesdocs/demos/captions_multitrack.gifasset223,697 bytesdocs/demos/captions_phrase.gifasset196,271 bytesdocs/demos/captions_pop_karaoke.gifasset220,093 bytesdocs/demos/captions_zh.gifasset255,446 bytesdocs/demos/color_correct.gifasset251,845 bytesdocs/demos/color_lut.gifasset236,174 bytesdocs/demos/contact_sheet.gifasset233,762 bytesdocs/demos/crop_rect.gifasset152,168 bytesdocs/demos/cropdetect_crop.gifasset240,057 bytesdocs/demos/cut_accurate.gifasset169,175 bytesdocs/demos/cut_edit_list.gifasset172,269 bytesdocs/demos/cut_remove.gifasset165,570 bytesdocs/demos/deinterlace.gifasset230,026 bytesdocs/demos/delogo.gifasset243,761 bytesdocs/demos/denoise.gifasset255,876 bytesdocs/demos/downmix_51.gifasset13,621 bytesdocs/demos/export_reels.gifasset197,557 bytesdocs/demos/filler_en.gifasset177,647 bytesdocs/demos/filler_korean.gifasset9,861 bytesdocs/demos/fit_blur.gifasset184,031 bytesdocs/demos/freeze_hold.gifasset226,696 bytesdocs/demos/greenscreen.gifasset236,324 bytesdocs/demos/grid_2x2.gifasset197,971 bytesdocs/demos/hdr_tonemap.gifasset192,072 bytesdocs/demos/insert_still.gifasset252,756 bytesdocs/demos/join_fade.gifasset203,232 bytesdocs/demos/join_fadeblack.gifasset203,232 bytesdocs/demos/logo_overlay.gifasset253,024 bytesdocs/demos/loop_times.gifasset199,497 bytesdocs/demos/loudness.gifasset13,015 bytesdocs/demos/lower_third.gifasset215,362 bytesdocs/demos/lower_third_hindi.gifasset213,711 bytesdocs/demos/metadata_auto_chapters.gifasset219,215 bytesdocs/demos/metadata_chapters.gifasset219,511 bytesdocs/demos/motion_centre_crop.gifasset35,248 bytesdocs/demos/multicam_switch.gifasset232,232 bytesdocs/demos/multicam_switch_energy.gifasset217,926 bytesdocs/demos/overlay_place.gifasset172,094 bytesdocs/demos/pad_timeline.gifasset254,443 bytesdocs/demos/proxy.gifasset148,909 bytesdocs/demos/redact_blur.gifasset168,407 bytesdocs/demos/reframe_crop.gifasset199,423 bytesdocs/demos/reframe_pad.gifasset197,828 bytesdocs/demos/reframe_talk.gifasset179,047 bytesdocs/demos/render_pip.gifasset223,728 bytesdocs/demos/render_project.gifasset172,530 bytesdocs/demos/reverse.gifasset214,530 bytesdocs/demos/scenes_highlights.gifasset217,820 bytesdocs/demos/scenes_shots.gifasset216,949 bytesdocs/demos/sequence_frames.gifasset182,062 bytesdocs/demos/silence_removal.gifasset209,051 bytesdocs/demos/silence_speech_aware.gifasset13,048 bytesdocs/demos/speed_up.gifasset199,080 bytesdocs/demos/speedramp.gifasset147,702 bytesdocs/demos/sphere_flat.gifasset206,662 bytesdocs/demos/stabilize.gifasset199,986 bytesdocs/demos/straighten.gifasset149,112 bytesdocs/demos/sync_mic.gifasset12,819 bytesdocs/demos/template_tiktok.gifasset195,829 bytesdocs/demos/title_card.gifasset118,758 bytesdocs/demos/waveform_render.gifasset184,706 bytesdocs/design-decisions.mddoc209,059 bytesdocs/roadmap.mddoc61,767 bytesevals/README.mddoc21,940 bytesevals/agent_prompts.jsonasset1,943 bytesevals/agent_prompts_24.jsonasset47,138 bytesevals/agent_prompts_25.jsonasset2,554 bytesevals/agent_prompts_26.jsonasset3,642 bytesevals/agent_prompts_audio.jsonasset1,389 bytesevals/agent_prompts_audio2.jsonasset1,793 bytesevals/agent_prompts_exec.jsonasset3,369 bytesevals/contract/README.mddoc986 bytesevals/contract/check.pyruns3,203 bytesevals/contract/questions.jsonasset2,668 bytesevals/grade_runs.pyruns2,144 bytesevals/grade_runs_24.pyruns23,151 bytesevals/grade_runs_25.pyruns6,688 bytesevals/results/audio-2.jsonasset1,167 bytesevals/results/audio-only-1.jsonasset1,039 bytesevals/results/contract-2026-09-04.jsonasset794 bytesevals/results/corpus-2026-09-13-1.10.0.mddoc4,914 bytesevals/results/exec-1.jsonasset1,980 bytesevals/results/iteration-1.jsonasset1,440 bytesevals/results/iteration-10-independent-grades.jsonasset18,119 bytesevals/results/iteration-10.jsonasset8,961 bytesevals/results/iteration-11-independent-grades.jsonasset13,693 bytesevals/results/iteration-11.jsonasset11,960 bytesevals/results/iteration-12-independent-grades.jsonasset11,557 bytesevals/results/iteration-12.jsonasset9,775 bytesevals/results/iteration-13-independent-grades.jsonasset14,611 bytesevals/results/iteration-13.jsonasset7,379 bytesevals/results/iteration-14-independent-grades.jsonasset27,247 bytesevals/results/iteration-14.jsonasset9,964 bytesevals/results/iteration-15-independent-grades.jsonasset21,515 bytesevals/results/iteration-15.jsonasset9,527 bytesevals/results/iteration-16-independent-grades.jsonasset28,813 bytesevals/results/iteration-16.jsonasset15,637 bytesevals/results/iteration-17-independent-grades.jsonasset41,327 bytesevals/results/iteration-17.jsonasset18,790 bytesevals/results/iteration-18-independent-grades.jsonasset22,163 bytesevals/results/iteration-18.jsonasset21,184 bytesevals/results/iteration-19-independent-grades.jsonasset24,846 bytesevals/results/iteration-19.jsonasset19,205 bytesevals/results/iteration-2-4-independent-grades.jsonasset24,897 bytesevals/results/iteration-2-4.jsonasset1,648 bytesevals/results/iteration-2.jsonasset1,545 bytesevals/results/iteration-20-independent-grades.jsonasset7,677 bytesevals/results/iteration-20.jsonasset11,200 bytesevals/results/iteration-21.jsonasset6,820 bytesevals/results/iteration-22.jsonasset10,382 bytesevals/results/iteration-23-partial.jsonasset5,005 bytesevals/results/iteration-23b.jsonasset6,070 bytesevals/results/iteration-23b/ff1/with_skill/outputs/run.mddoc1,348 bytesevals/results/iteration-23b/kw1/with_skill/outputs/run.mddoc2,418 bytesevals/results/iteration-24.jsonasset3,107 bytesevals/results/iteration-24/h1/with_skill/outputs/run.mddoc2,107 bytesevals/results/iteration-24/h2/with_skill/outputs/run.mddoc3,314 bytesevals/results/iteration-24/ow1/with_skill/outputs/run.mddoc3,460 bytesevals/results/iteration-24/ow2/with_skill/outputs/run.mddoc2,249 bytesevals/results/iteration-24/q1/with_skill/outputs/run.mddoc2,526 bytesevals/results/iteration-25.jsonasset5,822 bytesevals/results/iteration-5.jsonasset3,640 bytesevals/results/iteration-6.jsonasset3,819 bytesevals/results/iteration-7-independent-grades.jsonasset32,094 bytesevals/results/iteration-7.jsonasset7,789 bytesevals/results/iteration-8-independent-grades.jsonasset32,126 bytesevals/results/iteration-8.jsonasset12,309 bytesevals/results/iteration-9-independent-grades.jsonasset35,873 bytesevals/results/iteration-9.jsonasset13,437 bytesevals/results/routing-skill-md-restructure.jsonasset17,167 bytesevals/run.pyruns7,121 bytesevals/run_agents_25.shruns1,245 bytesevals/tasks.jsonasset4,646 bytesevals/trigger/README.mddoc3,952 bytesevals/trigger/prompts.jsonasset8,841 bytesevals/trigger/prompts_25.jsonasset626 bytesevals/trigger/results-2026-09-04.jsonasset5,624 bytesevals/trigger/results-2026-09-11.jsonasset6,665 bytesevals/trigger/results-2026-09-12-it7.jsonasset6,494 bytesevals/trigger/results-2026-09-12-it8.jsonasset5,724 bytesevals/trigger/results-2026-09-12-it9.jsonasset5,799 bytesevals/trigger/results-2026-09-12.jsonasset6,461 bytesevals/trigger/results-2026-09-13-it10.jsonasset5,800 bytesevals/trigger/results-2026-09-13-it11.jsonasset5,818 bytesevals/trigger/results-2026-09-13-it12.jsonasset5,818 bytesevals/trigger/results-2026-09-13-it13.jsonasset7,981 bytesevals/trigger/results-2026-09-13-it14.jsonasset9,524 bytesevals/trigger/results-2026-09-13-it15.jsonasset9,517 bytesevals/trigger/results-2026-09-13-it16.jsonasset10,119 bytesevals/trigger/results-2026-09-14-it17.jsonasset11,370 bytesevals/trigger/results-2026-09-14-it18.jsonasset12,579 bytesevals/trigger/results-2026-09-14-it19.jsonasset12,539 bytesevals/trigger/results-2026-09-14-it20.jsonasset14,355 bytesevals/trigger/results-2026-09-24-it25.jsonasset720 bytesevals/trigger/results-2026-10-31.jsonasset606 bytesevals/write_fixtures.pyruns10,140 bytesexamples/README.mddoc10,175 bytesexamples/brand.jsonasset500 bytesexamples/make_demo.shruns6,220 bytesmcp/server.pyruns12,141 bytespackage.jsonruns2,117 bytesreferences/ci-platform-pitfalls.mddoc14,183 bytesreferences/devices.mddoc3,072 bytesreferences/flags.mddoc2,170 bytesreferences/gotchas.mddoc25,808 bytesreferences/process-pitfalls.mddoc16,946 bytesreferences/report.mddoc2,827 bytesreferences/requests.mddoc12,621 bytesreferences/scripts.mddoc138,817 bytesreferences/timestamps.mddoc411 bytesreferences/workflow.mddoc9,009 bytesscripts/_ass_overlay.pyruns7,770 bytesscripts/_common/__init__.pyruns17,029 bytesscripts/_common/asr.pyruns63,447 bytesscripts/_common/color.pyruns16,414 bytesscripts/_common/decision.pyruns76,547 bytesscripts/_common/drawtext.pyruns14,625 bytesscripts/_common/emit.pyruns46,677 bytesscripts/_common/emoji.pyruns16,647 bytesscripts/_common/fonts.pyruns30,531 bytesscripts/_common/probe.pyruns51,915 bytesscripts/_common/runner.pyruns100,582 bytesscripts/_common/text.pyruns3,990 bytesscripts/_common/timeline.pyruns31,230 bytesscripts/_common/wrap.pyruns42,348 bytesscripts/_contract.pyruns177,735 bytesscripts/_platforms.pyruns12,700 bytesscripts/audio.pyruns27,247 bytesscripts/background.pyruns4,652 bytesscripts/batch.pyruns42,305 bytesscripts/broll.pyruns9,882 bytesscripts/caption.pyruns100,798 bytesscripts/check.pyruns32,184 bytesscripts/color.pyruns30,506 bytesscripts/crop.pyruns3,835 bytesscripts/cropdetect.pyruns10,272 bytesscripts/cut.pyruns104,392 bytesscripts/deinterlace.pyruns4,084 bytesscripts/denoise.pyruns4,871 bytesscripts/export.pyruns40,170 bytesscripts/fit.pyruns14,316 bytesscripts/freeze.pyruns6,524 bytesscripts/graphics.pyruns47,003 bytesscripts/grid.pyruns10,344 bytesscripts/insert.pyruns6,094 bytesscripts/join.pyruns51,016 bytesscripts/look.pyruns16,561 bytesscripts/loop.pyruns8,393 bytesscripts/loudness.pyruns12,880 bytesscripts/metadata.pyruns15,027 bytesscripts/multicam.pyruns18,188 bytesscripts/overlay.pyruns31,422 bytesscripts/pad.pyruns4,455 bytesscripts/probe.pyruns2,733 bytesscripts/proxy.pyruns3,793 bytesscripts/redact.pyruns7,504 bytesscripts/render.pyruns98,519 bytesscripts/report.pyruns17,253 bytesscripts/reverse.pyruns2,443 bytesscripts/scenes.pyruns17,776 bytesscripts/sequence.pyruns7,133 bytesscripts/silence.pyruns39,173 bytesscripts/speedramp.pyruns6,131 bytesscripts/sphere.pyruns7,302 bytesscripts/stabilize.pyruns5,338 bytesscripts/straighten.pyruns5,342 bytesscripts/sync.pyruns22,937 bytesscripts/verify.pyruns14,201 bytesscripts/waveform.pyruns21,826 bytessite/brand/apple-touch-icon.pngasset2,042 bytessite/brand/favicon.icoasset2,126 bytessite/brand/favicon.svgasset672 bytessite/brand/ffmpeg-skill-horizontal-on-dark.svgasset8,361 bytessite/brand/ffmpeg-skill-symbol-on-dark.svgasset678 bytessite/brand/og.pngasset101,199 bytessite/brand/velisa-horizontal-on-dark.svgasset8,641 bytessite/brand/velisa-horizontal.svgasset8,641 bytessite/index.htmlasset53,066 bytessite/media/filler_en.jpgasset45,708 bytessite/media/filler_en.mp4asset1,375,647 bytessite/media/reframe_talk.jpgasset35,284 bytessite/media/reframe_talk.mp4asset1,165,539 bytestemplates/audiogram.jsonasset461 bytestemplates/facebook.jsonasset702 bytestemplates/linkedin.jsonasset702 bytestemplates/podcast.jsonasset310 bytestemplates/reels.jsonasset686 bytestemplates/shorts.jsonasset689 bytestemplates/tiktok.jsonasset689 bytestemplates/x.jsonasset681 bytestemplates/youtube-shorts.jsonasset697 bytestemplates/youtube.jsonasset699 bytestests/_fixtures.pyruns24,525 bytestests/bench_scenes.pyruns5,158 bytestests/bench_silence.pyruns5,738 bytestests/bench_sync.pyruns6,968 bytestests/bench_vt.pyruns11,240 bytestests/corpus.pyruns10,059 bytestests/fixtures/README.mddoc2,619 bytestests/fixtures/caption_1_16_1_fitsize_off.assasset916 bytestests/fixtures/ffmpeg_bsfs_6.1.txtdoc608 bytestests/fixtures/ffmpeg_bsfs_8.1.2_macos.txtdoc695 bytestests/fixtures/ffmpeg_bsfs_9.0.1_windows.txtdoc759 bytestests/fixtures/ffmpeg_encoders_6.1.txtdoc13,199 bytestests/fixtures/ffmpeg_encoders_6.1_no_aac.txtdoc13,142 bytestests/fixtures/ffmpeg_encoders_8.1.2_macos.txtdoc11,102 bytestests/fixtures/ffmpeg_encoders_9.0.1_windows.txtdoc13,322 bytestests/fixtures/ffmpeg_filters_6.1.txtdoc40,185 bytestests/fixtures/ffmpeg_filters_7.1_constructed.txtdoc40,185 bytestests/fixtures/ffmpeg_filters_8.1.2_macos.txtdoc34,502 bytestests/fixtures/ffmpeg_filters_9.0.1_windows.txtdoc38,394 bytestests/fixtures/ffmpeg_filters_garbage.txtdoc75 bytestests/fixtures/mcp_tools.jsonasset16,897 bytestests/release_check.shruns6,616 bytestests/run_parallel.pyruns6,214 bytestests/test_accel.pyruns84,671 bytestests/test_all.pyruns1,596 bytestests/test_analysis.pyruns88,849 bytestests/test_asr.pyruns77,684 bytestests/test_audio.pyruns52,433 bytestests/test_contract.pyruns447,561 bytestests/test_cut_copy.pyruns134,296 bytestests/test_delivery.pyruns42,174 bytestests/test_editing.pyruns183,774 bytestests/test_orchestration.pyruns164,492 bytestests/test_picture.pyruns315,741 bytes
Read SKILL.md
# ffmpeg-skill
## Quick start
Run `python3 <skill-dir>/scripts/<name>.py`; the table below routes requests, `--help` lists every flag.
MCP `tools/list` shows the core 12; the other 30 of the 42 tools stay callable by name.
Shared flags (the rest, codec defaults and `--hw`: `references/flags.md`):
`--dry-run` (plan, write nothing), `--json` (output, probe, commands), `--json-brief` (status + `summary`),
`--overwrite` (step 7), `--timeout SECONDS` (default 1800, `0` = none; `kind: timeout`).
Writing tools run nothing under `--dry-run`; the measuring tools (`probe`, `check`, `sync`, `multicam`,
`scenes`, `cropdetect`, `report`, `silence`, `loudness`, `stabilize`, `overlay`) may still run
ffmpeg/ffprobe without writing artifacts; `verify` ignores the flag. Per tool: `contract --json` `dry_run`.View the complete source on GitHubSkills included
- ffmpeg-skill
Repository facts
- License
- MIT
- Created
- Sep 3, 2026
- Last pushed
- Nov 6, 2026
- Forks
- 371
- Open issues
- 17
- Project activity
- Active
Rank over the last 12 weeks
Now #293 · best #292 · up 174 in 30 days
- #300 on Oct 30
- #298 on Oct 31
- #296 on Nov 1
- #292 from Nov 2 to Nov 3
- #295 on Nov 4
- #293 since Nov 5
53 earlier periods
- #890 on Aug 30
- #884 on Sep 4
- #859 on Sep 5
- #890 on Sep 6
- #912 on Sep 7
- #756 on Sep 8
- #681 on Sep 9
- #664 on Sep 10
- #639 on Sep 11
- #627 on Sep 12
- #618 on Sep 13
- #625 on Sep 14
- #617 on Sep 15
- #623 on Sep 16
- #617 on Sep 17
- #587 on Sep 18
- #542 on Sep 19
- #536 on Sep 20
- #533 on Sep 21
- #540 on Sep 22
- #530 on Sep 23
- #517 on Sep 24
- #515 on Sep 25
- #513 on Sep 26
- #529 from Sep 27 to Sep 28
- #546 on Sep 29
- #534 on Sep 30
- #527 on Oct 1
- #526 on Oct 2
- #503 on Oct 3
- #464 on Oct 4
- #456 on Oct 5
- #462 on Oct 6
- #467 on Oct 7
- #475 on Oct 8
- #477 on Oct 9
- #471 on Oct 10
- #474 on Oct 11
- #483 on Oct 12
- #481 from Oct 13 to Oct 14
- #479 on Oct 15
- #482 on Oct 16
- #470 on Oct 17
- #474 on Oct 18
- #482 on Oct 19
- #483 on Oct 20
- #487 on Oct 21
- #479 on Oct 22
- #464 on Oct 23
- #404 on Oct 24
- #420 on Oct 25
- #339 on Oct 28
- #305 on Oct 29
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 5, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 9 notes
CHANGELOG.md:694Analysis incomplete: physical or joined line exceeds character limitCHANGELOG.md:696Analysis incomplete: physical or joined line exceeds character limitSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedbrand/logo/ffmpeg-skill-wordmark-black.svg:1Analysis incomplete: physical or joined line exceeds character limitbrand/logo/ffmpeg-skill-wordmark-white.svg:1Analysis incomplete: physical or joined line exceeds character limitsite/brand/ffmpeg-skill-horizontal-on-dark.svg:1Analysis incomplete: physical or joined line exceeds character limitsite/brand/velisa-horizontal-on-dark.svg:1Analysis incomplete: physical or joined line exceeds character limitsite/brand/velisa-horizontal.svg:1Analysis incomplete: physical or joined line exceeds character limit
- No broad tool permissions
- 31 dangerous shell commandsin 15 files: .claude/skills/git-hygiene/SKILL.md:3 demos/CI.md:42 README.md:106 and 12 more
- 347 network referencesin 64 files: site/index.html:10 tests/corpus.py:23 CHANGELOG.md:212 and 61 more
- 2 obfuscation signalsin 2 files: scripts/_common/emoji.py:75 tests/test_picture.py:3567
- No instruction overrides
- 95 executable scriptsin 95 files: .github/scripts/build_pages.py:1 .github/scripts/bump_contract_md.py:1 .github/scripts/bump_roadmap_md.py:1 and 92 more
- 165 references to secretsin 20 files: tests/test_contract.py:27 tests/test_picture.py:602 tests/test_accel.py:59 and 17 more
- No requests to vote in Hot
Show all 640 signals by file
.claude-plugin/marketplace.json
.claude-plugin/plugin.json
- Network accessline 5
"author": { "name": "kajisho5", "url": "https://github.com/kajisho5" - Network accessline 6
"name": "kajisho5", "url": "https://github.com/kajisho5" }, - Network accessline 7
"url": "https://github.com/kajisho5" - Network accessline 8
}, "homepage": "https://github.com/kajisho5/ffmpeg-skill", "repository": "https://github.com/kajisho5/ffmpeg-skill", - Network accessline 9
"homepage": "https://github.com/kajisho5/ffmpeg-skill", - Network accessline 10
"repository": "https://github.com/kajisho5/ffmpeg-skill",
.claude/skills/build-artifacts/SKILL.md
- Network accessline 182
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/ci-pipeline-synthesizer/SKILL.md
- Network accessline 114
- Use `actions/cache` for dependencies to reduce build times - Keep matrix versions current with language support policies - Add status badges to README.md: `` - Network accessline 116
- Add status badges to README.md: ``
.claude/skills/concurrent-branches/SKILL.md
- Network accessline 244
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/cross-surface-changes/SKILL.md
- Network accessline 227
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/defect-reports/SKILL.md
- Network accessline 222
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/destructive-operations/SKILL.md
- Dangerous shell operationline 3
description: Add and review preconditions on operations that delete, overwrite, rewrite history, or resolve a caller-supplied name to a filesystem path — refusing instead of warning, placing the guard ahead of the first mutation, structural - Dangerous shell operationline 29
// `rm -rf --ignore-unmatch .`, keeping only the state files it rewrites. - Network accessline 211
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/git-hygiene/SKILL.md
- Dangerous shell operationline 3
description: Prevents, detects, and remediates files that should never be committed — secrets (.env, API tokens, hardcoded credentials) and dev artifacts (build output, scratch databases, editor/OS files). Covers .gitignore (and why it does - Dangerous shell operationline 23
git rm --cached path/to/file # untrack, leave working-tree copy in place - Dangerous shell operationline 24
git rm -r --cached some/dir/ # for a directory - Dangerous shell operationline 62
2. **Untrack going forward** (`git rm --cached` + `.gitignore` + `.env.example` - Network accessline 93
# .pre-commit-config.yaml repos: - repo: https://github.com/gitleaks/gitleaks - Network accessline 94
repos: - repo: https://github.com/gitleaks/gitleaks rev: v8.18.0 - Network accessline 95
- repo: https://github.com/gitleaks/gitleaks - Network accessline 96
rev: v8.18.0 hooks: [{id: gitleaks}] - repo: https://github.com/Yelp/detect-secrets - Network accessline 97
hooks: [{id: gitleaks}] - repo: https://github.com/Yelp/detect-secrets rev: v1.5.0 - Network accessline 98
- repo: https://github.com/Yelp/detect-secrets - Access to secretsline 107
[Credential-related source omitted] - Access to secretsline 183
[Credential-related source omitted] - Dangerous shell operationline 188
- [ ] `git rm --cached` + .gitignore entry for each offending file - Network accessline 216
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/github-actions/SKILL.md
- Network accessline 49
run: | set -euxo pipefail curl -fsSL -o /tmp/sl.zip https://github.com/realm/SwiftLint/releases/download/0.65.0/swiftlint_linux_amd64.zip - Network accessline 50
set -euxo pipefail curl -fsSL -o /tmp/sl.zip https://github.com/realm/SwiftLint/releases/download/0.65.0/swiftlint_linux_amd64.zip unzip -oq /tmp/sl.zip -d /tmp/sl - Network accessline 51
curl -fsSL -o /tmp/sl.zip https://github.com/realm/SwiftLint/releases/download/0.65.0/swiftlint_linux_amd64.zip - Network accessline 52
unzip -oq /tmp/sl.zip -d /tmp/sl sudo install -m0755 /tmp/sl/swiftlint-static /usr/local/bin/swiftlint curl -fsSL -o /tmp/sf.zip https://github.com/nicklockwood/SwiftFormat/releases/download/0.62.1/swiftformat_linux.zip - Dangerous shell operationline 53
sudo install -m0755 /tmp/sl/swiftlint-static /usr/local/bin/swiftlint - Network accessline 53
sudo install -m0755 /tmp/sl/swiftlint-static /usr/local/bin/swiftlint curl -fsSL -o /tmp/sf.zip https://github.com/nicklockwood/SwiftFormat/releases/download/0.62.1/swiftformat_linux.zip unzip -oq /tmp/sf.zip -d /tmp/sf - Network accessline 54
curl -fsSL -o /tmp/sf.zip https://github.com/nicklockwood/SwiftFormat/releases/download/0.62.1/swiftformat_linux.zip - Dangerous shell operationline 56
sudo install -m0755 /tmp/sf/swiftformat_linux /usr/local/bin/swiftformat - Network accessline 62
which needs a Swift runtime the bare runner lacks) and SwiftFormat's `swiftformat_linux` — both are statically linked and run on plain `ubuntu-latest`. Pin versions in the URL, `curl -f` to fail on a bad download, and reference the - Network accessline 63
`swiftformat_linux` — both are statically linked and run on plain `ubuntu-latest`. Pin versions in the URL, `curl -f` to fail on a bad download, and reference the exact binary names rather than a fragile `find`. - Network accessline 64
Pin versions in the URL, `curl -f` to fail on a bad download, and reference the - Network accessline 317
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/mcp-server-design/SKILL.md
- Network accessline 286
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/release-management/SKILL.md
.claude/skills/reproducing-ci-locally/SKILL.md
- Network accessline 250
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.claude/skills/verifying-external-behavior/SKILL.md
- Network accessline 26
# The exact URL, including the collection-vs-item distinction curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/v1/things - Network accessline 27
curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/v1/things - Network accessline 28
curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/v1/things/1 - Network accessline 217
Source: [wdm0006/python-skills](https://github.com/wdm0006/python-skills) (MIT).
.github/ISSUE_TEMPLATE/config.yml
- Network accessline 2
contact_links: - name: Security vulnerability url: https://github.com/kajisho5/ffmpeg-skill/security/advisories/new - Network accessline 3
- name: Security vulnerability url: https://github.com/kajisho5/ffmpeg-skill/security/advisories/new about: Please report vulnerabilities privately (see SECURITY.md) instead of a public issue. - Network accessline 4
url: https://github.com/kajisho5/ffmpeg-skill/security/advisories/new
.github/scripts/build_pages.py
.github/scripts/bump_contract_md.py
- Executable scriptline 1
#!/usr/bin/env python3
.github/scripts/bump_roadmap_md.py
- Executable scriptline 1
#!/usr/bin/env python3
.github/scripts/design_decisions_index.py
- Executable scriptline 1
Executable file
.github/scripts/pages_layout.html
- Network accessline 8
<meta property="og:title" content="{{ page.title | default: site.title }}"> <meta property="og:description" content="{{ site.description }}"> <meta property="og:image" content="https://raw.githubusercontent.com/kajisho5/ffmpeg-skill/main/as - Network accessline 9
<meta property="og:description" content="{{ site.description }}"> <meta property="og:image" content="https://raw.githubusercontent.com/kajisho5/ffmpeg-skill/main/assets/social-preview.png"> <link rel="icon" href="{{ '/brand/app-icon.png' | - Network accessline 10
<meta property="og:image" content="https://raw.githubusercontent.com/kajisho5/ffmpeg-skill/main/assets/social-preview.png"> - Network accessline 61
<a href="{{ '/docs/design-decisions.html' | relative_url }}">Design decisions</a> <a href="{{ '/CHANGELOG.html' | relative_url }}">Changelog</a> <a href="https://github.com/kajisho5/ffmpeg-skill">GitHub</a> - Network accessline 62
<a href="{{ '/CHANGELOG.html' | relative_url }}">Changelog</a> <a href="https://github.com/kajisho5/ffmpeg-skill">GitHub</a> </div></nav> - Network accessline 63
<a href="https://github.com/kajisho5/ffmpeg-skill">GitHub</a> - Network accessline 66
{{ content }} </main> <footer>Generated from the repository's own Markdown by <code>.github/scripts/build_pages.py</code>. Source: <a href="https://github.com/kajisho5/ffmpeg-skill">kajisho5/ffmpeg-skill</a> · MIT</footer> - Network accessline 67
</main> <footer>Generated from the repository's own Markdown by <code>.github/scripts/build_pages.py</code>. Source: <a href="https://github.com/kajisho5/ffmpeg-skill">kajisho5/ffmpeg-skill</a> · MIT</footer> </body> - Network accessline 68
<footer>Generated from the repository's own Markdown by <code>.github/scripts/build_pages.py</code>. Source: <a href="https://github.com/kajisho5/ffmpeg-skill">kajisho5/ffmpeg-skill</a> · MIT</footer>
.github/scripts/resolve_version.py
.github/workflows/ci.yml
- Dangerous shell operationline 62
run: sudo apt-get update && sudo apt-get install -y ffmpeg fonts-dejavu-core
.github/workflows/pages.yml
- Network accessline 1
# Publishes https://kajisho5.github.io/ffmpeg-skill/: the landing page in site/ plus the
.github/workflows/release.yml
- Access to secretsline 131
[Credential-related source omitted] - Access to secretsline 132
[Credential-related source omitted] - Network accessline 272
with: node-version: "20" registry-url: "https://registry.npmjs.org" - Network accessline 274
registry-url: "https://registry.npmjs.org" - Access to secretsline 285
[Credential-related source omitted]
.npmignore
- Network accessline 3
# SKILL.md, README.md and LICENSE -- this excludes junk *within* those directories that npm's own # default ignore list doesn't cover (unlike .gitignore, an .npmignore is honored even when "files" # is set, per npm's own docs: https://docs. - Network accessline 4
# default ignore list doesn't cover (unlike .gitignore, an .npmignore is honored even when "files" # is set, per npm's own docs: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#files). __pycache__/ - Network accessline 5
# is set, per npm's own docs: https://docs.npmjs.com/cli/v10/configuring-npm/package-json#files).
.snyk
- Network accessline 1
# Snyk (https://snyk.io) policy file
CHANGELOG.md
- Network accessline 212
- **An input or output with a protocol prefix is refused.** ffmpeg opens a value such as `tcp:...`, `http://...` or `file:...` as a URL, while the path guards (output-is-input, existing output, output directory) read it as a path. Every too - Network accessline 345
- **A project site on GitHub Pages.** `pages.yml` publishes https://kajisho5.github.io/ffmpeg-skill/ on every push to `main` that touches the docs. `.github/scripts/build_pages.py` assembles the site from the repository's own Markdown: the - Network accessline 498
- **`doctor` warns when the FFmpeg it runs is older than the upstream fix for a known high-severity CVE.** ffmpeg-skill does not ship FFmpeg, so a decoder bug in the installed build stays until the user upgrades it. `doctor --json` has a ne - Network accessline 609
- **A `render.py` project can carry a video layer (#326).** An `overlays[]` entry takes `"video": "webcam.mp4"` as a fourth kind next to `logo`/`image`/`text`, mapped to `overlay.py --video` with the same `position`/`scale`/`opacity`/`start - Network accessline 658
- **whisper.cpp transcripts are decoded with `-mc 0` (no previous-text context).** This is a decoding change for whisper.cpp users: `caption.py --transcribe` and `silence.py --filler --transcribe` pass `-mc 0` to the `whisper-cli` calls tha - Network accessline 703
- feat(cut): `reencode_reason` says why anything was re-encoded: a list of `requested`, `codec`, `vfr`, `vfr_inconclusive`, `pcm_container`, `copy_failed`, `tolerance`, `concat_fallback` in first-seen order, `[]` for a clean copy. `--segmen - Network accessline 704
- fix(cut): a `--segments` cut whose parts copied losslessly but whose join had to re-encode reported `mode: "copy"`, `reencoded: false` and `precision: "packet"`; it now reports `hybrid`, `reencoded: true`, the re-encode's precision and `c - Network accessline 705
- The `cut.py` work above, from `reencode_reason` and the `concat_fallback` report to the edit-list, HEVC and frame-timing paths and the exact `--segments` copy joins with their `join_check`, was built by [@rymalia](https://github.com/rymal - Network accessline 712
- feat: Parakeet speech engines, built by [@rymalia](https://github.com/rymalia) in #305. `parakeet-mlx` and `parakeet.cpp` (`parakeet-cli` + a `.gguf`) for `caption.py --transcribe` and `silence.py --filler --transcribe`; `--engine` / `FFM - Network accessline 724
- feat: opt-in Apple VideoToolbox encoding. `--hw`/`--no-hw` on every re-encoding tool and `export.py` (two booleans in the contract and MCP: `hw`, `no_hw`); `FFMPEG_SKILL_HW=1` makes it the default for everything but `export.py`'s delivery - Network accessline 2511
Thanks to [@willy92wins](https://github.com/willy92wins) for the detailed repro in #100. - Network accessline 2590
stream-copied (`-c:s:i copy` per existing index) ahead of the new one, whose own `-c:s`/ `-metadata:s:s:N` now target its real index instead of always `0`. Closes [#93](https://github.com/kajisho5/ffmpeg-skill/issues/93). - Network accessline 2592
[#93](https://github.com/kajisho5/ffmpeg-skill/issues/93). - Network accessline 2613
in 0.12.0. `--json` gains `dropped_non_av_streams` (`true` only when that fallback was actually needed), matching the field name `--retag` already introduced. - **Deliberately left as-is, tracked in [#91](https://github.com/kajisho5/ffmpe - Network accessline 2614
needed), matching the field name `--retag` already introduced. - **Deliberately left as-is, tracked in [#91](https://github.com/kajisho5/ffmpeg-skill/issues/91):** `caption.py`'s burn mode (whether a pre-existing embedded subtitle should - Network accessline 2615
- **Deliberately left as-is, tracked in [#91](https://github.com/kajisho5/ffmpeg-skill/issues/91):** - Network accessline 2682
implicit "best stream" heuristic, which for audio favours channel count over track order). `join.py`/`multicam.py` are out of scope — they combine separate input files, a different problem shape. Closes [#62](https://github.com/kajisho5 - Network accessline 2683
`join.py`/`multicam.py` are out of scope — they combine separate input files, a different problem shape. Closes [#62](https://github.com/kajisho5/ffmpeg-skill/issues/62) (the same gap `caption.py`/`audio.py` already closed in [#55](http - Network accessline 2684
problem shape. Closes [#62](https://github.com/kajisho5/ffmpeg-skill/issues/62) (the same gap - Network accessline 2685
`caption.py`/`audio.py` already closed in [#55](https://github.com/kajisho5/ffmpeg-skill/issues/55)). - Network accessline 2746
since ffmpeg never runs). `--json` was never affected by any of this — it always omitted the placeholder; only a dry-run's human-readable summary line could echo the fake number. Closes [#77](https://github.com/kajisho5/ffmpeg-skill/iss - Network accessline 2748
[#77](https://github.com/kajisho5/ffmpeg-skill/issues/77). - Network accessline 2750
- **`probe.py`: `subtitle_stream_details`.** `subtitle_streams` was a plain integer count while `audio_streams` was already a detailed array, so nothing could tell which subtitle index was which language on a multi-track input (e.g. an MKV - Network accessline 2751
- **`caption.py --audio-stream N`: explicit multi-audio-track selection.** Confirmed `caption.py` did silently pick a track on a multi-audio-track input (dubbed languages, M&E stems): burn mode had no `-map` at all (ffmpeg's own automatic s - Network accessline 2752
- **`caption.py --text`: SMPTE non-drop-frame timecode cues.** Cues were positioned by decimal seconds only; broadcast-style deliverables often supply cue timing as `hh:mm:ss:ff` frame timecode instead. `--text` cue lines now also accept th - Network accessline 2753
- **`references/process-pitfalls.md`: development-process mistakes already made once.** Distinct from `references/ci-platform-pitfalls.md` (ffmpeg/CI behaviour differences): this is about the process of making a change safely, not FFmpeg it - Network accessline 2754
- **`doctor --json`: `gpu_encoders`.** No tool here uses GPU-accelerated encoding — every tool assumes CPU x264/x265 — but `doctor` had no way to answer "is GPU encoding available on this machine" at all, unlike every other capability it al - Network accessline 2755
- **`caption.py --mode mux`: soft subtitle stream instead of burn-in.** Every caption call previously re-encoded both streams to render pixels (`reencodes_video`/`reencodes_audio`: `"always"`) even when the caller only wanted a subtitle tra - Network accessline 2756
- **Test: the prose tool count in README/`docs/contract.md`/`package.json` is now checked against the real tool list.** 0.11.0 was cut to fix exactly this drift (README said 28 twice and 22 once; `package.json` said 21) by hand, with nothin - Network accessline 2766
Closes the video-editing-skill ADR-002/ADR-003 gap investigation (11 confirmed gaps): `crop.py`, `insert.py` (incl. Ken Burns), `fit.py --rotate`/`--flip`, `overlay.py --video`/`--chromakey` (video-on-video PiP, chroma key), `reverse.py`, ` - Network accessline 2768
- **SKILL.md: two more worked examples of the mechanical-vs-judgement line.** "What this skill does and does not decide" already named categories (which cut is right, highlight ranking, thumbnails, content understanding) but not the line it
CODE_OF_CONDUCT.md
- Network accessline 3
This project follows the [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/), version 2.1.
CONTRIBUTING.md
- Network accessline 43
git clone https://github.com/kajisho5/ffmpeg-skill
README.md
- Network accessline 22
<a href="#tools">Tools</a> · <a href="#mcp">MCP</a> · <a href="https://www.npmjs.com/package/ffmpeg-skill">npm</a> - Network accessline 23
<a href="#mcp">MCP</a> · <a href="https://www.npmjs.com/package/ffmpeg-skill">npm</a> </p> - Network accessline 24
<a href="https://www.npmjs.com/package/ffmpeg-skill">npm</a> - Network accessline 27
<p align="center"> <a href="https://github.com/kajisho5/ffmpeg-skill/actions/workflows/ci.yml"><img src="https://github.com/kajisho5/ffmpeg-skill/actions/workflows/ci.yml/badge.svg" alt="tests"></a> - Network accessline 28
<a href="https://github.com/kajisho5/ffmpeg-skill/actions/workflows/ci.yml"><img src="https://github.com/kajisho5/ffmpeg-skill/actions/workflows/ci.yml/badge.svg" alt="tests"></a> - Network accessline 29
<a href="https://www.npmjs.com/package/ffmpeg-skill"><img src="https://img.shields.io/npm/v/ffmpeg-skill" alt="npm"></a> - Network accessline 30
<a href="#ffmpeg-compatibility"><img src="https://img.shields.io/badge/ffmpeg-6.1%20%7C%207.1%20%7C%208%20%7C%209%20tested-orange" alt="FFmpeg 6.1, 7.1, 8 and 9 tested in CI"></a> - Network accessline 31
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="MIT"></a> - Network accessline 32
<a href="https://github.com/sponsors/kajisho5"><img src="https://img.shields.io/badge/sponsor-%E2%9D%A4-ea4aaa?logo=githubsponsors" alt="Sponsor"></a> - Network accessline 52
`ffmpeg-skill` is an [Agent Skill](https://docs.anthropic.com/en/docs/agents-and-tools/agent-skills) for Claude Code, Cursor, Codex and any agent that reads `SKILL.md`. It teaches the agent a fixed workflow (probe → edit losslessly where po - Network accessline 68
**In [kajisho5](https://github.com/kajisho5)'s wider video-production ecosystem**, this repo is the *hands*: it cuts, measures and exports files, and reports back in structured JSON. It does not decide what to cut, whether a deliverable is - Network accessline 71
|---|---| | Cut / join / measure / export a file right now | **this repo** (`ffmpeg-skill`), standalone | | Decide cut points, approve a deliverable, plan a whole edit | [`video-production-agent`](https://github.com/kajisho5/video-productio - Network accessline 72
| Cut / join / measure / export a file right now | **this repo** (`ffmpeg-skill`), standalone | | Decide cut points, approve a deliverable, plan a whole edit | [`video-production-agent`](https://github.com/kajisho5/video-production-agent) / - Network accessline 73
| Decide cut points, approve a deliverable, plan a whole edit | [`video-production-agent`](https://github.com/kajisho5/video-production-agent) / [`AI-video-production-OS`](https://github.com/kajisho5/AI-video-production-OS) | - Network accessline 74
| Build a typed editing graph across a workspace, without writing raw `ffmpeg` | [`video-editing-skill`](https://github.com/kajisho5/video-editing-skill) / [`audio-production-skill`](https://github.com/kajisho5/audio-production-skill) | - Network accessline 75
| Put Remotion motion graphics (animated captions, silence jump cuts, audio-peak motion) on a real recording | [`remotion-ffmpeg-skill`](https://github.com/kajisho5/remotion-ffmpeg-skill): its compositions take their length, fps, frame, sil - Network accessline 77
Other repos in the ecosystem — [`media-analysis-skill`](https://github.com/kajisho5/media-analysis-skill), [`transcription-skill`](https://github.com/kajisho5/transcription-skill), [`subtitle-skill`](https://github.com/kajisho5/subtitle-ski - Network accessline 100
Kajiyama, S. (2026). *What Is Verification-Driven Coding? — A Discipline for Not Trusting Generation.* Zenodo. https://doi.org/10.5281/zenodo.23720216 - Dangerous shell operationline 106
sudo apt install ffmpeg - Network accessline 199
2. **Lossless when possible.** `cut.py` and `loudness.py` stream-copy what they do not need to touch (`join.py` re-encodes so it can crossfade and conform mismatched clips; `--copy --transition none` joins clips that already match by stream - Network accessline 200
3. **Plan before render.** Every tool takes `--dry-run` (print the ffmpeg command lines, write nothing), `--plan FILE` (the dry run saved as a plan with fingerprinted inputs that `render.py FILE` executes later, refusing if an input changed - Network accessline 201
4. **Machine-readable contract.** `contract --json` describes all 42 tools: input schema generated from the parser, output schema, role, required and conditional FFmpeg capabilities, dry-run support, the verification tools to run afterwards - Network accessline 303
**SPEC** (Self-Producing Execution Contract) is the name this project's author, [kajisho5](https://github.com/kajisho5), gave the pattern the tool layer is built on: each tool's - Network accessline 304
[kajisho5](https://github.com/kajisho5), gave the pattern the tool layer is built on: each tool's - Network accessline 381
`doctor` also compares the FFmpeg version with a small, dated table of high-severity FFmpeg CVEs (`doctor --json`'s `ffmpeg_security`; source [ffmpeg.org/security.html](https://ffmpeg.org/security.html), checked 2026-10-22). ffmpeg-skill do - Dangerous shell operationline 440
Every command a tool ran is in its `--json` `commands`, shell-quoted so it can be pasted and run again, and `--dry-run` prints the commands without running anything. In the 100-prompt agent eval (1.17.0, [Tested on real footage](#tested-on- - Network accessline 465
ffmpeg-skill edits footage you already have, on this machine, with FFmpeg tools whose flags are a machine-readable contract (`contract --json`). Remotion renders a video from React components. They complement each other: this repository doe - Network accessline 504
(`tests/corpus.py`) has been run on Linux and macOS; the full corpus has **not** been run on Windows yet, and neither has an install by someone other than the maintainer been reproduced there — [issue #143](https://github.com/kajisho5/ffmpe - Network accessline 505
Windows yet, and neither has an install by someone other than the maintainer been reproduced there — [issue #143](https://github.com/kajisho5/ffmpeg-skill/issues/143) tracks both. Treat the numbers below as measured on Linux (and, where sta - Network accessline 506
there — [issue #143](https://github.com/kajisho5/ffmpeg-skill/issues/143) tracks both. Treat the - Dangerous shell operationline 613
| Ubuntu / Debian | `sudo apt install ffmpeg` | - Network accessline 675
If this skill saves you time, you can help keep it maintained through [GitHub Sponsors](https://github.com/sponsors/kajisho5). Issues and pull requests are just as welcome.
SKILL.md
- Network accessline 60
- **Thumbnail or cover composition**, and **what a video is *about*** (`look.py` is for the agent's eyes). - **Judging what looks good** — a LUT is mechanical; "cinematic" belongs to [`color-grading-skill`](https://github.com/kajisho5/col - Network accessline 61
- **Judging what looks good** — a LUT is mechanical; "cinematic" belongs to [`color-grading-skill`](https://github.com/kajisho5/color-grading-skill), which then calls `color.py`. - **The words in a caption** — burned as written; never rew - Network accessline 62
[`color-grading-skill`](https://github.com/kajisho5/color-grading-skill), which then calls `color.py`.
bin/install.js
brand/ffmpeg-skill.icon/Assets/in-out.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><defs><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="1" stop-color="#FFFFFF" stop-opacity=".78"/></linearGradient></def
brand/ffmpeg-skill.icon/Assets/playhead.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><defs><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#FFFFFF"/><stop offset="1" stop-color="#FFFFFF" stop-opacity=".78"/></linearGradient></def
brand/logo/ffmpeg-skill-wordmark-black.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -1000 5814 1300" role="img" aria-label="ffmpeg-skill"><path fill="#111111" d="M111 0V-520Q111 -582 138.0 -631.5Q165 -681 215.5 -711.0Q266 -741 337 -741Q390 -741 430.0 -723.5Q470 -706 499 -
brand/logo/ffmpeg-skill-wordmark-white.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -1000 5814 1300" role="img" aria-label="ffmpeg-skill"><path fill="#FFFFFF" d="M111 0V-520Q111 -582 138.0 -631.5Q165 -681 215.5 -711.0Q266 -741 337 -741Q390 -741 430.0 -723.5Q470 -706 499 -
demos/CI.md
- Dangerous shell operationline 42
sudo apt-get update - Dangerous shell operationline 43
sudo apt-get install -y ffmpeg fonts-dejavu-core fonts-ipafont-gothic \ - Dangerous shell operationline 96
sudo apt-get update - Dangerous shell operationline 97
sudo apt-get install -y ffmpeg fonts-dejavu-core fonts-ipafont-gothic \ - Dangerous shell operationline 104
rm -f release_assets/*_before.mp4 release_assets/*_after.mp4
demos/build.py
demos/pages_videos.py
- Executable scriptline 1
#!/usr/bin/env python3
docs/contract.md
- Network accessline 529
high-severity FFmpeg CVEs and the first upstream release on each branch that carries the fix. The table is hand-maintained in `scripts/_contract.py` (`FFMPEG_ADVISORIES`), copied from <https://ffmpeg.org/security.html> and last checked on 2 - Network accessline 530
hand-maintained in `scripts/_contract.py` (`FFMPEG_ADVISORIES`), copied from <https://ffmpeg.org/security.html> and last checked on 2026-10-22; the document repeats both as `source` and `checked`. Nothing is fetched: the check is offline, l - Network accessline 531
<https://ffmpeg.org/security.html> and last checked on 2026-10-22; the document repeats both as `source` - Network accessline 540
`{"source": "https://ffmpeg.org/security.html", "checked": "2026-10-22", "ffmpeg": {"version": "...", "status":
docs/roadmap.md
- Dangerous shell operationline 481
from 1.17.2's eval (`cs2`, a break-at-the-column-edge escape for the 1.16.1 keep-the-run-whole
evals/agent_prompts_24.json
- Network accessline 214
"id": "r03-download", "lang": "en", "prompt": "Download this YouTube video and make it a reel: https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 215
"lang": "en", "prompt": "Download this YouTube video and make it a reel: https://www.youtube.com/watch?v=dQw4w9WgXcQ", "expect": [], - Network accessline 216
"prompt": "Download this YouTube video and make it a reel: https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 251
"id": "c02", "lang": "zh", "prompt": "帮我把这个 YouTube 视频下载下来,剪成一条竖屏短视频存到 OUTDIR:https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 252
"lang": "zh", "prompt": "帮我把这个 YouTube 视频下载下来,剪成一条竖屏短视频存到 OUTDIR:https://www.youtube.com/watch?v=dQw4w9WgXcQ", "expect": [], - Network accessline 253
"prompt": "帮我把这个 YouTube 视频下载下来,剪成一条竖屏短视频存到 OUTDIR:https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 326
"id": "fr2", "lang": "fr", "prompt": "Télécharge cette vidéo YouTube et monte-la en format vertical dans OUTDIR : https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 327
"lang": "fr", "prompt": "Télécharge cette vidéo YouTube et monte-la en format vertical dans OUTDIR : https://www.youtube.com/watch?v=dQw4w9WgXcQ", "expect": [], - Network accessline 328
"prompt": "Télécharge cette vidéo YouTube et monte-la en format vertical dans OUTDIR : https://www.youtube.com/watch?v=dQw4w9WgXcQ",
evals/contract/check.py
- Executable scriptline 1
#!/usr/bin/env python3
evals/grade_runs.py
- Executable scriptline 1
#!/usr/bin/env python3
evals/grade_runs_24.py
- Executable scriptline 1
#!/usr/bin/env python3
evals/grade_runs_25.py
- Executable scriptline 1
#!/usr/bin/env python3
evals/results/iteration-16-independent-grades.json
- Dangerous shell operationline 16
"encodes_delivery": "12 of 13 delivery runs took exactly one encoding pass; e11-ready took ZERO video encodes (loudness stream-copies video); j06-report again took TWO (export.py without --normalize, then rm and re-export). Identical to ite - Dangerous shell operationline 408
"reason": "x 12/0/0 on my re-run and report.html written; but this is the one run that still takes TWO encodes - export.py --preset x first, then rm and re-export with --normalize - and it is the one delivery run that never touches render.p
evals/results/iteration-16.json
- Dangerous shell operationline 51
"encodes_delivery": "12 of 13 delivery runs took exactly one encoding pass; e11-ready took ZERO video encodes (loudness stream-copies video); j06-report again took TWO (export.py without --normalize, then rm and re-export). Identical to ite
evals/run.py
- Executable scriptline 1
#!/usr/bin/env python3
evals/run_agents_25.sh
- Executable scriptline 1
#!/bin/sh
evals/trigger/prompts.json
- Network accessline 105
"id": "n03", "lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 106
"lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", "should_trigger": false - Network accessline 107
"prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ",
evals/trigger/results-2026-09-04.json
- Network accessline 114
"id": "n03", "lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 115
"lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", "should_trigger": false, - Network accessline 116
"prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ",
evals/trigger/results-2026-09-11.json
- Network accessline 127
"id": "n03", "lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 128
"lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", "should_trigger": false, - Network accessline 129
"prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ",
evals/trigger/results-2026-09-12-it7.json
- Network accessline 127
"id": "n03", "lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 128
"lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", "should_trigger": false, - Network accessline 129
"prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ",
evals/trigger/results-2026-09-12-it8.json
- Network accessline 16
{"id": "n01","lang": "en","prompt": "Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger": false,"chosen": "image-tools","model": "sonnet","correct": true,"reason": "still image resize/transparency - Network accessline 17
{"id": "n02","lang": "ja","prompt": "Windows に ffmpeg をインストールする方法を教えて","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "install how-to, not an editing task"}, {"id": "n03","lang": "en","prompt" - Network accessline 18
{"id": "n03","lang": "en","prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "downloading a video, not edi
evals/trigger/results-2026-09-12-it9.json
- Network accessline 16
{"id": "n01","lang": "en","prompt": "Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger": false,"chosen": "image-tools","model": "sonnet","correct": true,"reason": "still image resize/transparency - Network accessline 17
{"id": "n02","lang": "ja","prompt": "Windows に ffmpeg をインストールする方法を教えて","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "install how-to question, not an editing task on a file"}, {"id": "n03","l - Network accessline 18
{"id": "n03","lang": "en","prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "downloading from the web, no
evals/trigger/results-2026-09-12.json
- Network accessline 127
"id": "n03", "lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 128
"lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", "should_trigger": false, - Network accessline 129
"prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ",
evals/trigger/results-2026-09-13-it10.json
- Network accessline 16
{"id": "n01","lang": "en","prompt": "Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger": false,"chosen": "image-tools","model": "sonnet","correct": true,"reason": "still image resize/transparency - Network accessline 17
{"id": "n02","lang": "ja","prompt": "Windows に ffmpeg をインストールする方法を教えて","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "install how-to question, not an editing task on a file"}, {"id": "n03","l - Network accessline 18
{"id": "n03","lang": "en","prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "downloading from the web, no
evals/trigger/results-2026-09-13-it11.json
- Network accessline 17
{"id": "n01","lang": "en","prompt": "Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger": false,"chosen": "image-tools","model": "sonnet","correct": true,"reason": "still image resize/transparency - Network accessline 18
{"id": "n02","lang": "ja","prompt": "Windows に ffmpeg をインストールする方法を教えて","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "install how-to question, not an editing task on a file"}, {"id": "n03","l - Network accessline 19
{"id": "n03","lang": "en","prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "downloading from the web, no
evals/trigger/results-2026-09-13-it12.json
- Network accessline 17
{"id": "n01","lang": "en","prompt": "Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger": false,"chosen": "image-tools","model": "sonnet","correct": true,"reason": "still image resize/transparency - Network accessline 18
{"id": "n02","lang": "ja","prompt": "Windows に ffmpeg をインストールする方法を教えて","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "install how-to question, not an editing task on a file"}, {"id": "n03","l - Network accessline 19
{"id": "n03","lang": "en","prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "downloading from the web, no
evals/trigger/results-2026-09-13-it13.json
- Network accessline 17
{"id": "n01","lang": "en","prompt": "Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger": false,"chosen": "image-tools","model": "sonnet","correct": true,"reason": "still image resize/transparency - Network accessline 18
{"id": "n02","lang": "ja","prompt": "Windows に ffmpeg をインストールする方法を教えて","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "install how-to question, not an editing task on a file"}, {"id": "n03","l - Network accessline 19
{"id": "n03","lang": "en","prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger": false,"chosen": "web-research","model": "sonnet","correct": true,"reason": "downloading from the web, no
evals/trigger/results-2026-09-13-it14.json
- Network accessline 12
{"id":"n01","lang":"en","prompt":"Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger":false,"chosen":"image-tools","model":"sonnet","correct":true,"reason":"Still-image resize/transparency, not vi - Network accessline 13
{"id":"n02","lang":"ja","prompt":"Windows に ffmpeg をインストールする方法を教えて","should_trigger":false,"chosen":"none","model":"sonnet","correct":true,"reason":"Installation how-to, not an editing task."}, {"id":"n03","lang":"en","prompt":"Download thi - Network accessline 14
{"id":"n03","lang":"en","prompt":"Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger":false,"chosen":"web-research","model":"sonnet","correct":true,"reason":"Downloading online content, not loca
evals/trigger/results-2026-09-13-it15.json
- Network accessline 17
{"id":"n01","lang":"en","prompt":"Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger":false,"chosen":"image-tools","model":"sonnet","correct":true,"reason":"Still image (PNG) resize, not video/aud - Network accessline 18
{"id":"n02","lang":"ja","prompt":"Windows に ffmpeg をインストールする方法を教えて","should_trigger":false,"chosen":"none","model":"sonnet","correct":true,"reason":"Install-instructions question, no media file or editing task"}, {"id":"n03","lang":"en"," - Network accessline 19
{"id":"n03","lang":"en","prompt":"Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger":false,"chosen":"web-research","model":"sonnet","correct":true,"reason":"Downloading online content, not loca
evals/trigger/results-2026-09-13-it16.json
- Network accessline 17
{"id":"n01","lang":"en","prompt":"Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger":false,"chosen":"image-tools","model":"sonnet","correct":true,"reason":"Still-image resize/transparency, not vi - Network accessline 18
{"id":"n02","lang":"ja","prompt":"Windows に ffmpeg をインストールする方法を教えて","should_trigger":false,"chosen":"none","model":"sonnet","correct":true,"reason":"Installation how-to question, not an edit request"}, {"id":"n03","lang":"en","prompt":"Do - Network accessline 19
{"id":"n03","lang":"en","prompt":"Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger":false,"chosen":"web-research","model":"sonnet","correct":true,"reason":"Downloading online content, no local
evals/trigger/results-2026-09-14-it17.json
- Network accessline 17
{"id":"n01","lang":"en","prompt":"Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger":false,"chosen":"image-tools","model":"sonnet","correct":true,"reason":"Still-image resize/transparency, not vi - Network accessline 18
{"id":"n02","lang":"ja","prompt":"Windows に ffmpeg をインストールする方法を教えて","should_trigger":false,"chosen":"none","model":"sonnet","correct":true,"reason":"Install-instructions question, not an editing task."}, {"id":"n03","lang":"en","prompt":" - Network accessline 19
{"id":"n03","lang":"en","prompt":"Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger":false,"chosen":"web-research","model":"sonnet","correct":true,"reason":"Fetching/downloading online content,
evals/trigger/results-2026-09-14-it18.json
- Network accessline 22
{"id":"n01","lang":"en","prompt":"Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger":false,"chosen":"image-tools","model":"sonnet","correct":true,"reason":"Still-image resize/transparency, not vi - Network accessline 23
{"id":"n02","lang":"ja","prompt":"Windows に ffmpeg をインストールする方法を教えて","should_trigger":false,"chosen":"none","model":"sonnet","correct":true,"reason":"Install-instructions question, not an editing task."}, {"id":"n03","lang":"en","prompt":" - Network accessline 24
{"id":"n03","lang":"en","prompt":"Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger":false,"chosen":"web-research","model":"sonnet","correct":true,"reason":"Fetching online content, not local e
evals/trigger/results-2026-09-14-it19.json
- Network accessline 22
{"id":"n01","lang":"en","prompt":"Resize this PNG logo to 512x512 and make the background transparent: logo.png","should_trigger":false,"chosen":"image-tools","model":"sonnet","correct":true,"reason":"Still-image resize/transparency, not vi - Network accessline 23
{"id":"n02","lang":"ja","prompt":"Windows に ffmpeg をインストールする方法を教えて","should_trigger":false,"chosen":"none","model":"sonnet","correct":true,"reason":"Install-instructions question, not an editing task."}, {"id":"n03","lang":"en","prompt":" - Network accessline 24
{"id":"n03","lang":"en","prompt":"Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ","should_trigger":false,"chosen":"web-research","model":"sonnet","correct":true,"reason":"Fetching online content, not local e
evals/trigger/results-2026-09-14-it20.json
- Network accessline 178
"id": "n03", "lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", - Network accessline 179
"lang": "en", "prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ", "should_trigger": false, - Network accessline 180
"prompt": "Download this YouTube video for me: https://www.youtube.com/watch?v=dQw4w9WgXcQ",
evals/write_fixtures.py
- Executable scriptline 1
#!/usr/bin/env python3
examples/make_demo.sh
- Executable scriptline 1
#!/usr/bin/env bash
mcp/server.py
package.json
- Executable scriptline 1
Executable file - Network accessline 29
"repository": { "type": "git", "url": "git+https://github.com/kajisho5/ffmpeg-skill.git" - Network accessline 30
"type": "git", "url": "git+https://github.com/kajisho5/ffmpeg-skill.git" }, - Network accessline 31
"url": "git+https://github.com/kajisho5/ffmpeg-skill.git" - Network accessline 32
}, "homepage": "https://github.com/kajisho5/ffmpeg-skill#readme", "bugs": "https://github.com/kajisho5/ffmpeg-skill/issues", - Network accessline 33
"homepage": "https://github.com/kajisho5/ffmpeg-skill#readme", - Network accessline 34
"bugs": "https://github.com/kajisho5/ffmpeg-skill/issues",
references/process-pitfalls.md
- Dangerous shell operationline 63
Rule: a probe that runs `git commit`, `git tag`, `rm -rf`, or writes into the tree goes
references/workflow.md
- Network accessline 43
- **Thumbnail or cover composition** — a design decision, not measurement. - **Understanding what a video is *about*** — there is no vision here beyond `look.py`'s contact sheets, for the calling agent's eyes, not for this skill to interpre - Network accessline 44
- **Understanding what a video is *about*** — there is no vision here beyond `look.py`'s contact sheets, for the calling agent's eyes, not for this skill to interpret. - **Judging what looks good** — "apply this LUT", "correct exposure by + - Network accessline 45
- **Judging what looks good** — "apply this LUT", "correct exposure by +0.3 stops" (`color.py`) is mechanical; "grade this scene to look cinematic" belongs to a colour-grading skill ([`color-grading-skill`](https://github.com/kajisho5/color
scripts/_ass_overlay.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/_common/__init__.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/_common/asr.py
- Executable scriptline 1
Executable file - Access to secretsline 688
[Credential-related source omitted] - Access to secretsline 706
[Credential-related source omitted] - Access to secretsline 880
[Credential-related source omitted] - Access to secretsline 897
[Credential-related source omitted] - Access to secretsline 898
[Credential-related source omitted] - Access to secretsline 939
[Credential-related source omitted]
scripts/_common/color.py
- Executable scriptline 1
Executable file
scripts/_common/decision.py
- Executable scriptline 1
Executable file
scripts/_common/drawtext.py
- Executable scriptline 1
Executable file
scripts/_common/emit.py
- Executable scriptline 1
Executable file
scripts/_common/emoji.py
scripts/_common/fonts.py
scripts/_common/probe.py
- Executable scriptline 1
Executable file
scripts/_common/runner.py
- Executable scriptline 1
Executable file - Dangerous shell operationline 25
" Debian/Ubuntu: sudo apt install ffmpeg\n" - Dangerous shell operationline 26
" Fedora: sudo dnf install ffmpeg\n" - Dangerous shell operationline 27
" Arch: sudo pacman -S ffmpeg" - Network accessline 30
" winget install Gyan.FFmpeg\n" " or: choco install ffmpeg\n" " or download a build from https://ffmpeg.org/download.html and add it to PATH" - Network accessline 31
" or: choco install ffmpeg\n" " or download a build from https://ffmpeg.org/download.html and add it to PATH" ), - Network accessline 32
" or download a build from https://ffmpeg.org/download.html and add it to PATH" - Access to secretsline 82
[Credential-related source omitted] - Access to secretsline 208
[Credential-related source omitted] - Access to secretsline 230
[Credential-related source omitted] - Network accessline 284
if found != (0, 0) and (found[0] < MIN_FFMPEG[0] or (_FFMPEG_VERSION_IS_RELEASE and found < MIN_FFMPEG)): system = platform.system() hint = INSTALL_HINTS.get(system, " See https://ffmpeg.org/download.html") - Network accessline 285
system = platform.system() hint = INSTALL_HINTS.get(system, " See https://ffmpeg.org/download.html") refuse("missing_tool", "ffmpeg_unsupported", - Network accessline 286
hint = INSTALL_HINTS.get(system, " See https://ffmpeg.org/download.html") - Network accessline 292
return path system = platform.system() hint = INSTALL_HINTS.get(system, " See https://ffmpeg.org/download.html") - Network accessline 293
system = platform.system() hint = INSTALL_HINTS.get(system, " See https://ffmpeg.org/download.html") die( - Network accessline 294
hint = INSTALL_HINTS.get(system, " See https://ffmpeg.org/download.html") - Access to secretsline 445
[Credential-related source omitted] - Access to secretsline 456
[Credential-related source omitted] - Access to secretsline 457
[Credential-related source omitted] - Access to secretsline 458
[Credential-related source omitted] - Network accessline 678
# A protocol prefix (`tcp:`, `http://`, `file:`, `concat:`, ...): ffmpeg opens such a value as a URL, - Access to secretsline 1145
[Credential-related source omitted]
scripts/_common/text.py
- Executable scriptline 1
Executable file
scripts/_common/timeline.py
- Executable scriptline 1
Executable file
scripts/_common/wrap.py
- Executable scriptline 1
Executable file
scripts/_contract.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 426
"output_path_taken": "two files one run writes (a side file and the output, or two side files) resolve to the same path, so the second would replace the first; details: {output, other}", "output_looks_like_option": "the output starts wi - Network accessline 427
"output_looks_like_option": "the output starts with '-' (other than '-' for stdout), which ffmpeg would read as an option; ./name writes a file of that name; details: {output}", "media_path_is_url": "an input or output has a protocol pr - Network accessline 428
"media_path_is_url": "an input or output has a protocol prefix (tcp:, http://, file:, ...) that ffmpeg would open as a URL; the skill reads and writes local files only; details: {path, scheme}", - Network accessline 912
# table and the local `-version` line only -- no network call, ever (execution.network: false). # # Source: https://ffmpeg.org/security.html (each release section lists the CVEs it fixes), checked - Network accessline 913
# # Source: https://ffmpeg.org/security.html (each release section lists the CVEs it fixes), checked # on FFMPEG_ADVISORIES_CHECKED. A branch absent from `fixed_in` had no release listed with the fix - Network accessline 914
# Source: https://ffmpeg.org/security.html (each release section lists the CVEs it fixes), checked - Network accessline 919
FFMPEG_ADVISORY_SOURCE = "https://ffmpeg.org/security.html" - Dangerous shell operationline 971
return "sudo apt update && sudo apt install --only-upgrade ffmpeg" - Network accessline 974
return "brew upgrade ffmpeg-full" if source == "homebrew-ffmpeg-full" else "brew upgrade ffmpeg, or the package manager it came from" if system == "Windows": return "winget upgrade Gyan.FFmpeg, or a newer build from https://ffmp - Network accessline 975
if system == "Windows": return "winget upgrade Gyan.FFmpeg, or a newer build from https://ffmpeg.org/download.html" if system == "Linux": - Network accessline 976
return "winget upgrade Gyan.FFmpeg, or a newer build from https://ffmpeg.org/download.html" - Network accessline 977
if system == "Linux": return "your distribution's package update, e.g. sudo apt install --only-upgrade ffmpeg or sudo dnf upgrade ffmpeg" return "a newer build from https://ffmpeg.org/download.html" - Dangerous shell operationline 978
return "your distribution's package update, e.g. sudo apt install --only-upgrade ffmpeg or sudo dnf upgrade ffmpeg" - Network accessline 979
return "a newer build from https://ffmpeg.org/download.html" - Network accessline 1117
result["note"] = ("drawtext renders with fontfile= (what every drawtext tool passes by default) but crashes " "when it has to resolve a font through fontconfig: pass --font-file, not a bare --font " - Network accessline 1118
"when it has to resolve a font through fontconfig: pass --font-file, not a bare --font " "<family>, on this machine (https://github.com/kajisho5/ffmpeg-skill/issues/100)") return result - Network accessline 1119
"<family>, on this machine (https://github.com/kajisho5/ffmpeg-skill/issues/100)") - Network accessline 1138
"detail": f"drawtext render crashed (exit {proc.returncode}) instead of failing cleanly -- " "the filter is present in this build but cannot render even with the fontfile= the " "tools p - Network accessline 1139
"the filter is present in this build but cannot render even with the fontfile= the " "tools pass (see https://github.com/kajisho5/ffmpeg-skill/issues/100)"} tail = " ".join(proc.stderr.strip().splitlines()[-2: - Network accessline 1140
"tools pass (see https://github.com/kajisho5/ffmpeg-skill/issues/100)"} - Network accessline 1396
if cap in ("ffmpeg", "ffprobe"): from _common import INSTALL_HINTS hint = INSTALL_HINTS.get(platform.system(), "see https://ffmpeg.org/download.html").strip().splitlines()[0].strip() - Network accessline 1398
hint = INSTALL_HINTS.get(platform.system(), "see https://ffmpeg.org/download.html").strip().splitlines()[0].strip()
scripts/_platforms.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/audio.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/background.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/batch.py
scripts/broll.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/caption.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/check.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/color.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/crop.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/cropdetect.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/cut.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/deinterlace.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/denoise.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/export.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/fit.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/freeze.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/graphics.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/grid.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/insert.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/join.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/look.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/loop.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/loudness.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/metadata.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/multicam.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/overlay.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/pad.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/probe.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/proxy.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/redact.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/render.py
scripts/report.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/reverse.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/scenes.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/sequence.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/silence.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/speedramp.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/sphere.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/stabilize.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/straighten.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/sync.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/verify.py
- Executable scriptline 1
#!/usr/bin/env python3
scripts/waveform.py
- Executable scriptline 1
#!/usr/bin/env python3
site/brand/favicon.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><style>.a{fill:#101114}.d{fill:#00A63E}@media (prefers-color-scheme:dark){.a{fill:#FFFFFF}.d{fill:#17D16A}}</style><path class="a" fill-rule="evenodd" d="M110.0,52 H52 A18,18 0 0
site/brand/ffmpeg-skill-horizontal-on-dark.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 902 256" width="902" height="256" role="img" aria-label="ffmpeg-skill"><title>ffmpeg-skill</title><g transform="translate(-34,0)"><path fill="#FFFFFF" fill-rule="evenodd" d="M117.0,52 H52
site/brand/ffmpeg-skill-symbol-on-dark.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256" role="img" aria-label="ffmpeg-skill"><title>ffmpeg-skill</title><path fill="#FFFFFF" fill-rule="evenodd" d="M117.0,52 H52 A18,18 0 0 0 34,70 V186 A18,18
site/brand/velisa-horizontal-on-dark.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 778 256" width="778" height="256" role="img" aria-label="Velisa"><title>Velisa</title><path fill="#FFFFFF" fill-rule="evenodd" d="M64.06,163.08 L64.86,164.08 L65.74,165.00 L66.72,165.82 L
site/brand/velisa-horizontal.svg
- Network accessline 1
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 778 256" width="778" height="256" role="img" aria-label="Velisa"><title>Velisa</title><path fill="#101114" fill-rule="evenodd" d="M64.06,163.08 L64.86,164.08 L65.74,165.00 L66.72,165.82 L
site/index.html
- Network accessline 10
<link rel="icon" href="brand/favicon.svg" type="image/svg+xml"> <link rel="apple-touch-icon" href="brand/apple-touch-icon.png"> <link rel="canonical" href="https://kajisho5.github.io/ffmpeg-skill/"> - Network accessline 11
<link rel="apple-touch-icon" href="brand/apple-touch-icon.png"> <link rel="canonical" href="https://kajisho5.github.io/ffmpeg-skill/"> <link rel="alternate" hreflang="en" href="https://kajisho5.github.io/ffmpeg-skill/"> - Network accessline 12
<link rel="canonical" href="https://kajisho5.github.io/ffmpeg-skill/"> - Network accessline 13
<link rel="alternate" hreflang="en" href="https://kajisho5.github.io/ffmpeg-skill/"> - Network accessline 14
<link rel="alternate" hreflang="ja" href="https://kajisho5.github.io/ffmpeg-skill/?lang=ja"> - Network accessline 16
<meta property="og:title" content="ffmpeg-skill"> <meta property="og:description" content="Give your coding agent a video editor. Local FFmpeg, no cloud, no API keys."> <meta property="og:url" content="https://kajisho5.github.io/ffmpeg-skil - Network accessline 17
<meta property="og:description" content="Give your coding agent a video editor. Local FFmpeg, no cloud, no API keys."> <meta property="og:url" content="https://kajisho5.github.io/ffmpeg-skill/"> <meta property="og:image" content="https://ka - Network accessline 18
<meta property="og:url" content="https://kajisho5.github.io/ffmpeg-skill/"> - Network accessline 19
<meta property="og:image" content="https://kajisho5.github.io/ffmpeg-skill/brand/og.png"> - Network accessline 21
<meta property="og:image:height" content="640"> <meta name="twitter:card" content="summary_large_image"> <link rel="preconnect" href="https://fonts.googleapis.com"> - Network accessline 22
<meta name="twitter:card" content="summary_large_image"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> - Network accessline 23
<link rel="preconnect" href="https://fonts.googleapis.com"> - Network accessline 24
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> - Network accessline 25
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet"> - Network accessline 26
<script src="https://unpkg.com/@phosphor-icons/web@2.1.2"></script> - Network accessline 27
<script type="application/ld+json"> { "@context": "https://schema.org", - Network accessline 28
{ "@context": "https://schema.org", "@type": "SoftwareApplication", - Network accessline 29
"@context": "https://schema.org", - Network accessline 32
"applicationCategory": "MultimediaApplication", "operatingSystem": "macOS, Linux, Windows", "license": "https://opensource.org/licenses/MIT", - Network accessline 33
"operatingSystem": "macOS, Linux, Windows", "license": "https://opensource.org/licenses/MIT", "offers": {"@type": "Offer", "price": "0", "priceCurrency": "USD"}, - Network accessline 34
"license": "https://opensource.org/licenses/MIT", - Network accessline 35
"offers": {"@type": "Offer", "price": "0", "priceCurrency": "USD"}, "url": "https://kajisho5.github.io/ffmpeg-skill/", "codeRepository": "https://github.com/kajisho5/ffmpeg-skill" - Network accessline 36
"url": "https://kajisho5.github.io/ffmpeg-skill/", - Network accessline 37
"codeRepository": "https://github.com/kajisho5/ffmpeg-skill" - Network accessline 347
<div class="acts"> <a class="btn btn-key btn-lg" href="#install" data-i="cta.start">Get started</a> <a class="btn btn-line btn-lg" href="https://github.com/kajisho5/ffmpeg-skill"><i class="ph ph-github-logo" aria-hidden= - Network accessline 348
<a class="btn btn-key btn-lg" href="#install" data-i="cta.start">Get started</a> <a class="btn btn-line btn-lg" href="https://github.com/kajisho5/ffmpeg-skill"><i class="ph ph-github-logo" aria-hidden="true"></i><span data-i="cta. - Network accessline 349
<a class="btn btn-line btn-lg" href="https://github.com/kajisho5/ffmpeg-skill"><i class="ph ph-github-logo" aria-hidden="true"></i><span data-i="cta.gh">View on GitHub</span></a> - Network accessline 494
<img class="vl vl-dark" src="brand/velisa-horizontal-on-dark.svg" alt="Velisa" width="91" height="30"> <p data-i="eco.p">On its own, it is a local FFmpeg engine. In Velisa, it is the hands: it cuts, measures and exports, and reports - Network accessline 495
<p data-i="eco.p">On its own, it is a local FFmpeg engine. In Velisa, it is the hands: it cuts, measures and exports, and reports back in JSON. It never decides what to cut.</p> <a class="go" href="https://github.com/kajisho5/Velisa - Network accessline 496
<a class="go" href="https://github.com/kajisho5/Velisa"><span data-i="eco.l">Velisa</span> →</a> - Network accessline 500
<h3>What Is Verification-Driven Coding?<br>A Discipline for Not Trusting Generation</h3> <p class="cite">Kajiyama, S. (2026). Zenodo · doi:10.5281/zenodo.23720216</p> <a class="go" href="https://doi.org/10.5281/zenodo.237202 - Network accessline 501
<p class="cite">Kajiyama, S. (2026). Zenodo · doi:10.5281/zenodo.23720216</p> <a class="go" href="https://doi.org/10.5281/zenodo.23720216"><span data-i="paper.l">Read the paper</span> →</a> </div> - Network accessline 502
<a class="go" href="https://doi.org/10.5281/zenodo.23720216"><span data-i="paper.l">Read the paper</span> →</a> - Network accessline 515
<div class="acts"> <a class="btn btn-key btn-lg" href="#install" data-i="cta.start">Get started</a> <a class="btn btn-line btn-lg" href="https://github.com/kajisho5/ffmpeg-skill"><i class="ph ph-github-logo" aria-hidden= - Network accessline 516
<a class="btn btn-key btn-lg" href="#install" data-i="cta.start">Get started</a> <a class="btn btn-line btn-lg" href="https://github.com/kajisho5/ffmpeg-skill"><i class="ph ph-github-logo" aria-hidden="true"></i><span data-i="cta. - Network accessline 517
<a class="btn btn-line btn-lg" href="https://github.com/kajisho5/ffmpeg-skill"><i class="ph ph-github-logo" aria-hidden="true"></i><span data-i="cta.gh">View on GitHub</span></a> - Network accessline 534
<span>© 2026 kajisho5 · MIT · <span data-i="f.part">Part of Velisa</span></span> <nav aria-label="Footer"> <a href="https://github.com/kajisho5/ffmpeg-skill">GitHub</a> - Network accessline 535
<nav aria-label="Footer"> <a href="https://github.com/kajisho5/ffmpeg-skill">GitHub</a> <a href="https://www.npmjs.com/package/ffmpeg-skill">npm</a> - Network accessline 536
<a href="https://github.com/kajisho5/ffmpeg-skill">GitHub</a> - Network accessline 537
<a href="https://www.npmjs.com/package/ffmpeg-skill">npm</a> - Network accessline 538
<a href="https://github.com/sponsors/kajisho5">Sponsor</a>
tests/_fixtures.py
- Executable scriptline 1
#!/usr/bin/env python3 - Access to secretsline 22
[Credential-related source omitted] - Access to secretsline 24
[Credential-related source omitted] - Access to secretsline 29
[Credential-related source omitted] - Access to secretsline 35
[Credential-related source omitted] - Access to secretsline 40
[Credential-related source omitted] - Access to secretsline 225
[Credential-related source omitted]
tests/bench_scenes.py
- Executable scriptline 1
#!/usr/bin/env python3
tests/bench_silence.py
- Executable scriptline 1
#!/usr/bin/env python3
tests/bench_sync.py
- Executable scriptline 1
#!/usr/bin/env python3
tests/bench_vt.py
- Executable scriptline 1
#!/usr/bin/env python3
tests/corpus.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 23
ROOT = Path(__file__).resolve().parent.parent DEST = ROOT / "tests" / "corpus" UA = {"User-Agent": "ffmpeg-skill-corpus/0.1 (+https://github.com/kajisho5/ffmpeg-skill)"} - Network accessline 25
UA = {"User-Agent": "ffmpeg-skill-corpus/0.1 (+https://github.com/kajisho5/ffmpeg-skill)"} - Network accessline 27
MANIFEST = [ {"id": "gopro_hero", "url": "https://archive.org/download/grizzly-bear-selfie/GX010743.MP4", "file": "gopro_GX010743.MP4", - Network accessline 28
{"id": "gopro_hero", "url": "https://archive.org/download/grizzly-bear-selfie/GX010743.MP4", "file": "gopro_GX010743.MP4", - Network accessline 29
"source": "archive.org grizzly-bear-selfie (user upload)", "why": "GoPro HERO native file: GPMF metadata track, 4:2:0 HEVC/H.264, high bitrate, extra data streams", "max_mb": 260, "expect": {"video.codec": ["hevc", "h264"], "audio.chan - Network accessline 30
"expect": {"video.codec": ["hevc", "h264"], "audio.channels": 2}}, {"id": "dji_drone", "url": "https://archive.org/download/dji-0230/DJI_0038.MOV", "file": "dji_DJI_0038.MOV", "source": "archive.org dji-0230 (user upload)", "why": - Network accessline 31
{"id": "dji_drone", "url": "https://archive.org/download/dji-0230/DJI_0038.MOV", "file": "dji_DJI_0038.MOV", - Network accessline 32
"source": "archive.org dji-0230 (user upload)", "why": "DJI drone .MOV: 4K, D-Log/normal profile, possibly no audio", "max_mb": 200, "expect": {"video.codec": ["hevc", "h264"]}}, {"id": "iphone_mov", "url": "https://archive.org/dow - Network accessline 33
"expect": {"video.codec": ["hevc", "h264"]}}, {"id": "iphone_mov", "url": "https://archive.org/download/jupiter-canyon/IMG_3179.MOV", "file": "iphone_IMG_3179.MOV", "source": "archive.org jupiter-canyon (user upload)", "why": "iPho - Network accessline 34
{"id": "iphone_mov", "url": "https://archive.org/download/jupiter-canyon/IMG_3179.MOV", "file": "iphone_IMG_3179.MOV", - Network accessline 35
"source": "archive.org jupiter-canyon (user upload)", "why": "iPhone .MOV from another device/generation than the local sample", "max_mb": 80, "expect": {"video.codec": ["hevc", "h264"]}}, {"id": "android_screen", "url": "https://a - Network accessline 36
"expect": {"video.codec": ["hevc", "h264"]}}, {"id": "android_screen", "url": "https://archive.org/download/screen-recording-20231223-021623/Screen_Recording_20231223_021623.mp4", "file": "android_screen_1.mp4", "source": "archive. - Network accessline 37
{"id": "android_screen", "url": "https://archive.org/download/screen-recording-20231223-021623/Screen_Recording_20231223_021623.mp4", "file": "android_screen_1.mp4", - Network accessline 38
"source": "archive.org screen-recording-20231223-021623", "why": "Android screen recording: VFR, odd resolution, possibly mono/no audio", "max_mb": 20, "expect": {}}, {"id": "android_screen2", "url": "https://archive.org/download/s - Network accessline 39
"expect": {}}, {"id": "android_screen2", "url": "https://archive.org/download/screen-recording-20260303-174357-2/Screen_Recording_20260303_174357(2).mp4", "file": "android_screen_2.mp4", "source": "archive.org screen-recording-2026 - Network accessline 40
{"id": "android_screen2", "url": "https://archive.org/download/screen-recording-20260303-174357-2/Screen_Recording_20260303_174357(2).mp4", "file": "android_screen_2.mp4", - Network accessline 41
"source": "archive.org screen-recording-20260303-174357-2", "why": "second Android screen recording", "max_mb": 20, "expect": {}}, {"id": "hdr10_pattern", "url": "https://archive.org/download/mehanik-hdr10-test-patterns/02.%20White%20%2 - Network accessline 42
{"id": "hdr10_pattern", "url": "https://archive.org/download/mehanik-hdr10-test-patterns/02.%20White%20%26%20Color%20clipping/02.%20White%20240-1000nits-MaxCLL-1000-MDL-1000.mp4", "file": "hdr10_white_clipping.mp4", - Network accessline 43
"source": "archive.org mehanik-hdr10-test-patterns", "why": "HDR10 (PQ, BT.2020) with MaxCLL/MDL metadata: tone-map and tag handling", "max_mb": 60, "expect": {"video.hdr": True, "video.color_transfer": "smpte2084"}}, {"id": "iphon - Network accessline 44
"expect": {"video.hdr": True, "video.color_transfer": "smpte2084"}}, {"id": "iphone13_4k60", "url": "https://img.photographyblog.com/reviews/apple_iphone_13_pro/sample_images/4K60p.mov", "file": "iphone13pro_4K60p.mov", "source": " - Network accessline 45
{"id": "iphone13_4k60", "url": "https://img.photographyblog.com/reviews/apple_iphone_13_pro/sample_images/4K60p.mov", "file": "iphone13pro_4K60p.mov", - Network accessline 46
"source": "photographyblog.com iPhone 13 Pro review samples", "why": "iPhone 13 Pro 4K60 .mov (Dolby Vision HLG expected), large frame + high fps", "max_mb": 400, "expect": {"video.codec": "hevc", "video.hdr": True}}, {"id": "blend - Network accessline 47
"expect": {"video.codec": "hevc", "video.hdr": True}}, {"id": "blender_tos_720", "url": "https://download.blender.org/demo/movies/ToS/tears_of_steel_720p.mov", "file": "tears_of_steel_720p.mov", "source": "Blender Foundation, Tears - Network accessline 48
{"id": "blender_tos_720", "url": "https://download.blender.org/demo/movies/ToS/tears_of_steel_720p.mov", "file": "tears_of_steel_720p.mov", - Network accessline 49
"source": "Blender Foundation, Tears of Steel (CC-BY 3.0)", "why": "clean H.264 .mov with real dialogue, music and scene cuts for scenes/silence/loudness", "max_mb": 400, "expect": {"video.codec": "h264", "audio.channels": 2}}, {"i - Network accessline 50
"expect": {"video.codec": "h264", "audio.channels": 2}}, {"id": "vp9_hdr", "url": "https://storage.googleapis.com/media.webmproject.org/devsite/vp9/hdr-encoding/strobe_scientist.mkv", "file": "vp9_hdr_strobe_scientist.mkv", "source - Network accessline 51
{"id": "vp9_hdr", "url": "https://storage.googleapis.com/media.webmproject.org/devsite/vp9/hdr-encoding/strobe_scientist.mkv", "file": "vp9_hdr_strobe_scientist.mkv", - Network accessline 52
"source": "webmproject.org VP9 HDR encoding guide", "why": "VP9 10-bit HDR in Matroska: non-HEVC HDR path", "max_mb": 200, "expect": {"video.codec": "vp9", "video.hdr": True}}, {"id": "rtings_24p", "url": "https://www.rtings.com/im - Network accessline 53
"expect": {"video.codec": "vp9", "video.hdr": True}}, {"id": "rtings_24p", "url": "https://www.rtings.com/images/test-materials/2015/305_24p.mp4", "file": "rtings_305_24p.mp4", "source": "rtings.com test materials", "why": "24p jud - Network accessline 54
{"id": "rtings_24p", "url": "https://www.rtings.com/images/test-materials/2015/305_24p.mp4", "file": "rtings_305_24p.mp4", - Network accessline 59
def fetch(entry: dict, force: bool = False) -> Path: - Network accessline 63
out = DEST / entry["file"] cap = entry["max_mb"] * 1024 * 1024 head = urllib.request.urlopen(urllib.request.Request(entry["url"], headers=UA, method="HEAD"), timeout=60) - Network accessline 64
cap = entry["max_mb"] * 1024 * 1024 head = urllib.request.urlopen(urllib.request.Request(entry["url"], headers=UA, method="HEAD"), timeout=60) total = int(head.headers.get("Content-Length") or 0) - Network accessline 65
head = urllib.request.urlopen(urllib.request.Request(entry["url"], headers=UA, method="HEAD"), timeout=60) - Network accessline 80
headers["Range"] = f"bytes={have}-" try: with urllib.request.urlopen(urllib.request.Request(entry["url"], headers=headers), timeout=60) as resp: - Network accessline 81
try: with urllib.request.urlopen(urllib.request.Request(entry["url"], headers=headers), timeout=60) as resp: mode = "ab" if have and resp.status == 206 else "wb" - Network accessline 82
with urllib.request.urlopen(urllib.request.Request(entry["url"], headers=headers), timeout=60) as resp: - Network accessline 138
for e in entries: try: p = fetch(e, args.force) - Network accessline 139
try: p = fetch(e, args.force) print(f"ok {e['id']:16s} {p.stat().st_size / 1e6:6.1f} MB {p.name}") - Network accessline 140
p = fetch(e, args.force)
tests/release_check.sh
tests/run_parallel.py
tests/test_accel.py
- Executable scriptline 1
#!/usr/bin/env python3 - Access to secretsline 59
[Credential-related source omitted] - Access to secretsline 178
[Credential-related source omitted] - Access to secretsline 181
[Credential-related source omitted] - Access to secretsline 193
[Credential-related source omitted] - Access to secretsline 201
[Credential-related source omitted] - Access to secretsline 211
[Credential-related source omitted] - Access to secretsline 219
[Credential-related source omitted] - Access to secretsline 301
[Credential-related source omitted] - Access to secretsline 302
[Credential-related source omitted] - Access to secretsline 304
[Credential-related source omitted] - Access to secretsline 306
[Credential-related source omitted] - Access to secretsline 494
[Credential-related source omitted] - Access to secretsline 579
[Credential-related source omitted] - Access to secretsline 582
[Credential-related source omitted] - Access to secretsline 595
[Credential-related source omitted] - Access to secretsline 737
[Credential-related source omitted] - Access to secretsline 739
[Credential-related source omitted] - Access to secretsline 1220
[Credential-related source omitted] - Access to secretsline 1250
[Credential-related source omitted] - Access to secretsline 1277
[Credential-related source omitted] - Access to secretsline 1356
[Credential-related source omitted]
tests/test_all.py
- Executable scriptline 1
#!/usr/bin/env python3
tests/test_analysis.py
- Executable scriptline 1
#!/usr/bin/env python3
tests/test_asr.py
- Executable scriptline 1
#!/usr/bin/env python3 - Access to secretsline 39
[Credential-related source omitted] - Access to secretsline 40
[Credential-related source omitted] - Access to secretsline 128
[Credential-related source omitted] - Access to secretsline 129
[Credential-related source omitted] - Access to secretsline 137
[Credential-related source omitted] - Access to secretsline 142
[Credential-related source omitted] - Access to secretsline 143
[Credential-related source omitted] - Access to secretsline 145
[Credential-related source omitted] - Access to secretsline 237
[Credential-related source omitted] - Access to secretsline 263
[Credential-related source omitted] - Access to secretsline 769
[Credential-related source omitted] - Access to secretsline 771
[Credential-related source omitted] - Access to secretsline 775
[Credential-related source omitted] - Access to secretsline 921
[Credential-related source omitted] - Access to secretsline 922
[Credential-related source omitted]
tests/test_audio.py
tests/test_contract.py
- Executable scriptline 1
#!/usr/bin/env python3 - Access to secretsline 27
[Credential-related source omitted] - Access to secretsline 34
[Credential-related source omitted] - Access to secretsline 39
[Credential-related source omitted] - Access to secretsline 46
[Credential-related source omitted] - Access to secretsline 106
[Credential-related source omitted] - Access to secretsline 945
[Credential-related source omitted] - Access to secretsline 983
[Credential-related source omitted] - Access to secretsline 1264
[Credential-related source omitted] - Access to secretsline 1265
[Credential-related source omitted] - Access to secretsline 1269
[Credential-related source omitted] - Access to secretsline 1272
[Credential-related source omitted] - Access to secretsline 1274
[Credential-related source omitted] - Access to secretsline 1366
[Credential-related source omitted] - Access to secretsline 1367
[Credential-related source omitted] - Access to secretsline 1374
[Credential-related source omitted] - Access to secretsline 1376
[Credential-related source omitted] - Access to secretsline 1377
[Credential-related source omitted] - Access to secretsline 1593
[Credential-related source omitted] - Network accessline 1857
probe.write_text( "const inst = require(process.argv[2]);\n" "const cases = [['ffmpeg version 5.1.1-static https://johnvansickle.com/ffmpeg/ Copyright', '5.1'],\n" - Network accessline 1858
"const inst = require(process.argv[2]);\n" "const cases = [['ffmpeg version 5.1.1-static https://johnvansickle.com/ffmpeg/ Copyright', '5.1'],\n" " ['ffmpeg version 6.0 Copyright', '6.0'], ['ffmpeg version 6.1.1-3u - Network accessline 1859
"const cases = [['ffmpeg version 5.1.1-static https://johnvansickle.com/ffmpeg/ Copyright', '5.1'],\n" - Access to secretsline 1919
[Credential-related source omitted] - Access to secretsline 2002
[Credential-related source omitted] - Access to secretsline 2024
[Credential-related source omitted] - Access to secretsline 2027
[Credential-related source omitted] - Access to secretsline 2028
[Credential-related source omitted] - Access to secretsline 2032
[Credential-related source omitted] - Access to secretsline 2041
[Credential-related source omitted] - Access to secretsline 2058
[Credential-related source omitted] - Access to secretsline 2132
[Credential-related source omitted] - Access to secretsline 2390
[Credential-related source omitted] - Access to secretsline 2447
[Credential-related source omitted] - Access to secretsline 2563
[Credential-related source omitted] - Access to secretsline 2877
[Credential-related source omitted] - Access to secretsline 2888
[Credential-related source omitted] - Access to secretsline 3045
[Credential-related source omitted] - Access to secretsline 3276
[Credential-related source omitted] - Access to secretsline 3279
[Credential-related source omitted] - Access to secretsline 3281
[Credential-related source omitted] - Access to secretsline 3292
[Credential-related source omitted] - Access to secretsline 3299
[Credential-related source omitted] - Access to secretsline 3302
[Credential-related source omitted] - Access to secretsline 3303
[Credential-related source omitted] - Network accessline 3415
import importlib, socket runner = importlib.import_module("_common.runner") for url in ("tcp:127.0.0.1:9?x=.mkv", "http://127.0.0.1:9/../../x.mkv", "file:other.mp4", "FILE:x.mp4", - Network accessline 3416
runner = importlib.import_module("_common.runner") for url in ("tcp:127.0.0.1:9?x=.mkv", "http://127.0.0.1:9/../../x.mkv", "file:other.mp4", "FILE:x.mp4", "rtmp://h/live", "concat:a.ts|b.ts", "data:video/mp4;base - Network accessline 3417
for url in ("tcp:127.0.0.1:9?x=.mkv", "http://127.0.0.1:9/../../x.mkv", "file:other.mp4", "FILE:x.mp4", - Network accessline 3424
srv = socket.socket(); srv.bind(("127.0.0.1", 0)); srv.listen(1); srv.settimeout(0.5) - Network accessline 3428
cases = [ ("fit", [self.src, "--aspect", "9:16", "-o", f"tcp:127.0.0.1:{port}?x=.mkv"]), ("fit", [self.src, "--aspect", "9:16", "-o", f"http://127.0.0.1:{port}/../../x.mkv"]), - Network accessline 3429
("fit", [self.src, "--aspect", "9:16", "-o", f"tcp:127.0.0.1:{port}?x=.mkv"]), ("fit", [self.src, "--aspect", "9:16", "-o", f"http://127.0.0.1:{port}/../../x.mkv"]), ("fit", [self.src, "--aspect", "9:16", "-o", "file - Network accessline 3430
("fit", [self.src, "--aspect", "9:16", "-o", f"http://127.0.0.1:{port}/../../x.mkv"]), - Network accessline 3432
("fit", [victim, "--aspect", "9:16", "-o", "file:" + str(victim)]), ("cut", [self.src, "--start", "0.2", "--end", "0.8", "--snap", "beats", "--snap-source", f"http://127.0.0.1:{port}/beacon.wav", "-o", self. - Network accessline 3433
("cut", [self.src, "--start", "0.2", "--end", "0.8", "--snap", "beats", "--snap-source", f"http://127.0.0.1:{port}/beacon.wav", "-o", self.out("ghsa_cut.mp4")]), ] - Network accessline 3434
"--snap-source", f"http://127.0.0.1:{port}/beacon.wav", "-o", self.out("ghsa_cut.mp4")]), - Access to secretsline 3681
[Credential-related source omitted] - Access to secretsline 3702
[Credential-related source omitted] - Access to secretsline 3736
[Credential-related source omitted] - Access to secretsline 3823
[Credential-related source omitted] - Access to secretsline 3840
[Credential-related source omitted] - Access to secretsline 5193
[Credential-related source omitted] - Access to secretsline 5250
[Credential-related source omitted] - Access to secretsline 5255
[Credential-related source omitted] - Access to secretsline 5259
[Credential-related source omitted] - Dangerous shell operationline 5524
self.assertIn("sudo apt", line) - Network accessline 5536
import datetime datetime.date.fromisoformat(_contract.FFMPEG_ADVISORIES_CHECKED) self.assertEqual(_contract.FFMPEG_ADVISORY_SOURCE, "https://ffmpeg.org/security.html") - Network accessline 5537
datetime.date.fromisoformat(_contract.FFMPEG_ADVISORIES_CHECKED) self.assertEqual(_contract.FFMPEG_ADVISORY_SOURCE, "https://ffmpeg.org/security.html") self.assertTrue(_contract.FFMPEG_ADVISORIES) - Network accessline 5538
self.assertEqual(_contract.FFMPEG_ADVISORY_SOURCE, "https://ffmpeg.org/security.html") - Network accessline 5554
src = (SCRIPTS / "_contract.py").read_text(encoding="utf-8") for mod in ("urllib", "http.client", "socket", "requests"): - Network accessline 5555
for mod in ("urllib", "http.client", "socket", "requests"): - Access to secretsline 5588
[Credential-related source omitted] - Access to secretsline 5660
[Credential-related source omitted] - Access to secretsline 5684
[Credential-related source omitted] - Access to secretsline 5787
[Credential-related source omitted] - Access to secretsline 5902
[Credential-related source omitted] - Access to secretsline 5944
[Credential-related source omitted] - Access to secretsline 5945
[Credential-related source omitted] - Access to secretsline 6114
[Credential-related source omitted] - Access to secretsline 6169
[Credential-related source omitted] - Access to secretsline 6360
[Credential-related source omitted]
tests/test_cut_copy.py
- Executable scriptline 1
#!/usr/bin/env python3
tests/test_delivery.py
- Executable scriptline 1
#!/usr/bin/env python3
tests/test_editing.py
- Executable scriptline 1
#!/usr/bin/env python3 - Access to secretsline 2329
[Credential-related source omitted] - Access to secretsline 2338
[Credential-related source omitted] - Access to secretsline 2360
[Credential-related source omitted] - Access to secretsline 2365
[Credential-related source omitted] - Access to secretsline 2386
[Credential-related source omitted] - Access to secretsline 2392
[Credential-related source omitted] - Access to secretsline 2524
[Credential-related source omitted]
tests/test_orchestration.py
tests/test_picture.py
- Executable scriptline 1
#!/usr/bin/env python3 - Access to secretsline 602
[Credential-related source omitted] - Access to secretsline 635
[Credential-related source omitted] - Access to secretsline 636
[Credential-related source omitted] - Access to secretsline 1127
[Credential-related source omitted] - Access to secretsline 1666
[Credential-related source omitted] - Access to secretsline 2292
[Credential-related source omitted] - Access to secretsline 3223
[Credential-related source omitted] - Access to secretsline 3224
[Credential-related source omitted] - Access to secretsline 3244
[Credential-related source omitted] - Access to secretsline 3245
[Credential-related source omitted] - Access to secretsline 3336
[Credential-related source omitted] - Access to secretsline 3337
[Credential-related source omitted] - Access to secretsline 3352
[Credential-related source omitted] - Access to secretsline 3353
[Credential-related source omitted] - Access to secretsline 3405
[Credential-related source omitted] - Network accessline 3526
source = "\n".join(p.read_text(encoding="utf-8") for p in sorted(Path(_common.__file__).parent.glob("*.py"))) for banned in ("urllib", "http.client", "requests", "socket."): - Network accessline 3527
for p in sorted(Path(_common.__file__).parent.glob("*.py"))) for banned in ("urllib", "http.client", "requests", "socket."): self.assertNotIn(banned, source, f"{banned} is reachable from the emoji path") - Network accessline 3528
for banned in ("urllib", "http.client", "requests", "socket."): - Possible obfuscationline 3567
"""U+200D ZWJ and U+200C ZWNJ are ordinary Indic/Persian orthography, not emoji: क्<U+200D>ष is - Access to secretsline 3729
[Credential-related source omitted] - Access to secretsline 3749
[Credential-related source omitted] - Access to secretsline 3776
[Credential-related source omitted] - Access to secretsline 3874
[Credential-related source omitted] - Access to secretsline 3951
[Credential-related source omitted] - Access to secretsline 4041
[Credential-related source omitted] - Access to secretsline 4894
[Credential-related source omitted]
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Hidden characters: 1 fact
- Joiner U+200D outside an emoji or a script that needs it, in prosescripts/_common/emoji.py:75High confidence
Signal confidence: 492 facts
- Network access in prose of the SKILL.md.claude/skills/build-artifacts/SKILL.md:182Low confidence
- Network access in prose of the SKILL.md.claude/skills/ci-pipeline-synthesizer/SKILL.md:114Low confidence
- Network access in prose of the SKILL.md.claude/skills/ci-pipeline-synthesizer/SKILL.md:116Low confidence
- Network access in prose of the SKILL.md.claude/skills/concurrent-branches/SKILL.md:244Low confidence
- Network access in prose of the SKILL.md.claude/skills/cross-surface-changes/SKILL.md:227Low confidence
- Network access in prose of the SKILL.md.claude/skills/defect-reports/SKILL.md:222Low confidence
- Dangerous shell operation in the frontmatter of the SKILL.md.claude/skills/destructive-operations/SKILL.md:3Low confidence
- Dangerous shell operation in code of the SKILL.md.claude/skills/destructive-operations/SKILL.md:29High confidence
- Network access in prose of the SKILL.md.claude/skills/destructive-operations/SKILL.md:211Low confidence
- Dangerous shell operation in the frontmatter of the SKILL.md.claude/skills/git-hygiene/SKILL.md:3Low confidence
- Dangerous shell operation in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:23High confidence
- Dangerous shell operation in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:24High confidence
- Dangerous shell operation in prose of the SKILL.md.claude/skills/git-hygiene/SKILL.md:62Low confidence
- Network access in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:93High confidence
- Network access in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:94High confidence
- Network access in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:95High confidence
- Network access in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:96High confidence
- Network access in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:97High confidence
- Network access in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:98High confidence
- Access to secrets in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:107High confidence
- Access to secrets in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:183High confidence
- Dangerous shell operation in code of the SKILL.md.claude/skills/git-hygiene/SKILL.md:188High confidence
- Network access in prose of the SKILL.md.claude/skills/git-hygiene/SKILL.md:216Low confidence
- Network access in code of the SKILL.md.claude/skills/github-actions/SKILL.md:49High confidence
- Network access in code of the SKILL.md.claude/skills/github-actions/SKILL.md:50High confidence
- Network access in code of the SKILL.md.claude/skills/github-actions/SKILL.md:51High confidence
- Network access in code of the SKILL.md.claude/skills/github-actions/SKILL.md:52High confidence
- Dangerous shell operation in code of the SKILL.md.claude/skills/github-actions/SKILL.md:53High confidence
- Network access in code of the SKILL.md.claude/skills/github-actions/SKILL.md:53High confidence
- Network access in code of the SKILL.md.claude/skills/github-actions/SKILL.md:54High confidence
- Dangerous shell operation in code of the SKILL.md.claude/skills/github-actions/SKILL.md:56High confidence
- Network access in prose of the SKILL.md.claude/skills/github-actions/SKILL.md:62Low confidence
- Network access in prose of the SKILL.md.claude/skills/github-actions/SKILL.md:63Low confidence
- Network access in prose of the SKILL.md.claude/skills/github-actions/SKILL.md:64Low confidence
- Network access in prose of the SKILL.md.claude/skills/github-actions/SKILL.md:317Low confidence
- Network access in prose of the SKILL.md.claude/skills/mcp-server-design/SKILL.md:286Low confidence
- Network access in code of the SKILL.md.claude/skills/release-management/SKILL.md:37High confidence
- Network access in code of the SKILL.md.claude/skills/release-management/SKILL.md:38High confidence
- Network access in prose of the SKILL.md.claude/skills/release-management/SKILL.md:147Low confidence
- Network access in prose of the SKILL.md.claude/skills/reproducing-ci-locally/SKILL.md:250Low confidence
- Network access in code of the SKILL.md.claude/skills/verifying-external-behavior/SKILL.md:26High confidence
- Network access in code of the SKILL.md.claude/skills/verifying-external-behavior/SKILL.md:27High confidence
- Network access in code of the SKILL.md.claude/skills/verifying-external-behavior/SKILL.md:28High confidence
- Network access in prose of the SKILL.md.claude/skills/verifying-external-behavior/SKILL.md:217Low confidence
- Executable script in code of a file that runs.github/scripts/build_pages.py:1High confidence
- Network access in code of a file that runs.github/scripts/build_pages.py:27High confidence
- Network access in code of a file that runs.github/scripts/build_pages.py:28High confidence
- Executable script in code of a file that runs.github/scripts/bump_contract_md.py:1High confidence
- Executable script in code of a file that runs.github/scripts/bump_roadmap_md.py:1High confidence
- Executable script in prose of a file that runs.github/scripts/design_decisions_index.py:1Low confidence
and 442 more
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Native | Manifest .claude-plugin/marketplace.json | .claude/skills/<skill-name>/ |
| Codex | Native | Manifest AGENTS.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.
Add this badge to your README
It updates every night and links to this page.
[](https://hotskills.dev/skill/kajisho5-ffmpeg-skill/)