skip to content
[··]nano-os v7.0 — booting portfolio
revival nano adolor
senior frontend engineer
00%

cookcut

Raw cooking footage in, short-form video out.

A local tool that turns raw cooking clips into platform-ready vertical video: scene and audio-event detection, a hook-first edit, loudness-normalised render — plus an editor UI and a batch CLI.

role
Side project · solo
year
2026
platform
Local web app + CLI
live
private
stack
FastAPIffmpegfaster-whisperNext.js 16Python
localhost:3000 — cookcut
cookcut editor — ingest, analyse, auto-cut and the segment timeline
The rendered cut opens on the finished dish
$ cookcut auto ./recipe --targets vertical_9x16
131s → 31s · 21 shots · hook first
131s → 31s
real footage, auto-cut
21
shots, opens on the dish
18
tests passing

$ ls ./screens

2 screens · scroll →
localhost:3000 — cookcut
cookcut editor — ingest, analyse, auto-cut and the segment timeline
cookcut editor — ingest, analyse, auto-cut and the segment timeline
The rendered cut opens on the finished dish
The rendered cut opens on the finished dish

The problem

Cooking content lives on short-form video, and editing it is the bottleneck: forty minutes of phone clips have to become thirty seconds that open on the finished dish. I wanted a tool that does the first cut for me — locally, with no uploads.

What I built

cookcut: a local web app and CLI that turns raw cooking footage into platform-ready video.

  • Backend: FastAPI + ffmpeg. Ingest is hash-deduplicated and streamed, so it never loads a whole video into memory. Scene detection and audio-event detection pick the moments; faster-whisper transcribes speech for captions.
  • The edit: hook-first — open on the finished dish — then pace the shots, cap how much of the runtime any single source clip can take, and render 9:16, 1:1, 4:5 or 16:9.
  • Review: review.py scores every cut on hook, pace, runtime and coverage, so "is this cut any good" is a test, not a feeling.
  • Frontend: a Next.js editor to nudge cuts. CLI: one-click, batch and watch-folder modes.

The hard part: real footage

Everything passed on synthetic test clips. The first real iPhone run found seven bugs. Three favourites:

  • Double rotation. ffmpeg autorotates portrait clips from the display matrix; the code was also applying a transpose. Every portrait clip came out sideways. Fix: -noautorotate on any input that feeds a rotation filter.
  • Audio events found nothing. The threshold was "noise floor + 12 dB", but real kitchen audio only spans 3–18 dB. Now the threshold is relative to each clip's own dynamic range.
  • True peak over the ceiling. AAC reconstructs peaks 0.6–1.2 dB above the PCM it's given, so loudness normalisation now aims lower and verification measures the encoded file.

Outcome

  • 131 seconds of real footage → a 31-second vertical cut, 21 shots, opening on the dish, passing every structural check.
  • 18 tests, now with real-footage fixtures where synthetic ones lied.
next case study →Kwikpik KYCSelf-hosted identity verification, liveness in the browser
✓