DownVid
1000개 이상의 사이트를 지원하고, 인터페이스가 간결하며 macOS·Windows·Linux에서 모두 사용 가능
코드 기반 영상 편집기 LLM이 TSX 파일을 생성하면 CutCraft가 연산·재생·편집·내보내기를 수행한다
Video editor as code: LLMs write code well and math badly, so a model writes a TSX file of words and shots, and CutCraft does the arithmetic, plays it in the browser, edits it and exports it.
미디어TypeScript · JavaScriptGitHub @prefix-tree온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗export const schema = z.object({ product: z.string(), accent: z.string() });
export const defaults = { product: "Shed", accent: "#ff5a1f" };
export default function Video({ product, accent }: z.infer<typeof schema>) {
return (
<Composition fps={30} width={1920} height={1080}>
<Track id="main">
<Clip id="hook" src="asset:founder" in="word:12" out="word:23.end" />
<Transition id="x1" type="crossfade" duration={0.4} />
<Clip id="broll" src="asset:product" in="shot:1" out="shot:1.end" fit="cover" />
</Track>
<Track id="overlays">
<Title id="title" anchor="hook" at="word:14" duration={2.8} color={accent}>{product}</Title>
</Track>
<Track id="music" layout="free">
<Audio id="bed" src="asset:music" start={0} duration="fill" volume={0.35} duck={{ under: "main", to: 0.15 }} />
</Track>
</Composition>
);
}
Drag the end of hook in the timeline and one token in the file changes. The b-roll moves up behind it, the title
stays on the word it was timed to, and the music still runs to the end. Whoever opens the file next, a person or a
model, reads the edit as ordinary code.
Language models write code well and do arithmetic badly. A cut written as 8.43 seconds can land in the middle of a
word; a cut written as word:12 lands on it. CutCraft lets the file say what it means (this word, that shot) and does
the math itself.
The timeline part of the file (tracks, clips, transitions, captions) uses elements with literal ids, so an editor
gesture can find the element it touched and change one value. Anything you draw on top can be free code: a
<Layer> holds any React, CSS, canvas or three.js you write.
And all of it should be free to use. A player, an editor that writes back to the file, a frame-exact export and a layout check are what a product built on video needs, and they belong under a licence that costs it nothing. CutCraft is MIT: no paid tier, no licence key, no watermark. The projects closest to it ask for something: Remotion's licence has a paid tier for companies, and Diffusion Studio's engine stamps a watermark on every frame without a licence key. Building on either would have carried those terms into everything made with CutCraft, so it is written from scratch, on open libraries (React, zod, three.js, Motion, and Mediabunny, which is MPL-2.0 and stays so for its own files).
You aren't limited to the built-in titles and graphics. A <Layer> takes any React component, with hooks, CSS 3D
transforms, filters, blend modes, a canvas or WebGL. <Three> and <Motion> bring three.js
and Motion onto the timeline:
<Three id="cube" anchor="hook" at="word:14" duration={4}
camera={{ position: [0, 0, 5], fov: 40 }} background="#101010"
setup={({ scene, THREE }) => {
const cube = new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshNormalMaterial());
scene.add(cube);
return ({ time }) => { cube.rotation.set(time * 0.6, time, 0); };
}}
/>
<Layer id="card" anchor="hook" at="word:20" duration={3}>
<FlipCard front="Before" back="After" /> {/* your own component: useT() gives the time */}
</Layer>
All of it runs on the video's clock. Scrub backwards, seek, or play at 2×, and a three.js scene, a Motion sequence or a CSS animation shows exactly the frame for that time. These layers are still timeline elements, so the editor moves, trims and anchors them to words like everything else; only what they draw is up to you.
@cutcraft/graphics has the host setup, and
Free code has the details.
The player draws all of this, and so does the export, which runs the real player in headless Chrome, frame by frame,
with the same sound
(exporting).
| Elements | Tracks (a magnetic sequence or free placement), clips trimmed by seconds, words or shots, transitions, titles, shapes, SVG, stickers, built-in graphics, captions, markers, masks, adjustment layers, keyframes, speed ramps, freeze frames, nested compositions and multicam. <Layer> takes any React. |
| Time by meaning | in="word:12", out="shot:3.end", and overlays pinned to a word of the clip that says it (anchor="hook" at="word:14"), so cuts and graphics follow every trim. |
| Editing | 119 actions, each with validation and undo. Every edit is written back into the file as the smallest text change. |
| Lint | Checks the file before anything plays: literal ids, cuts inside words, fonts and declarations, and the few limits listed in what renders. |
| Player | A React <Player> and a framework-free PlayerCore: WebCodecs decoding through mediabunny, one canvas for footage, DOM for overlays, Web Audio as the clock, and frame-exact seeking. |
| Export | The player itself, in headless Chrome that the first export downloads: MP4 (H.264 or AV1), WebM (VP9 or AV1), MP3 or WAV soundtracks, and PNG or JPEG stills. Everything the preview draws exports: three.js, Motion, motion blur and GLSL effects of the file's own included. A layout check reports overlays that leave the frame or the safe zone, or cover the captions or the subject, at their line in the file. |
A first video needs no footage. Save this as hello.tsx:
import { Composition, Shape, Title, Track } from "@cutcraft/kit";
export const manifest = { assets: {} }; // no footage yet
export default function Video() {
return (
<Composition fps={30} width={1280} height={720}>
<Track id="text" layout="free">
<Shape id="card" start={0} duration={3} shape="rectangle" width={760} height={220} style="card" />
<Title id="hello" start={0.3} duration={2.5} style="h1" animation={{ preset: "word-by-word" }}>Hello, video</Title>
</Track>
</Composition>
);
}
npm install cutcraft @cutcraft/kit react zod # the CLI, and types for the file
npx cutcraft hello.tsx --out hello.mp4 # or .webm, a .png still with --still 1
The quick start then adds your own footage, cuts on words, and three.js and Motion, one step at a time. Examples shows which file to start from for what you're making.
To render the examples from this repository you need Node 22.19 or later, pnpm 10 (corepack enable), and ffmpeg
with the drawtext filter for the placeholder footage. The first render downloads Chrome for Testing:
pnpm install
pnpm --filter @cutcraft/example-showcase gen # placeholder footage
pnpm --filter @cutcraft/example-showcase render # the showcase videos, into docs/public/showcase
pnpm --filter @cutcraft/example-launch-recap gen # the walkthrough's footage
pnpm --filter @cutcraft/example-launch-recap dev # the walkthrough in a player, http://localhost:5180
pnpm docs:dev # the documentation site
| Package | What it is |
|---|---|
cutcraft | The command line: export a file to video, audio or a still, or check its layout. |
@cutcraft/kit | The elements, time references, resolver, editor actions, source edits and lint. No DOM. |
@cutcraft/player | The browser player and the React <Player>. |
@cutcraft/render | The export as a library: loadVideo and renderVideo, driving the player in headless Chrome. |
@cutcraft/graphics | three.js and Motion on the video's clock for <Three> and <Motion>, and the 34 <Graphic> kinds, which are deprecated and will be removed. |
The repository also holds eight recipes (complete files for common videos, each tested) and the worked example.
| Works | Resolving, every editor action with undo, writing edits back to the file, lint. Playback with seek, rate and loop; crossfade, dip, wipe, slide and push transitions; keyframes on transforms, effects, colour and sound; speed ramps and freeze frames with their audio; masks, overlays, captions and ducking. Export with frame-exact pictures, and the layout check. |
| Partial | Six transitions, fourteen effects and nine title presets, all drawn: what the schemas accept is what renders, with a few limits listed in what renders. |
useClipFrame(clipId) will hand a clip's current frame to a <Layer>, for CSS 3D or a
shader of your own.CONTRIBUTING.md covers setup, where things live, and how to add an element or an action. Please report security issues privately as SECURITY.md describes, and follow the code of conduct.
MIT.