THE WORLD IS NOT STANDING STILL.RSS
BIG CHANGE.
BIG CHANGE, one tap away
BIG CHANGE, one tap away

Make room for the big picture.

Add BIG CHANGE to your home screen or desktop. It opens in its own window, with the latest stories when you’re online.

iPhone & iPad
Open bigchange.ai in Safari. Tap Share, then Add to Home Screen. Turn on Open as Web App if shown, then tap Add.
Android
Open bigchange.ai in Chrome. In the browser menu, choose Install app or Add to Home screen.
Desktop
In Chrome or Edge, use the install icon in the address bar or the browser’s app menu. In Safari on Mac, choose File → Add to Dock.

Markdown edition

# Turn one owned long video into five checked vertical shorts

> A documentation-based workflow for five source-checked video clips with corrected captions, vertical framing and human review.

By BIG CHANGE Editorial

Published: 2026-10-21T09:43:38.285Z
Updated: 2026-10-21T09:43:38.285Z
Canonical: https://bigchange.ai/blog/five-checked-video-shorts-claude-code-whisper-ffmpeg

![Conceptual charcoal illustration of five upright unbranded phones in a wall shelf, each showing a generic vertical image with a blank orange caption bar.](https://bigchange.ai/api/media/file/owned-video-five-shorts-hero-v1.png)
AI-generated conceptual illustration by BIG CHANGE.

One recording can supply several short clips, but a transcript cannot decide whether an excerpt is fair, and a 1080 × 1920 export cannot prove it is watchable. This guide uses five manually invoked Claude Code project skills to organize the work: transcribe, rank, cut, caption and render. A human editor approves every source interval and watches every finished file. The workflow is for a video you own or have explicit rights to edit and share.

This is a documentation-based recipe for macOS Terminal with zsh. BIG CHANGE has not run these commands, inspected private footage or produced the five files. Check the installed tools' help and your actual media before following it. The accompanying hero is a conceptual illustration of the five vertical videos a creator would review. These are not actual clips, software output or a BIG CHANGE test of the documented workflow.

## The big change

- **What changed:** Claude Code project skills can divide a local video edit into five manually invoked stages. The proposed handoff records connect source timestamps, approved cuts, corrected captions and final files; the tools' documentation does not establish that this particular chain has been run successfully.
- **Why it matters:** A creator with permitted source footage can give a human editor a specific decision at each stage, including whether five distinct excerpts exist at all. That structure makes it possible to reject a weak or misleading cut before it becomes a captioned export.
- **What to watch:** The decision to share any result still rests on rights, the chosen Claude account's data policy and complete playback of each saved MP4. A passing file probe cannot settle those questions.

## Before you start

You need a local `source.mp4` with usable audio, adequate storage, Claude Code access, a working local whisper.cpp `whisper-cli` and a language-compatible model, plus FFmpeg and ffprobe with the required encoders and filters. You also need an editor who can check the recording and all five exports. Record the Claude Code account and data policy, installed versions, whisper.cpp commit or build, model SHA-256 and license, and any usage limits. Claude Code may use a hosted model even when transcription and rendering run locally. Only give it transcript or media access your rights and account policy permit. Its [skill instructions](https://code.claude.com/docs/en/skills) do not restrict access. The separate [tool permission controls](https://code.claude.com/docs/en/permissions) govern tool calls; depending on settings, routine read-only actions may run without a prompt. Deliberately inspect what the skill can read as well as what it proposes to write or execute.

Put an immutable copy of the source and `rights.json` in a new trusted local run folder. The rights record should identify the source SHA-256, editor, allowed excerpts and downstream uses, and permissions for speakers, music and visuals, along with storage and retention rules. Do not proceed on uncertain rights. Open Terminal in that folder, verify `pwd`, then create the work folders:

```shell
mkdir -p transcript clips captions shorts probes .claude/skills/video-transcribe .claude/skills/video-rank .claude/skills/video-cut .claude/skills/video-caption .claude/skills/video-vertical
command -v claude
command -v ffmpeg
command -v ffprobe
claude --version
ffmpeg -version
ffprobe -version
ffmpeg -hide_banner -h encoder=libx264
ffmpeg -hide_banner -h encoder=aac
ffmpeg -hide_banner -h filter=subtitles
ffmpeg -hide_banner -h filter=scale
```

Set `WHISPER_CLI` and `WHISPER_MODEL` to real, quoted absolute paths. Set `LANGUAGE` to the verified spoken language code, such as `en` only when the audio is English. Confirm the model supports it; an English-only `.en` model will not cover another language. Mixed or unsupported languages need a checked plan before continuing. The [whisper.cpp CLI reference](https://github.com/ggml-org/whisper.cpp/blob/master/examples/cli/README.md) documents `-l`, `-m`, `-f`, `-osrt`, `-oj` and `-of`; verify them against your build's help. Do not enable its translation option.

```shell
WHISPER_CLI='/absolute/path/to/whisper-cli'
WHISPER_MODEL='/absolute/path/to/approved-model.bin'
LANGUAGE='en'
test -x "$WHISPER_CLI"
test -r "$WHISPER_MODEL"
"$WHISPER_CLI" --help
ffprobe -v error -show_entries format=duration:stream=index,codec_type,codec_name,width,height,sample_aspect_ratio -of json source.mp4
```

Replace the example paths and language before running anything. Check source duration, streams, orientation, audio and free space. Confirm the installed `subtitles` filter has libass support and `scale` accepts `force_original_aspect_ratio`, `force_divisible_by` and `reset_sar`. If a required feature is absent, use the maintainers' build instructions and repeat the checks. Do not silently drop captions.

## Make five bounded project skills

In the trusted project, save five separate `.claude/skills/<name>/SKILL.md` files. Each needs its own `name`, `description`, `disable-model-invocation: true`, and a complete input, action, output and stop rule. Invoke them manually, in order: `/video-transcribe`, `/video-rank`, `/video-cut`, `/video-caption`, `/video-vertical`. Do not add `allowed-tools`: Claude Code says that field grants prompt-free permission for listed tools during invocation; it does not confine the skill. Keep normal permission settings and deliberately review access. A read-only tool call may not prompt, while writes and execution follow the account's actual controls.

Use these complete bodies, with the shared run record described below. The prose inside a skill is an instruction to Claude Code, not an enforcement boundary.

**`.claude/skills/video-transcribe/SKILL.md`**

```markdown
---
name: video-transcribe
description: Transcribe the authorized local source for the five-short workflow.
disable-model-invocation: true
---

Input: rights.json, immutable source.mp4, checked source probe, verified language and local whisper.cpp executable/model. Confirm matching source and model hashes, usable audio and permitted access before any command.
Action: From the checked run directory, confirm source.wav and both transcript output paths do not exist. Extract mono 16 kHz 16-bit PCM source.wav with explicit first-audio mapping and no overwrite. Continue to whisper-cli only after a zero exit and valid WAV readback; use the verified model and explicit language, SRT and JSON output, and translation off. Inspect both outputs, parse source-relative times, and compare representative passages and uncertain names or quotes against source audio. Record a nonzero exit or uncertain output as a manifest blocker before any next stage.
Output: transcript/source.srt and transcript/source.json, recorded hashes, corrections or marked uncertainties, tool and model identity in manifest.json.
Stop: Missing rights, changed inputs, absent audio, empty or malformed transcript, or unverified relevant speech. Do not upload, publish or overwrite accepted files; ask the editor to settle uncertainty.
```

**`.claude/skills/video-rank/SKILL.md`**

```markdown
---
name: video-rank
description: Suggest source moments for human selection of five distinct clips.
disable-model-invocation: true
---

Input: Checked source transcript and hash, immutable source hash and probe duration, rights.json, intended audience. Verify all identities and authorized transcript access.
Action: Suggest more than five moments with numeric source-second start/end, source words, surrounding context and editorial rationale. Treat ranking as a suggestion, never a viral forecast. Have the editor open each candidate in the original and check speaker, wording, facts, context and rights. Record exactly five distinct coherent approved intervals and a rejected-candidate log.
Output: approved-moments.json with order, source hash and five numeric bounds satisfying 0 <= start < end <= source duration.
Stop: Fewer than five permissible, meaningful moments, mismatched hashes, uncertain bounds or missing human approval. Do not invent a fifth excerpt.
```

**`.claude/skills/video-cut/SKILL.md`**

```markdown
---
name: video-cut
description: Cut the five approved source intervals into separate local clips.
disable-model-invocation: true
---

Input: Immutable source.mp4, source hash/probe and five human-approved intervals. Verify hashes and calculate each duration as end minus start.
Action: For each 01-05, confirm its unique output path is unused, then transcode the approved source-relative interval with input -ss, -t duration, explicit first video/audio mapping, libx264, AAC and -n. Continue only on zero exit and file readback. Probe streams and duration, inspect first and last frames, and have the editor watch each whole cut for boundaries, sync and context. Record the exact command and output hash. Any failure or uncertain write is a manifest blocker; never pass that clip to captioning.
Output: Five accepted numbered clips, individual probe records and links to approved intervals in manifest.json.
Stop: Wrong bounds, absent stream, drift, misleading context, output collision or uncertain command result. Read back the existing path first; correct bounds with human approval and use a new filename. Never overwrite or reuse an old clip hash.
```

**`.claude/skills/video-caption/SKILL.md`**

```markdown
---
name: video-caption
description: Create and check local captions from each accepted clip.
disable-model-invocation: true
---

Input: Five accepted clip hashes, verified language and local model identity. Reject stale clips or mismatched source links.
Action: For each actual numbered clip 01-05, verify its accepted hash and unused WAV/raw-SRT paths, then extract its own mono 16 kHz 16-bit PCM WAV with -n. Run whisper-cli only after zero exit and WAV readback, with the matching language and SRT output; translation stays off. Preserve raw SRT. Have the editor correct words, names, numbers, cue timing, overlaps and readability against the actual clip, then save a distinct .checked.srt. Use clip-local times, not source-offset cues. Record failures as blockers before rendering.
Output: Five checked SRTs with raw-ASR and exact clip hash links in manifest.json.
Stop: Any cue outside clip duration, uncertain speech, bad alignment or stale clip hash. Repair and replay before rendering; a recut requires matching new captions.
```

**`.claude/skills/video-vertical/SKILL.md`**

```markdown
---
name: video-vertical
description: Render and review five captioned 1080x1920 MP4s.
disable-model-invocation: true
---

Input: Five accepted clip hashes/probes, matching checked SRT hashes, rights record and a human-approved crop or framing plan for each clip.
Action: Check decoded orientation and sample aspect ratio. Choose even integer crop width, height and x/y for each clip; require positive dimensions, nonnegative offsets and a rectangle within the decoded frame. A fixed crop does not track motion. Verify unique output and probe paths are unused. From the established run directory, render each separately with crop, aspect-preserving scale, pad, clip-local subtitles, explicit video/audio mapping, libx264, yuv420p, AAC and -n. Continue only on zero exit and saved-file readback. Create probe JSON without clobbering an existing path, reopen the MP4 and have the editor watch its entire video and audio, checking cut context, every caption, framing, sync, facts and rights. Record any failure or uncertain output as a blocker.
Output: Five distinct accepted 1080x1920 MP4s, hashes, probe JSON, exact source/clip/SRT lineage and UTC human acceptance notes.
Stop: Unknown orientation, invalid crop, missing filter, collision, unreadable file, silent audio, cut-off text, wrong duration, bad context or failed full playback. Inspect uncertain existing outputs; revise to a new filename, probe and watch again. No upload or publishing.
```

Keep one `manifest.json` for the run. At each handoff record the rights record and immutable source SHA-256, tool versions, model SHA-256/license/language, inputs and outputs with SHA-256, approved numeric source intervals, exact commands, and UTC decisions. If a named file or hash differs, stop and resolve it before the next skill.

Treat each shell block below as one stage in a fresh zsh script or controlled shell, with `set -e` so a failed command stops that stage. Check each output path is unused before running it and record any nonzero exit, missing file or uncertain write as a blocker in the manifest. A later skill must read that status and the output hash; it cannot accept a failed cut simply because a stale clip happens to exist.

## 1. Transcribe the source

The [whisper.cpp maintainer README](https://github.com/ggml-org/whisper.cpp/blob/master/README.md) says its CLI example currently needs 16-bit WAV. With confirmed source audio, run the following from the verified project folder. `-n` prevents FFmpeg from overwriting an existing WAV.

```shell
set -e
test ! -e source.wav
test ! -e transcript/source.srt
test ! -e transcript/source.json
ffmpeg -i source.mp4 -map 0:a:0 -ar 16000 -ac 1 -c:a pcm_s16le -n source.wav
test -s source.wav
"$WHISPER_CLI" -m "$WHISPER_MODEL" -f source.wav -l "$LANGUAGE" -osrt -oj -of transcript/source
test -s transcript/source.srt
test -s transcript/source.json
```

Confirm both `transcript/source.srt` and `.json` exist, contain timestamped speech and stay within the probed source duration. Listen to representative passages and verify uncertain names, numbers and quotes against the original. Keep a corrected source transcript or explicit uncertainty marks. If audio extraction or transcription is empty, inspect the source stream, executable, language and model compatibility before attempting a fresh uniquely named output.

## 2. Select five moments in the original

Invoke `/video-rank` with the checked transcript and audience. Ask for more than five candidates so the editor can reject weak excerpts. For each proposal, require numeric start and end seconds from the beginning of the source, the spoken passage, context before and after, and why the segment can stand alone. Open each interval in the original. The editor decides whether speaker, wording, visual context, facts and permissions survive the cut. Save exactly five distinct approved intervals in `approved-moments.json`; include order, source hash and `0 <= start < end <= source duration`. A transcript passage alone is only a locator. For a narrower timestamp-finding task, see [Find the spoken moment before editing a video](https://bigchange.ai/blog/find-spoken-moment-before-video-editing).

If the recording does not contain five defensible moments, stop. The five-file task remains incomplete.

## 3. Cut the approved intervals

Invoke `/video-cut`. For each interval, calculate `DURATION = END - START` from its approved numeric bounds. Substitute actual numbers for the bracketed placeholders below; the placeholders are not runnable values. Repeat with `clip-02.mp4` through `clip-05.mp4`. FFmpeg documents input seeking, duration, explicit stream selection and [no-overwrite output behavior](https://ffmpeg.org/ffmpeg.html). Transcode rather than stream-copy for the intended cut bounds.

```shell
set -e
test ! -e clips/clip-01.mp4
ffmpeg -ss <START_SECONDS> -i source.mp4 -t <DURATION_SECONDS> -map 0:v:0 -map 0:a:0 -c:v libx264 -c:a aac -n clips/clip-01.mp4
test -s clips/clip-01.mp4
```

Probe each actual clip's streams and duration, inspect its first and last frames, then watch it whole. Record its hash and approved source interval. A wrong cut needs newly approved bounds and a new output name. If a command fails or its result is uncertain, inspect the existing file and probe before rerunning anything; never direct a retry into the same name.

## 4. Correct captions against each actual cut

Invoke `/video-caption`. Transcribe each accepted clip, because its subtitles need time zero at the clip start. For clip 01, the commands are:

```shell
set -e
test ! -e captions/clip-01.wav
test ! -e captions/clip-01.srt
ffmpeg -i clips/clip-01.mp4 -map 0:a:0 -ar 16000 -ac 1 -c:a pcm_s16le -n captions/clip-01.wav
test -s captions/clip-01.wav
"$WHISPER_CLI" -m "$WHISPER_MODEL" -f captions/clip-01.wav -l "$LANGUAGE" -osrt -of captions/clip-01
test -s captions/clip-01.srt
```

Repeat with the actual matching two-digit number for 02 through 05 and distinct paths. Preserve each raw `captions/clip-NN.srt`. The editor compares every cue with that clip, fixes words, names and numbers, checks timing and readability, and saves `captions/clip-NN.checked.srt`. A cue beyond the clip's duration blocks rendering. Record each SRT's hash against its clip hash. If a cut changes, regenerate or recheck its captions against the new file.

## 5. Reframe, render and accept all five

Invoke `/video-vertical`. For each accepted clip, examine the decoded image, orientation, sample aspect ratio and motion. The editor chooses that clip's own even integer `CROP_W`, `CROP_H`, `CROP_X`, `CROP_Y`. The rectangle must fit the decoded frame. A fixed crop does not follow a moving subject; if it loses essential content, choose a reviewed scale-and-pad framing plan or revise the cut. Unclear rotation or crop coordinates stop the render. The [FFmpeg filter manual](https://ffmpeg.org/ffmpeg-filters.html) documents crop, scale, pad and the libass-backed subtitles filter.

From the established run directory, set `CLIP` to the actual two-digit number and the four crop variables to that clip's approved integers. The command is a template, not a tested example. Keep the simple relative subtitle path shown here; special characters in filenames need separate filtergraph escaping. Repeat independently for 02 through 05.

```shell
set -e
setopt noclobber
CLIP=01
CROP_W=<CHECKED_EVEN_INTEGER>
CROP_H=<CHECKED_EVEN_INTEGER>
CROP_X=<CHECKED_EVEN_INTEGER>
CROP_Y=<CHECKED_EVEN_INTEGER>
test ! -e "shorts/short-${CLIP}.mp4"
test ! -e "probes/short-${CLIP}.json"
ffmpeg -i "clips/clip-${CLIP}.mp4" -map 0:v:0 -map 0:a:0 -vf "crop=${CROP_W}:${CROP_H}:${CROP_X}:${CROP_Y},scale=1080:1920:force_original_aspect_ratio=decrease:force_divisible_by=2:reset_sar=1,pad=1080:1920:(ow-iw)/2:(oh-ih)/2,subtitles=captions/clip-${CLIP}.checked.srt" -c:v libx264 -pix_fmt yuv420p -c:a aac -n "shorts/short-${CLIP}.mp4"
test -s "shorts/short-${CLIP}.mp4"
ffprobe -v error -show_entries format=duration:stream=index,codec_type,codec_name,width,height,sample_aspect_ratio -of json "shorts/short-${CLIP}.mp4" > "probes/short-${CLIP}.json"
test -s "probes/short-${CLIP}.json"
```

For each of the five JSON probe files, require a video stream at 1080 × 1920 with sample aspect ratio 1:1, an audio stream, and a positive duration consistent with its approved cut after encoding/frame rounding. A missing or unknown value is unresolved. [ffprobe's JSON output](https://ffmpeg.org/ffprobe.html) checks file properties, not edit quality. Reopen and watch every entire MP4, comparing it with the source interval, accepted cut and checked SRT. Check sentence boundaries, captions (including safe placement), framing through motion, audio sync, facts and rights. Record accept, revise or reject with UTC time in the manifest. Five accepted files, each linked to its source hash, approved interval, clip hash, checked SRT hash and probe JSON, complete the task. Four accepted files do not.

## Limits and recovery

Claude Code access may be subject to a plan or API charge and usage limits. A downloaded local model, transcription, transcoding and multiple revisions consume storage and compute. Record actual charges if the account exposes them; unknown cost is not zero. No speed, accuracy, caption quality, savings or popularity outcome has been measured for this recipe.

Preserve the original and accepted artifacts. On a missing model, unsupported option, bad transcript, failed render or uncertain write, check the exact input hashes and existing file before changing anything. Repair the specific cause, give the revision a new path, and run its probe and full playback again. Do not upload or share a finished short until the human editor has accepted its content and rights.

## Sources

- [Claude Code skills](https://code.claude.com/docs/en/skills) — Anthropic documents project SKILL.md, manual invocation and that allowed-tools grants temporary prompt-free tool use. It does not establish any video workflow outcome.
- [Claude Code permissions](https://code.claude.com/docs/en/permissions) — Anthropic documents a distinct permission system. Skill prose does not enforce a media-access or upload boundary; users must review account and project settings, including read-only access that may occur without prompts.
- [whisper.cpp README](https://github.com/ggml-org/whisper.cpp/blob/master/README.md) — Maintainer build/model guidance and the current whisper-cli example describe the 16-bit WAV input prerequisite and FFmpeg conversion. Check the installed build and model separately.
- [whisper.cpp CLI README](https://github.com/ggml-org/whisper.cpp/blob/master/examples/cli/README.md) — The maintainer CLI lists -m, -f, -l, -osrt, -oj, -of and -tr. The guide sets a verified language and leaves translation off; local transcription does not guarantee correct words or timing.
- [FFmpeg command-line documentation](https://ffmpeg.org/ffmpeg.html) — Reference for input seeking, -t, explicit -map, transcoding and -n. Actual bounds and output require inspection; stream copy is not the prescribed cut mode.
- [FFmpeg filters documentation](https://ffmpeg.org/ffmpeg-filters.html) — Reference for crop, scale, pad and subtitles. The subtitles filter requires libass and supporting libraries; check that the installed build exposes the required scale options.
- [ffprobe documentation](https://ffmpeg.org/ffprobe.html) — Reference for machine-readable stream and format output. A probe cannot establish cut context, caption legibility, sync, factual accuracy or rights.
- [Find the spoken moment before editing a video](https://bigchange.ai/blog/find-spoken-moment-before-video-editing) — Related BIG CHANGE coverage locates timestamped transcript passages. This guide continues through five approved cuts, local captions, vertical rendering and full review; it is a distinct task, not a dated continuation.