video-cook
Deterministic executor for the video-cooking skill pipeline. Wraps yt-dlp, whisperX, and ffmpeg into subcommands that assemble correctly every time — so the skill docs can stay short and the agent never hand-assembles a long command.
This is the hands, not the brain. Skills decide what to do, when, and handle creative work (translation, copywriting). cook only executes the deterministic parts and verifies the expected outputs exist.
Why
The video-cooking / video-download / video-subtitle skill trio started as natural-language docs that told the agent which yt-dlp / ffmpeg / whisperx commands to run. Three classes of bugs kept recurring:
- Shell escaping traps — Windows paths with
C:break ffmpeg'sassfilter; backslashes get eaten by PowerShell; stdout redirects silently swallow downloads. - Hand-assembly drift — the agent forgets a flag (
--convert-thumbnails jpg), picks the wrong template variable, renames the wrong file. - No mechanical completion check — "the agent feels done" is not a Done criterion. Real runs shipped without
cover.jpg, withoutcloud-srt/, with translation drift the agent couldn't see.
cook fixes all three by being the single place where the commands are assembled. The skill docs shrink to a pipeline skeleton; the completion criteria become "cook exit 0".
Install
Option 1: One-liner via uv (recommended — uv handles Python interpreter + isolated env + PATH wiring automatically, no pip/venv knowledge needed):
# Linux / macOS
curl -LsSf https://github.com/ChHsiching/video-cook/releases/latest/download/install.sh | sh
# Windows (PowerShell)
irm https://github.com/ChHsiching/video-cook/releases/latest/download/install.ps1 | iex
The installer uses uv to install video-cook[all] as an isolated tool (~2GB — pulls whisperx + torch). After install, open a new shell and run cook doctor.
Option 2: pip directly:
pip install video-cook[all] # yt-dlp + whisperx + cook itself
# or pick what you need:
pip install video-cook[download] # for `cook download`
pip install video-cook[transcribe] # for `cook transcribe`
ffmpeg and Node.js must be on PATH separately (cook can't pip-install those).
Subcommands
| Command | What it does | Replaces (manual steps) |
|---|---|---|
cook doctor |
Check environment (ffmpeg/node/yt-dlp/whisperx/torch+CUDA) | Skill's "Environment reuse" prose |
cook download <url> |
yt-dlp download + cookie negotiation + thumbnail rename + ffprobe verify | video-download Steps 1-3 |
cook extract <root> <name> |
ffmpeg 16kHz mono WAV extraction | video-subtitle Step 1 |
cook transcribe <root> <name> |
whisperX transcription, auto-detects CUDA, auto-detaches | video-subtitle Step 2 |
cook subtitles <root> <name> |
shorten → merge-short → biliteral → ASS + cloud-srt in one shot | video-subtitle Step 4 + cloud-srt |
cook burn <root> <name> |
ffmpeg subtitle burning, auto-detaches, subprocess list-form | video-subtitle Step 5 |
cook cover <root> <name> |
Place cover.jpg in cooked/ (reuses raw thumbnail) |
video-subtitle Step 6 cover task |
cook show-source <root> <name> |
Extract key fields (title/uploader/links/description) from source.json | (new — surfaces the source context for translation + upload metadata) |
cook verify-align <root> <name> |
DP-align en.srt vs translations.txt, catch missing/drifted translations |
(new — no prior equivalent) |
cook verify-shipment <root> <name> |
Check the full release set exists; exit 0 = ready to ship | (new — no prior equivalent) |
Every command prints a JSON object on stdout (machine-readable; agents parse this) and human-readable progress on stderr. Exit codes are meaningful: 0 = done criterion passed, non-zero = it didn't.
Usage from a skill
The skill docs call cook as a subprocess and branch on its exit code. Example skeleton from video-subtitle:
Step 1: cook extract <root> <name> → exit 0 = done
Step 2: cook transcribe <root> <name> → exit 0 = launched, poll log until "[transcribe] done."
Step 3: (agent translates → writes translations.txt)
cook verify-align <root> <name> → exit 0 = aligned, proceed
Step 4: cook subtitles <root> <name> --mode bottom-bar --bar-px 180
Step 5: cook burn <root> <name> --mode bottom-bar --bar-px 180
Step 6: (agent writes upload.md)
cook cover <root> <name>
Step 7: (agent writes README.md)
The router (video-cooking) calls cook verify-shipment as the final gate before reporting the pipeline done.
Bugs that cook fixes
| Bug in the old skill docs | How cook fixes it |
|---|---|
--dump-json > file.json silently swallowed downloads |
cook uses print_to_file (yt-dlp's native JSON-to-file option) |
Thumbnail came out as <name>.raw.jpg not <name>.jpg |
cook renames it after download |
Windows C: paths broke ffmpeg ass filter |
cook uses subprocess list-form (never shell), runs from subtitle/ dir with bare filename |
subtitles.py split leaked single-language cues across zh.srt/en.srt |
cook copies *.merged.srt to cloud-srt instead of splitting bilingual.srt |
transcribe.py hardcoded device="cpu", float16 unusable on GPU |
cook auto-detects CUDA → float16+cuda, else float32+cpu |
source.json downloaded but never read by downstream — author/links/description wasted |
cook show-source surfaces the curated fields translation and upload metadata consume |
| detached template only covered transcribe, not burn | cook's _detach() helper handles both uniformly |
| No mechanical way to catch translation drift | cook verify-align runs DP global alignment |
| No mechanical way to catch missing release-set files | cook verify-shipment checks every expected file |
Development
git clone https://github.com/ChHsiching/video-cook
cd video-cook
pip install -e .[dev]
pytest test_cook.py -v
Tests cover the subcommands whose correctness is non-obvious: verify-align (DP alignment edge cases), verify-shipment (file-presence checks), and the cloud-srt copy logic (the fix for the split leak). No network, no ffmpeg, no whisperx — all tests use temp dirs and fake files.
License
MIT
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 video_cook-0.5.0.tar.gz.
File metadata
- Download URL: video_cook-0.5.0.tar.gz
- Upload date:
- Size: 29.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
300a57c95035868160506dd54e2ad61525d8ed04c766b689380df7e8e676f096
|
|
| MD5 |
fa43e75987d2d53d38df6b81e2a2bca4
|
|
| BLAKE2b-256 |
70c3b7ea80554c188a26c9645ebc9030876f480e69d4c16c5c680c9cee6cc5b4
|
Provenance
The following attestation bundles were made for video_cook-0.5.0.tar.gz:
Publisher:
publish.yml on ChHsiching/video-cook
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
video_cook-0.5.0.tar.gz -
Subject digest:
300a57c95035868160506dd54e2ad61525d8ed04c766b689380df7e8e676f096 - Sigstore transparency entry: 2356843281
- Sigstore integration time:
-
Permalink:
ChHsiching/video-cook@a52ba5001c6202504eaeb3e7041efcb7b3f74cd9 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/ChHsiching
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a52ba5001c6202504eaeb3e7041efcb7b3f74cd9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file video_cook-0.5.0-py3-none-any.whl.
File metadata
- Download URL: video_cook-0.5.0-py3-none-any.whl
- Upload date:
- Size: 26.7 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 |
c4cc7c6fa90bca10a22a4445b14db2d9a3b3d3a546917aa2a41eb7826c63d38a
|
|
| MD5 |
58ad32b6be4c5f2ab611ed802b1e4674
|
|
| BLAKE2b-256 |
4f6535727ef6a07896050190db017140c612ea24319e109e0bfe0c067a74a6ad
|
Provenance
The following attestation bundles were made for video_cook-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on ChHsiching/video-cook
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
video_cook-0.5.0-py3-none-any.whl -
Subject digest:
c4cc7c6fa90bca10a22a4445b14db2d9a3b3d3a546917aa2a41eb7826c63d38a - Sigstore transparency entry: 2356843924
- Sigstore integration time:
-
Permalink:
ChHsiching/video-cook@a52ba5001c6202504eaeb3e7041efcb7b3f74cd9 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/ChHsiching
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a52ba5001c6202504eaeb3e7041efcb7b3f74cd9 -
Trigger Event:
push
-
Statement type: