recut-cli 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- recut_cli-0.1.2/LICENSE +21 -0
- recut_cli-0.1.2/PKG-INFO +325 -0
- recut_cli-0.1.2/README.md +285 -0
- recut_cli-0.1.2/pyproject.toml +53 -0
- recut_cli-0.1.2/recut/__init__.py +3 -0
- recut_cli-0.1.2/recut/analyzer.py +320 -0
- recut_cli-0.1.2/recut/checkpoint.py +138 -0
- recut_cli-0.1.2/recut/cli.py +566 -0
- recut_cli-0.1.2/recut/config.py +180 -0
- recut_cli-0.1.2/recut/downloader.py +113 -0
- recut_cli-0.1.2/recut/editor.py +334 -0
- recut_cli-0.1.2/recut/scraper.py +35 -0
- recut_cli-0.1.2/recut/subtitle.py +210 -0
- recut_cli-0.1.2/recut/thumbnail.py +417 -0
- recut_cli-0.1.2/recut/transcriber.py +88 -0
- recut_cli-0.1.2/recut/translator.py +406 -0
- recut_cli-0.1.2/recut/tts.py +192 -0
- recut_cli-0.1.2/recut_cli.egg-info/PKG-INFO +325 -0
- recut_cli-0.1.2/recut_cli.egg-info/SOURCES.txt +33 -0
- recut_cli-0.1.2/recut_cli.egg-info/dependency_links.txt +1 -0
- recut_cli-0.1.2/recut_cli.egg-info/entry_points.txt +2 -0
- recut_cli-0.1.2/recut_cli.egg-info/requires.txt +16 -0
- recut_cli-0.1.2/recut_cli.egg-info/top_level.txt +1 -0
- recut_cli-0.1.2/setup.cfg +4 -0
- recut_cli-0.1.2/tests/test_analyzer.py +84 -0
- recut_cli-0.1.2/tests/test_cli.py +112 -0
- recut_cli-0.1.2/tests/test_cli_integration.py +157 -0
- recut_cli-0.1.2/tests/test_config.py +167 -0
- recut_cli-0.1.2/tests/test_downloader.py +210 -0
- recut_cli-0.1.2/tests/test_editor.py +90 -0
- recut_cli-0.1.2/tests/test_scraper.py +56 -0
- recut_cli-0.1.2/tests/test_subtitle.py +169 -0
- recut_cli-0.1.2/tests/test_transcriber.py +73 -0
- recut_cli-0.1.2/tests/test_translator.py +388 -0
- recut_cli-0.1.2/tests/test_tts.py +174 -0
recut_cli-0.1.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 windstudio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
recut_cli-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: recut-cli
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Auto-clip videos from the web into short social media videos with Chinese dubbing
|
|
5
|
+
Author: windstudio
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/windstudio/recutcli
|
|
8
|
+
Project-URL: Repository, https://github.com/windstudio/recutcli
|
|
9
|
+
Project-URL: Issues, https://github.com/windstudio/recutcli/issues
|
|
10
|
+
Keywords: video,kickstarter,shorts,dubbing,subtitle,whisper,tts
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Natural Language :: Chinese (Simplified)
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Multimedia :: Video
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: click>=8.0.0
|
|
26
|
+
Requires-Dist: requests>=2.28.0
|
|
27
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
28
|
+
Requires-Dist: imageio-ffmpeg>=0.4.0
|
|
29
|
+
Requires-Dist: numpy>=1.24.0
|
|
30
|
+
Requires-Dist: openai-whisper>=20250625
|
|
31
|
+
Requires-Dist: openai>=1.0.0
|
|
32
|
+
Requires-Dist: edge-tts>=7.2.7
|
|
33
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
34
|
+
Requires-Dist: Pillow>=10.0.0
|
|
35
|
+
Provides-Extra: tts-coqui
|
|
36
|
+
Requires-Dist: TTS>=0.22.0; extra == "tts-coqui"
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# Recut CLI
|
|
42
|
+
|
|
43
|
+
[](https://github.com/windstudio/recutcli/actions/workflows/ci.yml)
|
|
44
|
+
[](LICENSE)
|
|
45
|
+
[](https://github.com/windstudio/recutcli/blob/main/pyproject.toml)
|
|
46
|
+
|
|
47
|
+
Auto-clip videos from supported websites (such as Kickstarter) into short social media videos with Chinese dubbing.
|
|
48
|
+
|
|
49
|
+
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.
|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
▶ **[Watch the full demo (with audio)](https://github.com/windstudio/recutcli/releases/download/v0.1.0/ClawStage.mp4)**
|
|
54
|
+
|
|
55
|
+
## Motivation
|
|
56
|
+
|
|
57
|
+
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.
|
|
58
|
+
|
|
59
|
+
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.
|
|
60
|
+
|
|
61
|
+
## How it works
|
|
62
|
+
|
|
63
|
+
```mermaid
|
|
64
|
+
flowchart LR
|
|
65
|
+
A[Scrape project page] --> B[Download video]
|
|
66
|
+
B --> C[Scene & motion analysis]
|
|
67
|
+
C --> D[Whisper transcript]
|
|
68
|
+
D --> E[LLM writes Chinese script<br/>+ title + tags]
|
|
69
|
+
E --> F[TTS dubbing]
|
|
70
|
+
F --> G[Subtitle alignment]
|
|
71
|
+
G --> H[Thumbnail generation]
|
|
72
|
+
H --> I[Final composition]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
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.
|
|
76
|
+
|
|
77
|
+
## Installation
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install recut-cli
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Or from source:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
git clone https://github.com/windstudio/recutcli.git
|
|
87
|
+
cd recutcli
|
|
88
|
+
pip install .
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Requirements
|
|
92
|
+
|
|
93
|
+
- **Python** 3.10+
|
|
94
|
+
- **ffmpeg** on your system:
|
|
95
|
+
- Windows: `winget install ffmpeg`
|
|
96
|
+
- macOS: `brew install ffmpeg`
|
|
97
|
+
- Linux: `apt install ffmpeg`
|
|
98
|
+
- **An OpenAI-compatible API key** for script generation (see [Configuration](#configuration))
|
|
99
|
+
- **Disk space**: `openai-whisper` pulls in PyTorch (~2 GB). On first run, the Whisper model is downloaded to `~/.cache/whisper` (~460 MB for the default `small` model).
|
|
100
|
+
|
|
101
|
+
## Usage
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Options
|
|
108
|
+
|
|
109
|
+
| Option | Description |
|
|
110
|
+
|--------|-------------|
|
|
111
|
+
| `-o, --output` | Output video file path (auto-generated from URL if not specified) |
|
|
112
|
+
| `--platform` | Target platform: tiktok, instagram, reels (default: tiktok) |
|
|
113
|
+
| `--duration` | Video duration in seconds (default: 30) |
|
|
114
|
+
| `--scene-threshold` | Scene change sensitivity (default: 0.3) |
|
|
115
|
+
| `--video-url` | Direct video URL (mp4, avi, m3u8, etc.) - bypass Kickstarter scraping |
|
|
116
|
+
| `--chs-title` | Chinese title - skip LLM title generation |
|
|
117
|
+
| `--title` | English title from video page (optional, used for generating Chinese title) |
|
|
118
|
+
| `--image` | Main image URL or path for thumbnail generation |
|
|
119
|
+
| `--tts-engine` | TTS engine: edge, coqui, minimax (default: edge) |
|
|
120
|
+
| `--pause-on-chs-script` | Pause after generating Chinese script for user review |
|
|
121
|
+
| `--resume` | Resume from checkpoint (directory or .md file path) |
|
|
122
|
+
| `--no-overwrite` | Fail if the output file already exists instead of overwriting |
|
|
123
|
+
|
|
124
|
+
### Examples
|
|
125
|
+
|
|
126
|
+
Basic usage:
|
|
127
|
+
```bash
|
|
128
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
With custom Chinese title and cover image:
|
|
132
|
+
```bash
|
|
133
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 \
|
|
134
|
+
--chs-title "无狠活黑科技\n无狠活,不尬吹,只讲真东西" \
|
|
135
|
+
--image "https://example.com/product.jpg"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
With direct video URL:
|
|
139
|
+
```bash
|
|
140
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 \
|
|
141
|
+
--video-url "https://example.com/video.mp4"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Modes
|
|
145
|
+
|
|
146
|
+
Recut CLI supports two workflow modes:
|
|
147
|
+
|
|
148
|
+
**Automatic Mode** (default): Runs end-to-end without interruption. Best for batch processing.
|
|
149
|
+
|
|
150
|
+
**Semi-Automatic Mode**: Pauses after generating the Chinese script for user review. Use `--pause-on-chs-script` to enable:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 --pause-on-chs-script
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
This pauses before TTS generation, allowing you to:
|
|
157
|
+
1. Review and edit the generated Chinese script in `output/output.md`
|
|
158
|
+
2. Edit scene selections in `output/output_scenes.json`
|
|
159
|
+
3. Resume when ready: `recut --resume output/` or `recut --resume output/output.md`
|
|
160
|
+
|
|
161
|
+
### Resume Workflow
|
|
162
|
+
|
|
163
|
+
When resuming from a paused checkpoint:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# First run - pauses after script generation
|
|
167
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 --pause-on-chs-script
|
|
168
|
+
|
|
169
|
+
# Edit the script and scenes as needed
|
|
170
|
+
# output/output.md - Chinese script (title, transcript, tags)
|
|
171
|
+
# output/output_scenes.json - Scene timestamps with motion scores (motion_intensity)
|
|
172
|
+
|
|
173
|
+
# Resume processing
|
|
174
|
+
recut --resume output/
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
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.
|
|
178
|
+
|
|
179
|
+
You can also resume from the .md file directly:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
recut --resume output/output.md
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Output Structure
|
|
186
|
+
|
|
187
|
+
Running `recut https://kickstarter.com/projects/xxx/sample-project -o sample.mp4` generates:
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
output/
|
|
191
|
+
├── sample.mp4 # Final video with Chinese dubbing and subtitles
|
|
192
|
+
├── sample.md # Chinese script with title, transcript, tags, and source URL
|
|
193
|
+
└── sample/ # Intermediate files
|
|
194
|
+
├── sample_metadata.json # Checkpoint metadata for resume
|
|
195
|
+
├── sample_scenes.json # Scene timestamps for video cutting
|
|
196
|
+
├── sample_script.md # English transcript
|
|
197
|
+
├── sample_dubbing.wav # TTS-generated Chinese audio
|
|
198
|
+
├── sample_nodub.mp4 # Short video without dubbing
|
|
199
|
+
├── sample.srt # Subtitle file
|
|
200
|
+
├── sample_raw.mp4 # Original downloaded video
|
|
201
|
+
└── sample_thumb.jpg # Thumbnail with Chinese title
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Video Features
|
|
205
|
+
|
|
206
|
+
- **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.
|
|
207
|
+
- **Thumbnail Intro**: The first 0.5 seconds show a thumbnail with the Chinese title before the video content
|
|
208
|
+
- **Slanted Poster Thumbnail**: Thumbnails feature a slanted image mask, gradient background, and skewed title text
|
|
209
|
+
- **Logo Overlay**: If configured, a logo is displayed in the top-left corner throughout the video
|
|
210
|
+
- **Subtitles**: When a thumbnail intro is present, subtitles are delayed 0.5s so they don't show during the thumbnail display
|
|
211
|
+
|
|
212
|
+
## Getting the video URL manually
|
|
213
|
+
|
|
214
|
+
If Kickstarter blocks direct requests (403 error), grab the video URL from your browser instead:
|
|
215
|
+
|
|
216
|
+
1. Open the Kickstarter page in your browser
|
|
217
|
+
2. Open developer tools (F12) → Network tab
|
|
218
|
+
3. Filter for `m3u8` or `mp4` and copy the URL
|
|
219
|
+
4. Run with `--video-url`:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 \
|
|
223
|
+
--video-url "https://v2.kickstarter.com/..."
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Browser extension (coming soon)
|
|
227
|
+
|
|
228
|
+
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.
|
|
229
|
+
|
|
230
|
+
## Configuration
|
|
231
|
+
|
|
232
|
+
Create a `.env` file in the project directory (see [.env.example](https://github.com/windstudio/recutcli/blob/main/.env.example)):
|
|
233
|
+
|
|
234
|
+
```env
|
|
235
|
+
# LLM Configuration (required) — any OpenAI-compatible API works
|
|
236
|
+
LLM_API_KEY=your_api_key_here
|
|
237
|
+
LLM_API_URL=https://api.openai.com/v1
|
|
238
|
+
LLM_MODEL=gpt-4o-mini
|
|
239
|
+
|
|
240
|
+
# TTS Configuration (optional)
|
|
241
|
+
TTS_ENGINE=edge
|
|
242
|
+
TTS_VOICE=zh-CN-XiaoxiaoNeural
|
|
243
|
+
WHISPER_MODEL=small
|
|
244
|
+
|
|
245
|
+
# Thumbnail Configuration (optional)
|
|
246
|
+
THUMBNAIL_FONT=/path/to/chinese-font.ttf
|
|
247
|
+
THUMBNAIL_LOGO_PATH=material/logo.png
|
|
248
|
+
THUMBNAIL_FONT_SIZE_TITLE=72
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### LLM Configuration
|
|
252
|
+
|
|
253
|
+
The tool supports any OpenAI-compatible API:
|
|
254
|
+
|
|
255
|
+
- **LLM_API_KEY** - Your API key (required)
|
|
256
|
+
- **LLM_API_URL** - API endpoint URL (default: `https://api.openai.com/v1`)
|
|
257
|
+
- **LLM_MODEL** - Model name (default: `gpt-4o-mini`)
|
|
258
|
+
|
|
259
|
+
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.
|
|
260
|
+
|
|
261
|
+
### TTS Engines
|
|
262
|
+
|
|
263
|
+
- **edge** (default) - Microsoft Edge TTS, high quality Chinese voice
|
|
264
|
+
- **coqui** - Open-source TTS (requires Python 3.9-3.11, install with `pip install "recut-cli[tts-coqui]"`)
|
|
265
|
+
- **minimax** - MiniMax cloud TTS API, high quality Chinese voice
|
|
266
|
+
|
|
267
|
+
Each TTS engine has a different speaking speed. The tool automatically adjusts the Chinese script length to match the target duration:
|
|
268
|
+
|
|
269
|
+
| Engine | Character Rate | Target chars for 30s video |
|
|
270
|
+
|--------|---------------|----------------------------|
|
|
271
|
+
| edge | 3.5 chars/sec | ~105 chars |
|
|
272
|
+
| minimax | 4.5 chars/sec | ~135 chars |
|
|
273
|
+
| coqui | 3.5 chars/sec | ~105 chars |
|
|
274
|
+
|
|
275
|
+
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.
|
|
276
|
+
|
|
277
|
+
### MiniMax Configuration
|
|
278
|
+
|
|
279
|
+
To use MiniMax TTS, set these environment variables:
|
|
280
|
+
|
|
281
|
+
```env
|
|
282
|
+
MINIMAX_API_KEY=your-api-key
|
|
283
|
+
MINIMAX_API_URL=https://api.minimaxi.com/v1/t2a_v2
|
|
284
|
+
MINIMAX_VOICE_ID=moss_audio_ce44fc67-7ce3-11f0-8de5-96e35d26fb85
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Get your API key from [MiniMax Platform](https://platform.minimaxi.com).
|
|
288
|
+
|
|
289
|
+
**Note**: MiniMax TTS uses volume level 3.0 (default is 1.0) for better audio output.
|
|
290
|
+
|
|
291
|
+
### Thumbnail Configuration
|
|
292
|
+
|
|
293
|
+
Configure thumbnail generation with these environment variables:
|
|
294
|
+
|
|
295
|
+
```env
|
|
296
|
+
# Chinese font for title display (auto-detected if not set)
|
|
297
|
+
THUMBNAIL_FONT=/path/to/font.ttf
|
|
298
|
+
|
|
299
|
+
# Optional: Default fonts to search (comma-separated, auto-detection)
|
|
300
|
+
THUMBNAIL_DEFAULT_FONTS=ZCOOLGaoDuanHei-Regular.ttf,NotoSansSC-Bold.ttf
|
|
301
|
+
|
|
302
|
+
# Optional: Font sizes
|
|
303
|
+
THUMBNAIL_FONT_SIZE_TITLE=72
|
|
304
|
+
THUMBNAIL_FONT_SIZE_SUBTITLE=14
|
|
305
|
+
|
|
306
|
+
# Optional: Logo to overlay throughout video (top-left corner, 70% opacity)
|
|
307
|
+
THUMBNAIL_LOGO_PATH=material/logo.png
|
|
308
|
+
|
|
309
|
+
# Optional: Outro video to append at the end
|
|
310
|
+
THUMBNAIL_OUTRO_PATH=material/outro.mp4
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**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.
|
|
314
|
+
|
|
315
|
+
**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).
|
|
316
|
+
|
|
317
|
+
**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.
|
|
318
|
+
|
|
319
|
+
## Disclaimer
|
|
320
|
+
|
|
321
|
+
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.
|
|
322
|
+
|
|
323
|
+
## License
|
|
324
|
+
|
|
325
|
+
[MIT](https://github.com/windstudio/recutcli/blob/main/LICENSE)
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Recut CLI
|
|
2
|
+
|
|
3
|
+
[](https://github.com/windstudio/recutcli/actions/workflows/ci.yml)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://github.com/windstudio/recutcli/blob/main/pyproject.toml)
|
|
6
|
+
|
|
7
|
+
Auto-clip videos from supported websites (such as Kickstarter) into short social media videos with Chinese dubbing.
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
▶ **[Watch the full demo (with audio)](https://github.com/windstudio/recutcli/releases/download/v0.1.0/ClawStage.mp4)**
|
|
14
|
+
|
|
15
|
+
## Motivation
|
|
16
|
+
|
|
17
|
+
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.
|
|
18
|
+
|
|
19
|
+
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.
|
|
20
|
+
|
|
21
|
+
## How it works
|
|
22
|
+
|
|
23
|
+
```mermaid
|
|
24
|
+
flowchart LR
|
|
25
|
+
A[Scrape project page] --> B[Download video]
|
|
26
|
+
B --> C[Scene & motion analysis]
|
|
27
|
+
C --> D[Whisper transcript]
|
|
28
|
+
D --> E[LLM writes Chinese script<br/>+ title + tags]
|
|
29
|
+
E --> F[TTS dubbing]
|
|
30
|
+
F --> G[Subtitle alignment]
|
|
31
|
+
G --> H[Thumbnail generation]
|
|
32
|
+
H --> I[Final composition]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
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.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install recut-cli
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or from source:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git clone https://github.com/windstudio/recutcli.git
|
|
47
|
+
cd recutcli
|
|
48
|
+
pip install .
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Requirements
|
|
52
|
+
|
|
53
|
+
- **Python** 3.10+
|
|
54
|
+
- **ffmpeg** on your system:
|
|
55
|
+
- Windows: `winget install ffmpeg`
|
|
56
|
+
- macOS: `brew install ffmpeg`
|
|
57
|
+
- Linux: `apt install ffmpeg`
|
|
58
|
+
- **An OpenAI-compatible API key** for script generation (see [Configuration](#configuration))
|
|
59
|
+
- **Disk space**: `openai-whisper` pulls in PyTorch (~2 GB). On first run, the Whisper model is downloaded to `~/.cache/whisper` (~460 MB for the default `small` model).
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Options
|
|
68
|
+
|
|
69
|
+
| Option | Description |
|
|
70
|
+
|--------|-------------|
|
|
71
|
+
| `-o, --output` | Output video file path (auto-generated from URL if not specified) |
|
|
72
|
+
| `--platform` | Target platform: tiktok, instagram, reels (default: tiktok) |
|
|
73
|
+
| `--duration` | Video duration in seconds (default: 30) |
|
|
74
|
+
| `--scene-threshold` | Scene change sensitivity (default: 0.3) |
|
|
75
|
+
| `--video-url` | Direct video URL (mp4, avi, m3u8, etc.) - bypass Kickstarter scraping |
|
|
76
|
+
| `--chs-title` | Chinese title - skip LLM title generation |
|
|
77
|
+
| `--title` | English title from video page (optional, used for generating Chinese title) |
|
|
78
|
+
| `--image` | Main image URL or path for thumbnail generation |
|
|
79
|
+
| `--tts-engine` | TTS engine: edge, coqui, minimax (default: edge) |
|
|
80
|
+
| `--pause-on-chs-script` | Pause after generating Chinese script for user review |
|
|
81
|
+
| `--resume` | Resume from checkpoint (directory or .md file path) |
|
|
82
|
+
| `--no-overwrite` | Fail if the output file already exists instead of overwriting |
|
|
83
|
+
|
|
84
|
+
### Examples
|
|
85
|
+
|
|
86
|
+
Basic usage:
|
|
87
|
+
```bash
|
|
88
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
With custom Chinese title and cover image:
|
|
92
|
+
```bash
|
|
93
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 \
|
|
94
|
+
--chs-title "无狠活黑科技\n无狠活,不尬吹,只讲真东西" \
|
|
95
|
+
--image "https://example.com/product.jpg"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
With direct video URL:
|
|
99
|
+
```bash
|
|
100
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 \
|
|
101
|
+
--video-url "https://example.com/video.mp4"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Modes
|
|
105
|
+
|
|
106
|
+
Recut CLI supports two workflow modes:
|
|
107
|
+
|
|
108
|
+
**Automatic Mode** (default): Runs end-to-end without interruption. Best for batch processing.
|
|
109
|
+
|
|
110
|
+
**Semi-Automatic Mode**: Pauses after generating the Chinese script for user review. Use `--pause-on-chs-script` to enable:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 --pause-on-chs-script
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This pauses before TTS generation, allowing you to:
|
|
117
|
+
1. Review and edit the generated Chinese script in `output/output.md`
|
|
118
|
+
2. Edit scene selections in `output/output_scenes.json`
|
|
119
|
+
3. Resume when ready: `recut --resume output/` or `recut --resume output/output.md`
|
|
120
|
+
|
|
121
|
+
### Resume Workflow
|
|
122
|
+
|
|
123
|
+
When resuming from a paused checkpoint:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# First run - pauses after script generation
|
|
127
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 --pause-on-chs-script
|
|
128
|
+
|
|
129
|
+
# Edit the script and scenes as needed
|
|
130
|
+
# output/output.md - Chinese script (title, transcript, tags)
|
|
131
|
+
# output/output_scenes.json - Scene timestamps with motion scores (motion_intensity)
|
|
132
|
+
|
|
133
|
+
# Resume processing
|
|
134
|
+
recut --resume output/
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
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.
|
|
138
|
+
|
|
139
|
+
You can also resume from the .md file directly:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
recut --resume output/output.md
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Output Structure
|
|
146
|
+
|
|
147
|
+
Running `recut https://kickstarter.com/projects/xxx/sample-project -o sample.mp4` generates:
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
output/
|
|
151
|
+
├── sample.mp4 # Final video with Chinese dubbing and subtitles
|
|
152
|
+
├── sample.md # Chinese script with title, transcript, tags, and source URL
|
|
153
|
+
└── sample/ # Intermediate files
|
|
154
|
+
├── sample_metadata.json # Checkpoint metadata for resume
|
|
155
|
+
├── sample_scenes.json # Scene timestamps for video cutting
|
|
156
|
+
├── sample_script.md # English transcript
|
|
157
|
+
├── sample_dubbing.wav # TTS-generated Chinese audio
|
|
158
|
+
├── sample_nodub.mp4 # Short video without dubbing
|
|
159
|
+
├── sample.srt # Subtitle file
|
|
160
|
+
├── sample_raw.mp4 # Original downloaded video
|
|
161
|
+
└── sample_thumb.jpg # Thumbnail with Chinese title
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Video Features
|
|
165
|
+
|
|
166
|
+
- **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.
|
|
167
|
+
- **Thumbnail Intro**: The first 0.5 seconds show a thumbnail with the Chinese title before the video content
|
|
168
|
+
- **Slanted Poster Thumbnail**: Thumbnails feature a slanted image mask, gradient background, and skewed title text
|
|
169
|
+
- **Logo Overlay**: If configured, a logo is displayed in the top-left corner throughout the video
|
|
170
|
+
- **Subtitles**: When a thumbnail intro is present, subtitles are delayed 0.5s so they don't show during the thumbnail display
|
|
171
|
+
|
|
172
|
+
## Getting the video URL manually
|
|
173
|
+
|
|
174
|
+
If Kickstarter blocks direct requests (403 error), grab the video URL from your browser instead:
|
|
175
|
+
|
|
176
|
+
1. Open the Kickstarter page in your browser
|
|
177
|
+
2. Open developer tools (F12) → Network tab
|
|
178
|
+
3. Filter for `m3u8` or `mp4` and copy the URL
|
|
179
|
+
4. Run with `--video-url`:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
recut https://kickstarter.com/projects/xxx -o output.mp4 \
|
|
183
|
+
--video-url "https://v2.kickstarter.com/..."
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Browser extension (coming soon)
|
|
187
|
+
|
|
188
|
+
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.
|
|
189
|
+
|
|
190
|
+
## Configuration
|
|
191
|
+
|
|
192
|
+
Create a `.env` file in the project directory (see [.env.example](https://github.com/windstudio/recutcli/blob/main/.env.example)):
|
|
193
|
+
|
|
194
|
+
```env
|
|
195
|
+
# LLM Configuration (required) — any OpenAI-compatible API works
|
|
196
|
+
LLM_API_KEY=your_api_key_here
|
|
197
|
+
LLM_API_URL=https://api.openai.com/v1
|
|
198
|
+
LLM_MODEL=gpt-4o-mini
|
|
199
|
+
|
|
200
|
+
# TTS Configuration (optional)
|
|
201
|
+
TTS_ENGINE=edge
|
|
202
|
+
TTS_VOICE=zh-CN-XiaoxiaoNeural
|
|
203
|
+
WHISPER_MODEL=small
|
|
204
|
+
|
|
205
|
+
# Thumbnail Configuration (optional)
|
|
206
|
+
THUMBNAIL_FONT=/path/to/chinese-font.ttf
|
|
207
|
+
THUMBNAIL_LOGO_PATH=material/logo.png
|
|
208
|
+
THUMBNAIL_FONT_SIZE_TITLE=72
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### LLM Configuration
|
|
212
|
+
|
|
213
|
+
The tool supports any OpenAI-compatible API:
|
|
214
|
+
|
|
215
|
+
- **LLM_API_KEY** - Your API key (required)
|
|
216
|
+
- **LLM_API_URL** - API endpoint URL (default: `https://api.openai.com/v1`)
|
|
217
|
+
- **LLM_MODEL** - Model name (default: `gpt-4o-mini`)
|
|
218
|
+
|
|
219
|
+
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.
|
|
220
|
+
|
|
221
|
+
### TTS Engines
|
|
222
|
+
|
|
223
|
+
- **edge** (default) - Microsoft Edge TTS, high quality Chinese voice
|
|
224
|
+
- **coqui** - Open-source TTS (requires Python 3.9-3.11, install with `pip install "recut-cli[tts-coqui]"`)
|
|
225
|
+
- **minimax** - MiniMax cloud TTS API, high quality Chinese voice
|
|
226
|
+
|
|
227
|
+
Each TTS engine has a different speaking speed. The tool automatically adjusts the Chinese script length to match the target duration:
|
|
228
|
+
|
|
229
|
+
| Engine | Character Rate | Target chars for 30s video |
|
|
230
|
+
|--------|---------------|----------------------------|
|
|
231
|
+
| edge | 3.5 chars/sec | ~105 chars |
|
|
232
|
+
| minimax | 4.5 chars/sec | ~135 chars |
|
|
233
|
+
| coqui | 3.5 chars/sec | ~105 chars |
|
|
234
|
+
|
|
235
|
+
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.
|
|
236
|
+
|
|
237
|
+
### MiniMax Configuration
|
|
238
|
+
|
|
239
|
+
To use MiniMax TTS, set these environment variables:
|
|
240
|
+
|
|
241
|
+
```env
|
|
242
|
+
MINIMAX_API_KEY=your-api-key
|
|
243
|
+
MINIMAX_API_URL=https://api.minimaxi.com/v1/t2a_v2
|
|
244
|
+
MINIMAX_VOICE_ID=moss_audio_ce44fc67-7ce3-11f0-8de5-96e35d26fb85
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Get your API key from [MiniMax Platform](https://platform.minimaxi.com).
|
|
248
|
+
|
|
249
|
+
**Note**: MiniMax TTS uses volume level 3.0 (default is 1.0) for better audio output.
|
|
250
|
+
|
|
251
|
+
### Thumbnail Configuration
|
|
252
|
+
|
|
253
|
+
Configure thumbnail generation with these environment variables:
|
|
254
|
+
|
|
255
|
+
```env
|
|
256
|
+
# Chinese font for title display (auto-detected if not set)
|
|
257
|
+
THUMBNAIL_FONT=/path/to/font.ttf
|
|
258
|
+
|
|
259
|
+
# Optional: Default fonts to search (comma-separated, auto-detection)
|
|
260
|
+
THUMBNAIL_DEFAULT_FONTS=ZCOOLGaoDuanHei-Regular.ttf,NotoSansSC-Bold.ttf
|
|
261
|
+
|
|
262
|
+
# Optional: Font sizes
|
|
263
|
+
THUMBNAIL_FONT_SIZE_TITLE=72
|
|
264
|
+
THUMBNAIL_FONT_SIZE_SUBTITLE=14
|
|
265
|
+
|
|
266
|
+
# Optional: Logo to overlay throughout video (top-left corner, 70% opacity)
|
|
267
|
+
THUMBNAIL_LOGO_PATH=material/logo.png
|
|
268
|
+
|
|
269
|
+
# Optional: Outro video to append at the end
|
|
270
|
+
THUMBNAIL_OUTRO_PATH=material/outro.mp4
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**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.
|
|
274
|
+
|
|
275
|
+
**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).
|
|
276
|
+
|
|
277
|
+
**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.
|
|
278
|
+
|
|
279
|
+
## Disclaimer
|
|
280
|
+
|
|
281
|
+
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.
|
|
282
|
+
|
|
283
|
+
## License
|
|
284
|
+
|
|
285
|
+
[MIT](https://github.com/windstudio/recutcli/blob/main/LICENSE)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "recut-cli"
|
|
3
|
+
version = "0.1.2"
|
|
4
|
+
description = "Auto-clip videos from the web into short social media videos with Chinese dubbing"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = {text = "MIT"}
|
|
7
|
+
authors = [{ name = "windstudio" }]
|
|
8
|
+
keywords = ["video", "kickstarter", "shorts", "dubbing", "subtitle", "whisper", "tts"]
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Development Status :: 4 - Beta",
|
|
11
|
+
"Environment :: Console",
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Natural Language :: Chinese (Simplified)",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Topic :: Multimedia :: Video",
|
|
21
|
+
]
|
|
22
|
+
requires-python = ">=3.10"
|
|
23
|
+
dependencies = [
|
|
24
|
+
"click>=8.0.0",
|
|
25
|
+
"requests>=2.28.0",
|
|
26
|
+
"beautifulsoup4>=4.12.0",
|
|
27
|
+
"imageio-ffmpeg>=0.4.0",
|
|
28
|
+
"numpy>=1.24.0",
|
|
29
|
+
"openai-whisper>=20250625",
|
|
30
|
+
"openai>=1.0.0",
|
|
31
|
+
"edge-tts>=7.2.7",
|
|
32
|
+
"python-dotenv>=1.0.0",
|
|
33
|
+
"Pillow>=10.0.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
tts-coqui = ["TTS>=0.22.0"]
|
|
38
|
+
dev = ["pytest>=8.0"]
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
recut = "recut.cli:main"
|
|
42
|
+
|
|
43
|
+
[project.urls]
|
|
44
|
+
Homepage = "https://github.com/windstudio/recutcli"
|
|
45
|
+
Repository = "https://github.com/windstudio/recutcli"
|
|
46
|
+
Issues = "https://github.com/windstudio/recutcli/issues"
|
|
47
|
+
|
|
48
|
+
[build-system]
|
|
49
|
+
requires = ["setuptools>=61.0"]
|
|
50
|
+
build-backend = "setuptools.build_meta"
|
|
51
|
+
|
|
52
|
+
[tool.setuptools.packages.find]
|
|
53
|
+
include = ["recut*"]
|