by blixvip
Type a movie, get a captioned speech + beat-cut fan edit. Local-first, no API keys, works with your AI bot (Claude Code / Codex).
# Add to your Claude Code skills
git clone https://github.com/blixvip/easyeditSee how easyedit compares with popular alternatives.
easyedit is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by blixvip. Type a movie, get a captioned speech + beat-cut fan edit. Local-first, no API keys, works with your AI bot (Claude Code / Codex). It has 53 GitHub stars.
easyedit's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/blixvip/easyedit" and add it to your Claude Code skills directory (see the Installation section above).
easyedit is primarily written in Python. It is open-source under blixvip on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh easyedit against similar tools.
No comments yet. Be the first to share your thoughts!
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.

Type a movie name and get a finished fan edit. It makes the kind that's all over social media: the film's best speech with animated word-by-word captions, then a fast montage cut to the beat of a song.
python -m easyedit "The Wolf of Wall Street"
The finished video is saved to jobs/<movie>/<movie>.mp4 as 1920×1080 at 60fps.
| Stage | How |
|---|---|
| Plan | An LLM picks the film's most iconic speech, search queries for the scene and montage footage, a song that fits the mood, a color palette for the captions and a color grade. It uses your Claude Code login or the codex CLI, so you don't need API keys. If neither is available it uses built-in defaults. |
| Source | yt-dlp searches YouTube and downloads the speech scene, 1–2 montage sources and the song. Any of these can be replaced with a local file or a URL. |
| Transcribe | faster-whisper gives a timestamp for every word, on the GPU when one is available. |
| Quote | The LLM picks the best continuous 9–24s passage and marks emphasis words by role: positive, negative, gold or cool. The passage is split into caption lines at pauses. A heuristic takes over if the LLM fails. |
| Faces | OpenCV YuNet tracks the speaker at 10Hz so the camera can push in and follow their face. |
| Shots | Finds scene cuts in the montage sources and scores each shot on motion, sharpness, contrast, color and faces. It removes black bars, title cards and near-duplicate shots. |
| Beats | A numpy beat tracker (spectral flux plus dynamic programming) finds the song's tempo, its beats and the drop. The montage starts exactly on the drop. |
| Assemble | Cuts land exactly on real beats in a repeating short/long pattern. It encodes the footage frame-accurately, and the song stays quiet under the speech, then jumps to full volume on the drop. |
| Render | A HyperFrames composition (template/) adds the effects: face-follow camera, captions that go from blur to outline to glowing fill, echo text behind emphasis words, whip transitions with directional motion blur, flashes, beat-synced zoom pulses, film grain, and a black-and-white final shot with the title card. It renders as parallel sections (each one streams its frames straight into the encoder, so nothing piles up on disk), then the soundtrack is muxed in and the video is encoded once for delivery. |
Requirements: Python 3.10+, Node.js 22+, FFmpeg on PATH. An NVIDIA GPU is optional: it makes transcription
and the final encode faster. Everything else (fonts, the face model, Chrome for rendering) downloads on first
run into .cache/.
git clone https://github.com/blixvip/easyedit && cd easyedit
npm install
pip install -r requirements.txt
python -m easyedit.doctor # checks everything and tells you what to fix
Connect an AI account so it can pick the scene, the quote and the song. One is enough, and there are no API keys:
sign in to Claude Code (claude auth login) or Codex (codex login), or click Connect in the web UI. With no
account connected you still get an edit, but it runs on heuristics.
easyedit is built so an AI agent can run the whole thing for you, from install to curating the shots to the final render. Paste this into Claude Code, Codex or any agent that can use a terminal:
Install easyedit from https://github.com/blixvip/easyedit. Read its AGENTS.md first and follow it.
Run "python -m easyedit.doctor" and fix anything it flags.
Then make a fan edit of "Gladiator" and tell me where the finished video is.
AGENTS.md is the agent's playbook. It covers setup, checking the quote, reading the shot contact
sheets, writing curate.json, rendering, and checking the stills afterwards. For Claude Code there's also a skill:
python -m easyedit.skill install # then: /easyedit Gladiator
The web UI's Bot section has these prompts ready to copy, with your movie filled in. A bot on the same
computer can also drive the running app through its local API (POST /api/new, GET /api/jobs). See AGENTS.md.
python -m easyedit.web # http://127.0.0.1:4331 (easyedit-web.cmd on Windows)
A gallery of every edit you have made (thumbnail, length, the line it captions) plus a box to start a new one. Running jobs show a live stage/progress bar and their log, and can be stopped from the page. Click a thumbnail to watch the edit in the browser.
Connect shows which AI accounts are signed in and checks this computer's tools. Its buttons open the sign-in for Claude or Codex. Give it to your bot has copy-ready prompts for an agent.
# fully automatic
python -m easyedit "Fight Club"
# steer any stage: local file, URL, or your own search query
python -m easyedit "Interstellar" \
--speech "interstellar do not go gentle scene" \
--montage ~/clips/interstellar-trailer.mp4 \
--music "https://www.youtube.com/watch?v=..."
# fast iteration
python -m easyedit "Scarface" --draft # 30fps, draft quality
python -m easyedit "Scarface" --preview 15 25 # render only 15s-25s
python -m easyedit "Scarface" --no-render # build footage + edit.js only
| Flag | Default | |
|---|---|---|
--speech / --montage / --music |
auto | file, URL or search query (--montage can be repeated) |
--llm |
auto |
claude, codex or none |
--fps |
60 |
24, 30 or 60 |
--montage-length |
21 |
seconds of beat cuts |
--hero-length |
3.4 |
seconds of the final black-and-white shot |
--language |
en |
speech language (non-English uses whisper large-v3) |
--cookies-from-browser |
for age-restricted YouTube clips, e.g. chrome |
|
--fresh |
re-plan and re-pick instead of reusing the cache |
Every stage caches its results in jobs/<movie>/: downloads, transcripts, shot and beat analysis, plan.json,
quote.json and sources.json (which pins the chosen downloads, since YouTube search results drift).
Re-running is quick, and you can edit quote.json or render/edit.js by hand and render again.
To hand-pick the montage, add jobs/<movie>/curate.json. Shot ids are <source stem>@<start seconds>, and
they're listed in work/shots-*.json:
{"pin": ["TaaDkbG3I7g@110.52", "ebjTAHwSWMw@73.60"], "exclude": ["TaaDkbG3I7g@32.77"], "hero": "ebjTAHwSWMw@163.10"}
To see the shots, run python -m easyedit.sheet "<movie>". It writes qa/candidates.jpg (every shot, numbered),
qa/candidates.txt (number → id) and qa/footage.jpg (the cut in order). Add --final to get stills from
the rendered video.
pin shots are used first, in that order. exclude shots are never used, and hero is the final black-and-white shot.
Environment overrides: EASYEDIT_CLAUDE_MODEL, EASYEDIT_WHISPER (a faster-whisper model name),
EASYEDIT_PARALLEL (render processes, default 2 - raise it if you have RAM to spare) and
EASYEDIT_ENCODER=x264 (the default uses NVENC when the GPU has it).
Rendering is the slow part: roughly 5 frames/second at 1080p60 on a GTX 1650, so about 8 minutes
for a 40-second edit. --fps 30 halves it.
Everything visual is in template/film.js. It's a pure function of time, so any frame renders on its own.
To preview a built job in the browser:
cd jobs/<movie>/render && npx hyperframes preview
Use footage and music you have the right to use. easyedit doesn't include any film or music content; it only
processes what you point it at or what it downloads into your local jobs/ folder.
| Symptom | Fix |
|---|---|
| YouTube downloads fail with HTTP 403 | pip install -U "yt-dlp[default]". easyedit runs yt-dlp's JS challenges through Node, so Node must be on PATH. |
| "every download failed" | The clip is age-restricted: --cookies-from-browser chrome. Or pass the scene yourself with `--speech <file |
| The quote is dull, or the wrong scene | Both LLM routes were rate-limited and the heuristic ran. Check the log for quote (heuristic), then delete jobs/<movie>/quote.json and run again. |
| Render dies on temp space | Disk capture needs ~9 MB per frame. easyedit already streams frames instead, so if you see this, something forced the old path - make sure PRODUCER_FORCE_SCREENSHOT is not set. |
| Render is killed / the machine thrashes | Lower EASYEDIT_PARALLEL to 1. Each section is a separate Chrome. |
| Captions stall on silence | The passage spans dead air. MAX_GAP in quote.py controls how much is allowed. |
| Black bars or a channel watermark survive | letterbox() in vision.py keeps only rows lit across the frame. Sources taller than 16:9 keep the top of the frame, so corner watermarks at the bottom get cropped off. If one still survives, exclude that shot in curate.json or crop the source yourself. |
| The montage is weak or repetitive | Run python -m easyedit.sheet "<movie>", then pin a sequence and exclude text cards in curate.json. |
easyedit/
__main__.py CLI and the per-stage cache keys
plan.py movie title -> scene / montage / music queries, palette, grade
fetch.py yt-dlp search + download (or your own files and URLs)
transcribe.py faster-whisper word timings
quote.py the passage to caption, its lines and emphasis words
vision.py frame sampling, picture-area detection, YuNet faces
shots.py scene cuts and how edit-worthy each shot is
beats.py