---
name: koubo-video
description: "Make 40–90 second vertical talking-head voiceover videos (live presenter / digital-human inset / all-graphics all work): fix aspect ratio, duration and word count → six-part structure → capsule subtitles → change the picture every 5 seconds → five-layer overlay kit → audio mix → quantified acceptance with scripts. Use when the user says 'make a talking-head video', 'turn this script into a vertical talking-head piece', 'a 45-second knowledge talking-head', 'digital-human talking-head', 'this talking-head looks too much like a PPT', 'how fast should I speak in a talking-head', or when producing a vertical final cut with the local video/ pipeline. Not for pure editing (clip-skills / video-editing), pure voiceover (local-audio), or long landscape tutorials."
---

> Original skill · commissioned by the user · English edition, 2026-11-12

# Vertical Talking-Head Video (40–90 seconds)

**One-sentence principle: give the result first, then the reason; change the picture every 5 seconds, one subtitle sentence per screen, speak at a talking pace.**

## Fix three numbers before you start (get them wrong and all the rework comes later)

| Number | Value | Cost of getting it wrong |
|---|---|---|
| aspect ratio | 1080×1920 (9:16), no letterboxing in the master | a landscape master fills only half of the first vertical screen |
| duration | 45–90 s per piece | forcing 3 minutes of content into one piece forces the pace to 6 characters/second, like a newsreader |
| word count | duration × 4.2–4.8 characters/second (45s ≈ 190–215 characters, 90s ≈ 380–430 characters) | writing first and dubbing afterwards leaves the voiceover only able to speed up, and all the human feel is lost |

## Six-part structure (45-second version, marked in seconds)

| Part | Duration | Role |
|---|---|---|
| hook | 0–5s | one sentence giving the result or the conflict. **Not a table of contents** ("today I'll cover three methods" = wrong) |
| CTA up front | 0–2s | optional; "like and save this first" only gets taps when it comes before the information |
| how to | 12–18s | 3–4 demo points, one card per point |
| difference / boundary | 6–8s | why it is not some other tool; what it cannot do |
| coverage | 8–10s | which classes of work it handles, one nine-grid or list card |
| persona + closing CTA | 5–8s | "I'm Y, I do X — drop the keyword in the comments" |

## Hard metrics (no gut feeling, run the script before delivery)

| Item | Threshold | If it fails |
|---|---|---|
| speaking rate | 4.2–4.8 characters/second | **cut words**, do not speed up (speeding up = newsreader tone) |
| single subtitle line | ≤14 characters, one line | break at the points where you "speak", not at punctuation; drop filler words |
| picture change | at least once every ≤5 s; a longest gap >8s counts as a PPT | swap the card / page / big headline / before-after comparison; do not rely on camera moves |
| first screen | the first sentence is the hook, and there is a picture change within 5 seconds | rewrite the opening; do not add an intro |
| loudness | −16 LUFS (±1), true peak ≤−1.5 dBTP | re-run the audio mix |
| encoding | 30fps, ≥6 Mbps (target 8–10), AAC 192k, no letterboxing | re-export |

```bash
python scripts/check_delivery.py finalcut.mp4 --srt subtitles.srt      # any red item means no release
python scripts/check_delivery.py finalcut.mp4 --script script.json --json
```

A script exit code of 1 = there are FAILs. **The only two things it cannot measure are whether the content is good and whether it has human feel** — those are covered by the counter-example table below.

## Five-layer overlay kit (every layer solves one concrete problem)

| Layer | Position | What it solves |
|---|---|---|
| product identity card | top left | within 3 seconds the viewer knows which tool is being discussed |
| UI screenshot card | right side, stacked vertically | proves "this thing really exists" |
| two-line big headline | centre, second line white on a colour block | with sound off, the text carries the information |
| subtitle capsule | 120px above the bottom safe area | silent viewing |
| CTA sticker | top left / centre | interaction prompt |

Five is the ceiling. A sixth layer will always cover the face — to add one, remove one first.

## Counter-examples: these four relapse most often

| Wrong way | Consequence | Correct way |
|---|---|---|
| 6 scenes each held for 30s, with only a slow push-in | 3 minutes with only 6 change points = a PPT | 2–4 images per scene, each ≤10–12s |
| write the script first, then speed up the TTS when it overruns | 5.5–6.4 characters/second, newsreader tone | compute the word-count ceiling at 4.5 characters/second first |
| open by announcing the course structure | viewers drop off in the first 3 seconds | the first sentence gives the result or a failure scene |
| record landscape, publish vertical | only half the frame is usable | master in 9:16 directly; landscape is only for secondary distribution |

Original-clip measurements, item-by-item evidence and recomputation commands are in [references/reference-breakdown.md](references/reference-breakdown.md).

## Which pipeline to use

- The local `video/` (engine + build_audio.py + build_timeline.py + render.js) produces the piece; for how the vertical template and the rhythm controller hook in, see [references/engine-hooks.md](references/engine-hooks.md). **The current engine only has 16:9** — adding a vertical template comes first; do not render landscape and crop it.
- Need editing technique / B-roll → `clip-skills`; pure voiceover → `local-audio`; subtitle alignment → `agent-caption`; publishing → `release-manager`.

## Change the picture every 5 seconds: generate the images, do not hand-draw cards

Picture cards come from Volcano Ark Seedream; stop padding 5 seconds with colour-block cards:

```powershell
# write visuals.json in the work dir: {"aspect":"9:16","items":[{"scene":"pit","count":2,"prompt":"…"}]}
python video\tools\gen_visuals.py --dir video\work\<slug> --dry-run   # look first, costs nothing
python video\tools\gen_visuals.py --dir video\work\<slug>             # generate → assets\<scene>_<i>.jpg
```

- Lock 1080×1920 for vertical (the model defaults to 3:2, which ruins the asset); the default is `doubao-seedream-5-0-pro-260628`, with automatic fallback to 4.0 on a 404.
- The key is discovered automatically from the user-level environment variable, **no manual setup needed**.
- After generation, `build.ps1 -Size 1080x1920` picks the vertical template automatically; no engine change needed.
- Reference price 0.2 CNY per image, so the 6–10 images of one talking-head piece ≈ 1–2 CNY; report the image count to the user before generating.

## Delivery

1. Run the checker and paste the result table into `00-delivery-notes.md`.
2. Append any new deviation to [references/failure-log.md](references/failure-log.md) as "symptom → criterion → fix", one line each.
3. The final cut goes to `douyin/<YYYYMMDD>_<topic>/`, named per the workspace convention; reply with absolute paths and the files that can be published as-is.

## References

- [references/reference-breakdown.md](references/reference-breakdown.md): item-by-item measurement of a 45s reference clip (27 sentences / 4 hard cuts / 9 change points / letterboxing / recomputation commands)
- [references/engine-hooks.md](references/engine-hooks.md): the 7 changes that hook vertical framing, capsule subtitles and the 5-second rhythm controller into the existing engine
- [references/failure-log.md](references/failure-log.md): the log of past failures (write a new deviation here first, then decide whether it belongs in the body)
