Recut CLI
Auto-clip videos from supported websites (such as Kickstarter) into short social media videos with Chinese dubbing.
Point it at a project video page — Recut downloads the video, picks the most dynamic scenes by motion analysis, transcribes them with Whisper, writes a Chinese script with an LLM, dubs it with TTS, and burns in aligned subtitles. The output is a ready-to-post vertical video with a thumbnail intro.
▶ Watch the full demo (with audio)
Motivation
Combining the open-source ffmpeg library with LLMs and multimodal models, you can build many kinds of video workflows — and along the way, smaller models such as Whisper, edge-tts, and Coqui each have a role to play.
This is an automatic video-clipping CLI I built a while back, now open-sourced. Feel free to install and use it as-is, or take it as a starting point to build your own video workflow. Hope you find it helpful.
How it works
flowchart LR
A[Scrape project page] --> B[Download video]
B --> C[Scene & motion analysis]
C --> D[Whisper transcript]
D --> E[LLM writes Chinese script<br/>+ title + tags]
E --> F[TTS dubbing]
F --> G[Subtitle alignment]
G --> H[Thumbnail generation]
H --> I[Final composition]
Scene selection is motion-driven: fragments are scored by average pixel difference across sampled frames (with a duration penalty), so the final cut favors the most engaging footage instead of arbitrary segments.
Installation
pip install recut-cli
Or from source:
git clone https://github.com/windstudio/recutcli.git
cd recutcli
pip install .
Requirements
- Python 3.10+
- ffmpeg on your system:
- Windows:
winget install ffmpeg - macOS:
brew install ffmpeg - Linux:
apt install ffmpeg
- Windows:
- An OpenAI-compatible API key for script generation (see Configuration)
- Disk space:
openai-whisperpulls in PyTorch (~2 GB). On first run, the Whisper model is downloaded to~/.cache/whisper(~460 MB for the defaultsmallmodel).
Usage
recut https://kickstarter.com/projects/xxx -o output.mp4
Options
| Option | Description |
|---|---|
-o, --output |
Output video file path (auto-generated from URL if not specified) |
--platform |
Target platform: tiktok, instagram, reels (default: tiktok) |
--duration |
Video duration in seconds (default: 30) |
--scene-threshold |
Scene change sensitivity (default: 0.3) |
--video-url |
Direct video URL (mp4, avi, m3u8, etc.) - bypass Kickstarter scraping |
--chs-title |
Chinese title - skip LLM title generation |
--title |
English title from video page (optional, used for generating Chinese title) |
--image |
Main image URL or path for thumbnail generation |
--tts-engine |
TTS engine: edge, coqui, minimax (default: edge) |
--pause-on-chs-script |
Pause after generating Chinese script for user review |
--resume |
Resume from checkpoint (directory or .md file path) |
--no-overwrite |
Fail if the output file already exists instead of overwriting |
Examples
Basic usage:
recut https://kickstarter.com/projects/xxx -o output.mp4
With custom Chinese title and cover image:
recut https://kickstarter.com/projects/xxx -o output.mp4 \
--chs-title "无狠活黑科技\n无狠活,不尬吹,只讲真东西" \
--image "https://example.com/product.jpg"
With direct video URL:
recut https://kickstarter.com/projects/xxx -o output.mp4 \
--video-url "https://example.com/video.mp4"
Modes
Recut CLI supports two workflow modes:
Automatic Mode (default): Runs end-to-end without interruption. Best for batch processing.
Semi-Automatic Mode: Pauses after generating the Chinese script for user review. Use --pause-on-chs-script to enable:
recut https://kickstarter.com/projects/xxx -o output.mp4 --pause-on-chs-script
This pauses before TTS generation, allowing you to:
- Review and edit the generated Chinese script in
output/output.md - Edit scene selections in
output/output_scenes.json - Resume when ready:
recut --resume output/orrecut --resume output/output.md
Resume Workflow
When resuming from a paused checkpoint:
# First run - pauses after script generation
recut https://kickstarter.com/projects/xxx -o output.mp4 --pause-on-chs-script
# Edit the script and scenes as needed
# output/output.md - Chinese script (title, transcript, tags)
# output/output_scenes.json - Scene timestamps with motion scores (motion_intensity)
# Resume processing
recut --resume output/
The motion_intensity in scenes.json represents motion intensity (×100). Higher values indicate more dynamic content. You can manually adjust scene selections by editing this file.
You can also resume from the .md file directly:
recut --resume output/output.md
Output Structure
Running recut https://kickstarter.com/projects/xxx/sample-project -o sample.mp4 generates:
output/
├── sample.mp4 # Final video with Chinese dubbing and subtitles
├── sample.md # Chinese script with title, transcript, tags, and source URL
└── sample/ # Intermediate files
├── sample_metadata.json # Checkpoint metadata for resume
├── sample_scenes.json # Scene timestamps for video cutting
├── sample_script.md # English transcript
├── sample_dubbing.wav # TTS-generated Chinese audio
├── sample_nodub.mp4 # Short video without dubbing
├── sample.srt # Subtitle file
├── sample_raw.mp4 # Original downloaded video
└── sample_thumb.jpg # Thumbnail with Chinese title
Video Features
- Smart Fragment Selection: Uses motion detection to select the most dynamic video segments. Fragments with higher motion intensity are prioritized, ensuring the final video captures the most engaging content.
- Thumbnail Intro: The first 0.5 seconds show a thumbnail with the Chinese title before the video content
- Slanted Poster Thumbnail: Thumbnails feature a slanted image mask, gradient background, and skewed title text
- Logo Overlay: If configured, a logo is displayed in the top-left corner throughout the video
- Subtitles: When a thumbnail intro is present, subtitles are delayed 0.5s so they don't show during the thumbnail display
Getting the video URL manually
If Kickstarter blocks direct requests (403 error), grab the video URL from your browser instead:
- Open the Kickstarter page in your browser
- Open developer tools (F12) → Network tab
- Filter for
m3u8ormp4and copy the URL - Run with
--video-url:
recut https://kickstarter.com/projects/xxx -o output.mp4 \
--video-url "https://v2.kickstarter.com/..."
Browser extension (coming soon)
A companion Chrome extension is in the works: it grabs a video's download URL, cover image, and title from the page with one click, then assembles a ready-to-paste recut command for you. It will be open-sourced under the same account and linked here once released.
Configuration
Create a .env file in the project directory (see .env.example):
# LLM Configuration (required) — any OpenAI-compatible API works
LLM_API_KEY=your_api_key_here
LLM_API_URL=https://api.openai.com/v1
LLM_MODEL=gpt-4o-mini
# TTS Configuration (optional)
TTS_ENGINE=edge
TTS_VOICE=zh-CN-XiaoxiaoNeural
WHISPER_MODEL=small
# Thumbnail Configuration (optional)
THUMBNAIL_FONT=/path/to/chinese-font.ttf
THUMBNAIL_LOGO_PATH=material/logo.png
THUMBNAIL_FONT_SIZE_TITLE=72
LLM Configuration
The tool supports any OpenAI-compatible API:
- LLM_API_KEY - Your API key (required)
- LLM_API_URL - API endpoint URL (default:
https://api.openai.com/v1) - LLM_MODEL - Model name (default:
gpt-4o-mini)
For China-based users, point these at a domestic OpenAI-compatible endpoint, e.g. Yuanjing MaaS (https://maas-api.ai-yuanjing.com/openapi/compatible-mode/v1, model glm-5) or any other compatible provider.
TTS Engines
- edge (default) - Microsoft Edge TTS, high quality Chinese voice
- coqui - Open-source TTS (requires Python 3.9-3.11, install with
pip install "recut-cli[tts-coqui]") - minimax - MiniMax cloud TTS API, high quality Chinese voice
Each TTS engine has a different speaking speed. The tool automatically adjusts the Chinese script length to match the target duration:
| Engine | Character Rate | Target chars for 30s video |
|---|---|---|
| edge | 3.5 chars/sec | ~105 chars |
| minimax | 4.5 chars/sec | ~135 chars |
| coqui | 3.5 chars/sec | ~105 chars |
Additionally, if the dubbing duration is shorter than the target, the tool automatically selects more video fragments to ensure the final video meets the target duration.
MiniMax Configuration
To use MiniMax TTS, set these environment variables:
MINIMAX_API_KEY=your-api-key
MINIMAX_API_URL=https://api.minimaxi.com/v1/t2a_v2
MINIMAX_VOICE_ID=moss_audio_ce44fc67-7ce3-11f0-8de5-96e35d26fb85
Get your API key from MiniMax Platform.
Note: MiniMax TTS uses volume level 3.0 (default is 1.0) for better audio output.
Thumbnail Configuration
Configure thumbnail generation with these environment variables:
# Chinese font for title display (auto-detected if not set)
THUMBNAIL_FONT=/path/to/font.ttf
# Optional: Default fonts to search (comma-separated, auto-detection)
THUMBNAIL_DEFAULT_FONTS=ZCOOLGaoDuanHei-Regular.ttf,NotoSansSC-Bold.ttf
# Optional: Font sizes
THUMBNAIL_FONT_SIZE_TITLE=72
THUMBNAIL_FONT_SIZE_SUBTITLE=14
# Optional: Logo to overlay throughout video (top-left corner, 70% opacity)
THUMBNAIL_LOGO_PATH=material/logo.png
# Optional: Outro video to append at the end
THUMBNAIL_OUTRO_PATH=material/outro.mp4
Font Setup: The tool auto-detects Chinese fonts (Zcool GaoDuanHei, Noto Sans SC, Source Han Sans, SimHei, etc.). For custom fonts, set THUMBNAIL_FONT to the font file path.
Logo: When THUMBNAIL_LOGO_PATH is set, the logo image will be overlaid on the entire video (not on the thumbnail image itself, to avoid overlap).
Outro Video: When THUMBNAIL_OUTRO_PATH is set and the file exists, the outro video will be appended to the final video. The outro keeps its original audio. No subtitles or logo overlay are applied to the outro.
Disclaimer
This tool downloads and remixes third-party content. You are responsible for making sure your use of the source material and the resulting videos complies with the content owners' rights and the terms of service of the platforms you publish to.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file recut_cli-0.1.1.tar.gz.
File metadata
- Download URL: recut_cli-0.1.1.tar.gz
- Upload date:
- Size: 50.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9dc4ff726d06790296f166024dffb335fa790eb9818adb31a446e16738c1f9c9
|
|
| MD5 |
183420aa505d59e5c50a81baa929fedc
|
|
| BLAKE2b-256 |
c798093213b9e25088ca33fb2a36b4837d74dae053ce14af8611a8baacd41228
|
Provenance
The following attestation bundles were made for recut_cli-0.1.1.tar.gz:
Publisher:
publish.yml on windstudio/recutcli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
recut_cli-0.1.1.tar.gz -
Subject digest:
9dc4ff726d06790296f166024dffb335fa790eb9818adb31a446e16738c1f9c9 - Sigstore transparency entry: 2584846660
- Sigstore integration time:
-
Permalink:
windstudio/recutcli@31fe5631e876d94646f5cf4b422b4b61cb7b5c03 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/windstudio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@31fe5631e876d94646f5cf4b422b4b61cb7b5c03 -
Trigger Event:
push
-
Statement type:
File details
Details for the file recut_cli-0.1.1-py3-none-any.whl.
File metadata
- Download URL: recut_cli-0.1.1-py3-none-any.whl
- Upload date:
- Size: 40.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5050f4ac564592146414b25c3e963284f018cf8245ef3408921735d023afbeee
|
|
| MD5 |
b6249a8a25f8bf3594455e401711f7a1
|
|
| BLAKE2b-256 |
09541a2aa74e538a20f844ca69ff57f5f47e21217dc2dcba075ae320c2e35c1c
|
Provenance
The following attestation bundles were made for recut_cli-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on windstudio/recutcli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
recut_cli-0.1.1-py3-none-any.whl -
Subject digest:
5050f4ac564592146414b25c3e963284f018cf8245ef3408921735d023afbeee - Sigstore transparency entry: 2584847448
- Sigstore integration time:
-
Permalink:
windstudio/recutcli@31fe5631e876d94646f5cf4b422b4b61cb7b5c03 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/windstudio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@31fe5631e876d94646f5cf4b422b4b61cb7b5c03 -
Trigger Event:
push
-
Statement type: