Twitch VOD -> AI-selected vertical clips with burned-in Spanish captions.
Project description
clipsmith
Local Twitch → AI clip pipeline. Downloads a VOD, transcribes Spanish audio, ranks moments by chat activity, sends candidates to an LLM, and cuts 9:16 vertical MP4s — optionally with burned-in captions and a stacked webcam/gameplay layout for TikTok / YouTube Shorts.
Prerequisites
| Tool | Install |
|---|---|
| Python 3.11+ | python.org or winget install Python.Python.3 |
| ffmpeg | winget install Gyan.FFmpeg — must be on PATH |
| twitch-dl | bundled via pip install -e . |
| chat-downloader | bundled via pip install -e . |
| faster-whisper | bundled via pip install -e . |
Optional — webcam auto-detection:
pip install -e ".[vision]" # installs opencv-python-headless
Installation
git clone https://github.com/ricardogr07/clipsmith
cd clipsmith
pip install -e .
Configuration
Secrets — .env
Copy .env.example to .env and fill in your keys:
TWITCH_CLIENT_ID=...
TWITCH_CLIENT_SECRET=...
ANTHROPIC_API_KEY=... # if using provider: anthropic
OPENAI_API_KEY=... # if using provider: openai
Get Twitch credentials at https://dev.twitch.tv/console → Register Your Application → OAuth Redirect: http://localhost.
Behaviour — config.yaml
channels:
- chuyelwuero # Twitch logins to watch
llm:
provider: anthropic # anthropic | openai | ollama
model_anthropic: claude-sonnet-4-6
clip:
min_seconds: 15
max_seconds: 30
caption:
enabled: false # set true to burn subtitles into the video
font: Arial
font_size: 72 # ASS pts at 1080×1920 PlayRes
outline: 3
position: bottom # bottom | middle | top
reframe:
# center | webcam | stacked | none
mode: none
# Source-pixel crop for the webcam/face panel [x, y, w, h]
# Leave null to use center-crop fallback; set once per stream layout.
webcam_rect: null
# Source-pixel crop for the gameplay panel (stacked mode only)
# null = center-crop fallback
gameplay_rect: null
# Fraction of 1920px height given to the top (webcam) panel in stacked mode
# e.g. 0.4 → 768px webcam on top, 1152px gameplay on bottom
split_ratio: 0.4
Usage
First-time setup
clipsmith setup
Saves your API key to .env and verifies ffmpeg is available.
Process a local MP4
clipsmith process path/to/recording.mp4
Runs the full pipeline — transcribe → score candidates → LLM selection → cut clips. Clips appear in out/<video_id>/.
Useful flags:
| Flag | Effect |
|---|---|
--skip-transcribe |
Load cached transcript.json |
--captions / --no-captions |
Override caption config |
--reframe / --no-reframe |
Override reframe config |
--provider anthropic|openai |
Override LLM provider |
Daemon mode
clipsmith watch
Polls every poll_interval_s seconds (default 120). When a new archive VOD appears it runs the full pipeline automatically. State is persisted to state.json so already-processed VODs are skipped across restarts.
One-off Twitch VOD
clipsmith run-vod <video_id>
Useful flags:
| Flag | Effect |
|---|---|
--skip-download |
Use the existing .mp4 in work/<id>/ |
--skip-transcribe |
Load cached transcript.json |
--skip-chat |
Load cached chat.json |
--skip-select |
Stop after candidates, skip LLM |
--skip-clip |
Stop after picks, skip ffmpeg |
--provider anthropic|openai |
Override config LLM |
--max-candidates N |
Cap candidates sent to LLM (default 20) |
Re-cut flat clips
Re-run only the ffmpeg step from an existing picks.json (e.g. after adjusting caption style):
clipsmith clip <video_id>
Stacked vertical layout (webcam + gameplay)
After reviewing the flat clips, pick the best ones and reframe them into a stacked 9:16 layout — webcam on top, gameplay on bottom:
clipsmith reframe <video_id> clip_01 clip_04 clip_09
Output goes to out/<video_id>/stacked/. The reframe rects come from config.yaml; see the reframe section above.
Auto-detecting the webcam rect:
If reframe.webcam_rect is not set in config.yaml, clipsmith will try to detect the face rectangle automatically using OpenCV (requires pip install -e ".[vision]"). The result is cached to work/<video_id>/webcam_rect.json and reused on subsequent runs.
To run detection manually and write the result directly into config.yaml:
clipsmith detect-webcam <video_id>
This samples frames, detects the webcam rectangle, and saves reframe.webcam_rect in config.yaml automatically — no manual copy-paste needed.
Sanity check
clipsmith whoami chuyelwuero
Output
work/
<video_id>/
<video_id>.mp4 downloaded (or copied) source VOD
transcript.json faster-whisper segments + word timestamps
chat.json chat replay
candidates.json ranked candidate moments
picks.json LLM-accepted clips with titles and reasons
webcam_rect.json auto-detected webcam rect (cached, vision only)
out/
<video_id>/
clip_01_momento_gracioso.mp4 flat 9:16 clip
clip_01_momento_gracioso.ass sidecar ASS subtitle file
clip_02_reaccion_epica.mp4
...
stacked/
clip_01_momento_gracioso.mp4 stacked layout (webcam top, gameplay bottom)
clip_04_reaccion_epica.mp4
...
All clips are 1080×1920 (9:16), 15–30 s, h264/aac, with optional burned-in Spanish karaoke captions.
Pipeline overview
watch / run-vod / process
↓
downloader (twitch-dl) → work/<id>/<id>.mp4
↓
detect-webcam (opencv Haar cascade) → work/<id>/webcam_rect.json [optional]
↓
transcribe (faster-whisper) → transcript.json (word timestamps, lang=es)
↓
chat (chat-downloader) → chat.json
↓
candidates (density + clips + !clip) → candidates.json
↓
selector (LLM) → picks.json
↓
clipper (ffmpeg + libass) → out/<id>/clip_NN_<title>.mp4
↓ [manual: clipsmith reframe]
reframe (ffmpeg filter_complex) → out/<id>/stacked/clip_NN_<title>.mp4
Development
pip install -e ".[dev]"
pip install -e ".[vision]" # optional, for detect-webcam tests
python -m pytest tests -q
Project details
Release history Release notifications | RSS feed
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 clipsmith_ai-0.2.0.tar.gz.
File metadata
- Download URL: clipsmith_ai-0.2.0.tar.gz
- Upload date:
- Size: 94.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ceeb964ad65eefd7d4dbc8c930364de02eb49f05e62c93fd651958f31b2e522
|
|
| MD5 |
d66305d6ba838b828b6d2c2d6b43bcff
|
|
| BLAKE2b-256 |
12c2538ae49615934ea926b1f611144c38bebc85a932a373cf44183ec2295548
|
Provenance
The following attestation bundles were made for clipsmith_ai-0.2.0.tar.gz:
Publisher:
publish.yml on ricardogr07/clipsmith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
clipsmith_ai-0.2.0.tar.gz -
Subject digest:
9ceeb964ad65eefd7d4dbc8c930364de02eb49f05e62c93fd651958f31b2e522 - Sigstore transparency entry: 1480119554
- Sigstore integration time:
-
Permalink:
ricardogr07/clipsmith@1e455b03bbea0f481a1d6926832aa55b16f95987 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ricardogr07
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1e455b03bbea0f481a1d6926832aa55b16f95987 -
Trigger Event:
push
-
Statement type:
File details
Details for the file clipsmith_ai-0.2.0-py3-none-any.whl.
File metadata
- Download URL: clipsmith_ai-0.2.0-py3-none-any.whl
- Upload date:
- Size: 62.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
258ceb59d8bb0959b59c39dadddbc65abc415d669287377ed15b78fee8e2e85c
|
|
| MD5 |
7fbfba44e24e3407bcbd3e031798cdcb
|
|
| BLAKE2b-256 |
958a5ed7cf11f4ccbeb37bb8990e51b4f6f615dcf1500c291b27d5dd9d45c764
|
Provenance
The following attestation bundles were made for clipsmith_ai-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on ricardogr07/clipsmith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
clipsmith_ai-0.2.0-py3-none-any.whl -
Subject digest:
258ceb59d8bb0959b59c39dadddbc65abc415d669287377ed15b78fee8e2e85c - Sigstore transparency entry: 1480119752
- Sigstore integration time:
-
Permalink:
ricardogr07/clipsmith@1e455b03bbea0f481a1d6926832aa55b16f95987 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ricardogr07
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1e455b03bbea0f481a1d6926832aa55b16f95987 -
Trigger Event:
push
-
Statement type: