Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 31 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,36 @@

English | [中文](./README.zh-CN.md)

> **Privacy — update to 0.18.0 if you have ever run `capcut fixture`.** In every version up to and including 0.17.2, the bundle that command produces carries the `device_id`, `mac_address` and `hard_disk_id` CapCut stamps into your drafts. Only home paths and email addresses were redacted, and `SANITIZE_REPORT.json` wrote its own `source_dir` / `out_dir` unredacted, putting the username back. Because the documented flow is to attach that bundle to a public issue, following it published a stable device ID and MAC address while the filename and the report both said "sanitised". Fixed in 0.18.0 ([#59](https://github.com/renezander030/capcut-cli/issues/59)). **Treat any bundle generated by an earlier version as unsanitised.** `npm install -g capcut-cli@latest`.
**Create and edit real CapCut / JianYing projects from the terminal — or any LLM agent.**

> **Security — update to 0.17.1 or newer.** Versions up to and including 0.17.0 build the automation script behind `export --batch` by pasting the draft folder's name into it, so a folder named with the right characters can run commands of its own on macOS and Windows. Fixed in 0.17.1, together with an ffmpeg filter option injection reachable from a draft's caption colour (`render --burn-captions`), a `compile` spec whose `name` could write outside the draft store, predictable temp files on every draft write, and `serve` echoing credential values into its own output. Both injection paths need a draft folder or draft file you did not author, so the exposure is local rather than remote. `npm install -g capcut-cli@latest`. Details in the [changelog](./CHANGELOG.md).
Open the result in CapCut with every track still editable. capcut-cli works directly on the local draft store: JSON in, JSON out, with no upload, API, MCP server, or HTTP daemon.

`raw recording` → `silence-aware cuts + styled captions` → `editable CapCut / JianYing draft`

[**▶ Watch a captioned output example (60 seconds)**](./media/two-sisters-vietnam-short.mp4)

## Install and open your first editable draft

**Prerequisites:** Node ≥ 18 (built-ins only — no native modules). Optional tools unlock specific commands: Whisper for `caption`, FFmpeg for `render`, ffprobe for automatic media metadata, and `ANTHROPIC_API_KEY` for `translate`.

```bash
npm install -g capcut-cli
```

```bash
capcut doctor
capcut quickstart my-first --video clip.mp4 --srt captions.srt
capcut info ./my-first/ -H
```

**Result:** a real local project with video and captions on editable tracks — not a flattened export. Open it in CapCut or JianYing to review, adjust, and render. The publish click stays human.

Useful? [Star capcut-cli](https://github.com/renezander030/capcut-cli) to help other editors and agent builders find it.

Build from source instead: `git clone https://github.com/renezander030/capcut-cli && cd capcut-cli && npm install && npm run build` (then `npm link` to expose `capcut`). Or run any command without installing: `npx capcut-cli <command>`.

> [!IMPORTANT]
> **Upgrade before using older versions.** Fixture bundles made with versions up to 0.17.2 may contain stable device identifiers and must be treated as unsanitised ([#59](https://github.com/renezander030/capcut-cli/issues/59)). Versions up to 0.17.0 also contain local command/filter injection paths and unsafe temporary-file or credential-output behaviour. These issues are fixed in 0.18.0 and 0.17.1 respectively. Run `npm install -g capcut-cli@latest` and see the [changelog](./CHANGELOG.md) for full details.

> **Disclaimer:** This is an independent, community-maintained project. It is **not affiliated with, sponsored by, or endorsed by** CapCut, JianYing, or ByteDance Ltd. "CapCut" and "JianYing" (剪映) are trademarks of ByteDance Ltd. All product names, logos, and brands are the property of their respective owners and are used here only for identification (nominative) purposes.

Expand All @@ -28,30 +55,12 @@ JSON in, JSON out: every command reads and writes the local draft store directly
- **Library** — `import { loadDraft, lintDraft, saveDraft } from "capcut-cli"` (typed, zero-dep)
- **Queue runner** — `capcut serve` reads JSONL jobs from stdin, for [n8n / Make / Coze](./examples/serve-automation.md)

## Release notes

> **New in v0.20.0:** subtitles now carry their styling across the draft boundary in both directions — `export-ass` writes `[V4+ Styles]`, per-range override tags and `--karaoke` word timing, and `import-ass` keeps inline bold/italic/colour/size spans instead of flattening them to plain text, pinned by a round-trip test. The raw-recording pipeline closes: `detect-silence` finds dead air (with a `--pad` so no word gets clipped mid-syllable) and `tts` voices a script through any local TTS tool (piper, `say`, espeak-ng) straight onto an audio track. `render` finishes 0.19.0's fail-fast work — the audio filter chain is probed like the video chain ([#91](https://github.com/renezander030/capcut-cli/issues/91)) — and `--encoder` unlocks hardware encoders. Plus `harvest-enums --sync`/`--add` for the whole library, and `diagnose` now captures sanitized evidence for the open store-layout questions ([#50](https://github.com/renezander030/capcut-cli/issues/50)). No command was removed and no existing flag changed meaning. Full details in the [changelog](./CHANGELOG.md).

> **New in v0.19.1:** every multi-range text highlight was being written past the end of the text it styled. `styles[].range` holds UTF-16 code units, not UTF-16LE bytes, so `text-ranges`, `caption --karaoke`, `--highlight-words` and any preset carrying `text_ranges` stored offsets twice as large as they should be — a plain `add-text` looked fine only because a full-span range clamps back to the end of the text ([#85](https://github.com/renezander030/capcut-cli/issues/85), measured by [@hillimited](https://github.com/hillimited) across 38 app-authored drafts). Fixed everywhere those offsets are read or written, and `lint --fix` repairs drafts written by earlier versions (`text-range-doubled`). Full details in the [changelog](./CHANGELOG.md).

## Install

**Prerequisites:** Node ≥ 18 (built-ins only — no native modules). Optional tools unlock specific commands: Whisper for `caption`, FFmpeg for `render`, ffprobe for automatic media metadata, and `ANTHROPIC_API_KEY` for `translate`.

```bash
npm install -g capcut-cli # or: npx capcut-cli <command>
```

Build from source instead: `git clone https://github.com/renezander030/capcut-cli && cd capcut-cli && npm install && npm run build` (then `npm link` to expose `capcut`).

## Quickstart

```bash
capcut doctor # verify Node, FFmpeg, whisper, draft dirs
capcut quickstart my-first --video clip.mp4 # create + add input + lint, prints the "open in CapCut" step
capcut info ./my-first/ # inspect the draft (add -H for a table)
```

Then open the project in CapCut to review and render. Every short-video platform forbids automated upload, so the publish click stays human.

## Commands

JSON by default (pipe to `jq`); add `-H` for a human-readable table. Pass `--jianying` to use the JianYing enum namespace. Run `capcut <command> --help` for full flags.
Expand Down