Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clipsmith_ai-0.2.1.tar.gz (95.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clipsmith_ai-0.2.1-py3-none-any.whl (62.3 kB view details)

Uploaded Python 3

File details

Details for the file clipsmith_ai-0.2.1.tar.gz.

File metadata

  • Download URL: clipsmith_ai-0.2.1.tar.gz
  • Upload date:
  • Size: 95.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for clipsmith_ai-0.2.1.tar.gz
Algorithm Hash digest
SHA256 f8da67e284ba99ae629decb869d71a8056eff65dd2f43454ecb44d55ffb9a78f
MD5 db216242558d7d85ffa0009993d90c1b
BLAKE2b-256 0762d6d439f700a55a27b02dec04b1817ba5527e022ab8f481437ce5eb5b19cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for clipsmith_ai-0.2.1.tar.gz:

Publisher: publish.yml on ricardogr07/clipsmith

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file clipsmith_ai-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: clipsmith_ai-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 62.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for clipsmith_ai-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 84eb6431db71d25bf3c8132429f5ce4c520bd1789a42ad3a4e43992eceb91c6f
MD5 e5a24ac3439711cb74feeb03f36c42b0
BLAKE2b-256 871bc54d8eacf7cc19166d09348829f7fc1973227976a2ef9661587072b016c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for clipsmith_ai-0.2.1-py3-none-any.whl:

Publisher: publish.yml on ricardogr07/clipsmith

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page