1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 | # Setup
This repo is a **scoped extract** of `tools/` from a larger private video studio. It
is real, runnable render code โ but three things it depends on are not shipped here
(LUT files, HTML card templates, the compiled Swift binary). That's explained below,
and again in README.md's "What's missing" section. Read this whole file before you
run anything; skipping steps here is the #1 way to get a confusing failure.
## What you need (checklist table)
| Requirement | Why | Have it already? |
|---|---|---|
| macOS (any recent version) | `tools/personmatte.swift` uses Apple's Vision framework (`VNGeneratePersonSegmentationRequest`) and compiles with `swiftc` โ both Apple-only. Every other script is portable Python/ffmpeg and will run on Linux, but the masked/matte grade will not. | Check: `sw_vers` |
| Xcode Command Line Tools | Provides `swiftc`, needed only to build `personmatte`. | Check: `xcode-select -p` (installs with `xcode-select --install` if missing) |
| Homebrew | Package manager used to install ffmpeg-full, node, bun. | Check: `brew --version` |
| **`ffmpeg-full`** (not the slim `ffmpeg` formula) | Every render script shells out to a hardcoded path, `/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg`. Subtitle burn-in (`tools/word_captions.py`'s ASS captions) needs `libass`, which Homebrew's plain `ffmpeg` formula does not include. | Check: `/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg -hide_banner -filters \| grep -w subtitles` |
| Python 3 (any recent version) | All render tools are Python scripts. | Check: `python3 --version` |
| `opencv-python-headless` + `numpy` (Python packages) | `tools/reframe.py` imports `cv2` for face-tracked auto-reframe. | Check: `python3 -c "import cv2"` |
| `Pillow` (Python package) | `tools/quote_cards.py` and `tools/quote_reel_overlay.py` import `PIL` to draw quote cards. | Check: `python3 -c "import PIL"` |
| `playwright` (Python package) + Chromium browser | `tools/style_render.py` and `tools/quotecard_render.py` launch headless Chromium via `playwright.sync_api` to render HTML card templates transparently. | Check: `python3 -c "import playwright"` |
| Node.js 22 or newer | Only needed if you use `tools/motion_render.py` (Remotion) or `tools/hyperframes_render.py` (HyperFrames) โ both shell out to `npx`. Everything else needs no Node. | Check: `node -v` |
| ElevenLabs API key | Only needed if you transcribe via ElevenLabs Scribe (hosted). `tools/whisper_to_words.py` is the free local alternative and needs no key at all. | Check: nothing to check until you use hosted transcription |
| **Docker โ NOT needed.** Nothing here runs in a container. | โ | โ |
| **No paid API required to render.** ElevenLabs is optional and only for hosted transcription; every render/grade/caption tool runs on local ffmpeg/Python/Swift with no external service call. | โ | โ |
| **No GPU required.** All rendering is CPU (ffmpeg) plus Apple's on-device Vision framework for the matte tool โ no CUDA, no cloud inference. | โ | โ |
| **No account/login required** except the optional ElevenLabs account for hosted transcription. | โ | โ |
Two things this repo depends on but does **not** ship (the README explains why โ
this is a deliberate extract of the render logic, not the whole private studio):
- `tools/luts/{cool,warm,natural}.cube` โ LUT files `luxury_render.py` loads for
the `--grade` step. Bring your own `.cube` files, or skip `--grade` and rely on
the procedural color curves alone.
- `dashboard/styles/*.html` โ the HTML templates `style_render.py`, `quote_cards.py`,
`quotecard_render.py`, and `batch_cards.py` render via Playwright. They live in
the private dashboard layer, out of scope here. Those scripts will run but fail
to find a template until you write your own (plain HTML/CSS).
## Install, step by step
Assumes a fresh Mac with nothing installed. Skip any step where the "check it
worked" command already passes.
### 1. Install Homebrew (if you don't have it)
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
Installs the Homebrew package manager, used for every other install step below.
Check it worked:
```bash
brew --version
```
Expected: a line like `Homebrew 4.x.x`.
### 2. Install Xcode Command Line Tools
```bash
xcode-select --install
```
Installs `swiftc` (the Swift compiler) and other Apple dev tools. A GUI prompt
will pop up โ click Install and wait for it to finish.
Check it worked:
```bash
xcode-select -p
swiftc --version
```
Expected: a path like `/Library/Developer/CommandLineTools`, then a Swift version
banner.
### 3. Install ffmpeg-full (not plain ffmpeg)
```bash
brew install ffmpeg-full
```
Installs the keg-only, full-featured ffmpeg build with `libass` (subtitle burn-in)
compiled in. It will NOT put `ffmpeg` on your `PATH` (keg-only) โ every script here
calls it by its full path instead: `/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg`.
Check it worked:
```bash
/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg -hide_banner -filters | grep -w subtitles
```
Expected: a line containing `subtitles` (confirms libass support). No output means
caption burn-in will fail later.
**Apple Silicon note:** the path above (`/opt/homebrew/...`) is correct for Apple
Silicon Macs. On an Intel Mac, Homebrew installs to `/usr/local`, so the path is
`/usr/local/opt/ffmpeg-full/bin/ffmpeg` โ every script's hardcoded `FF`/`FFMPEG`
path will need that swap if you're on Intel.
### 4. Compile the Vision matte tool (macOS only โ skip if you don't need masked grades)
```bash
cd tools && swiftc -O -o personmatte personmatte.swift && cd ..
```
Builds the person-segmentation binary `luxury_render.py` shells out to for masked
(subject-cutout) grading. If you skip this, everything except masked grades still
works โ `luxury_render.py` falls back gracefully when the binary is missing.
Check it worked:
```bash
tools/personmatte 2>&1 | head -1
```
Expected: `personmatte: usage: personmatte <video> <outW> <outH> [fast|balanced|accurate]`
(it's erroring on purpose because you ran it with no video โ that error message
is the proof the binary built and runs).
### 5. Create a Python virtual environment and install Python dependencies
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install "opencv-python-headless<5" numpy pillow playwright
playwright install chromium
```
Creates an isolated Python environment, installs the packages the render scripts
import (`cv2`, `numpy`, `PIL`, `playwright`), and downloads the headless Chromium
browser Playwright drives.
Windows/Linux variant (same commands, different activate line):
```bash
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install "opencv-python-headless<5" numpy pillow playwright
playwright install chromium
```
Check it worked:
```bash
python3 -c "import cv2, numpy, PIL, playwright; print('ok')"
```
Expected: `ok`
### 6. (Optional) Install Node.js 22+ and bun โ only if you'll use the motion-graphics drivers
```bash
brew install node bun
```
`tools/motion_render.py` and `tools/hyperframes_render.py` shell out to `npx`/`bunx`
for two external engines (Remotion, HyperFrames) that are not vendored in this repo.
Skip this step if you only need the ffmpeg-based render tools (luxury grade, quote
cards, captions, reframe).
Check it worked:
```bash
node -v
```
Expected: `v22.x.x` or newer.
## Configure
```bash
cp env.example .env
```
Then edit `.env`:
```
ELEVENLABS_API_KEY=YOUR_KEY_HERE # keyzhub-allow
```
- Only needed if you use hosted transcription. Get a key at
https://elevenlabs.io/app/settings/api-keys.
- If you use the local-whisper path instead (`tools/whisper_to_words.py`, converting
`whisper-cli` JSON output), you need no key at all โ leave `.env` unfilled or skip
creating it.
- Note the filename is `env.example` (not `.env.example`) on purpose, so it isn't
swept up by dotfile secret-scanners โ same idea, just a plain filename. `setup.sh`
(the original studio's bootstrap script, not meant to run unmodified here)
references `.env.example`; use `env.example` as shown above instead.
## Run it
The scripts are standalone CLIs โ no server to start. First real command:
```bash
source .venv/bin/activate
python3 tools/luxury_render.py --video source.mp4 --start 12 --end 20 \
--title "YOUR CAPTION HERE" --out out.mp4
```
What success looks like: the command exits 0 and `out.mp4` exists in the current
directory. Verify it's a real render, not just a green exit code:
```bash
/opt/homebrew/opt/ffmpeg-full/bin/ffprobe -v error -show_entries \
stream=width,height,r_frame_rate -of default=noprint_wrappers=1 out.mp4
```
Expected: width/height/frame-rate lines describing a real video stream (e.g.
`width=1080`, `height=1920`, `r_frame_rate=30/1`).
If you asked for `--grade`, this step will fail until you supply your own
`tools/luts/{cool,warm,natural}.cube` files (not included โ see "What's missing"
above and in README.md).
## Troubleshooting
1. **`ffmpeg: command not found` or subtitle/caption burn-in fails silently.**
You installed the slim `ffmpeg` formula instead of `ffmpeg-full`, or you're on
Intel and the hardcoded `/opt/homebrew/...` path doesn't exist on your machine.
Fix: `brew install ffmpeg-full`, and on Intel Macs, edit the `FF`/`FFMPEG`/`FFPROBE`
constant near the top of the script you're running to point at
`/usr/local/opt/ffmpeg-full/bin/...` instead.
2. **`ModuleNotFoundError: No module named 'cv2'` (or `PIL`, or `playwright`).**
You're running the system `python3`, not the virtualenv's. Fix: run
`source .venv/bin/activate` in the same shell before running any `tools/*.py`
script, or call the interpreter directly: `.venv/bin/python3 tools/reframe.py ...`.
3. **`RuntimeError: personmatte unavailable (swiftc or source missing)` or masked
grades silently fall back to the unmasked look.**
Either you skipped step 4 (compiling `personmatte`), or you're not on macOS.
Masked/matte grading is Apple Vision-only and has no cross-platform equivalent โ
compile it with `cd tools && swiftc -O -o personmatte personmatte.swift`, or
accept the fallback and use the unmasked luxury grade.
|