---
name: knowledge-short-pipeline
description: Complete pipeline for a landscape (1920×1080) knowledge short video: topic decision → footage sourcing → talking-head script → Doubao voiceover → graphic cards → composite → dual-aspect-ratio covers + publish copy. Use when the user wants a "knowledge short video", "a one-minute landscape explainer", "turn a hot topic into a 1-minute video", "a Douyin knowledge short", or asks for the level of the pipeline's existing reference cuts. Not for pure editing, pure voiceover, vertical talking-head video (that is koubo-video), or WeChat Official Account / Xiaohongshu image posts. **Question 0 before work (hard gate set by the user)**: for every claim, list the real footage first and go find each item; if you cannot find it, delete the sentence or change the claim — illustrations and pure procedural cards are forbidden as substitutes; write the script only after the footage is locked; animation does transitions and number emphasis only, never the lead; besides the technical metrics, acceptance must answer "are these few seconds worth watching".
---

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

# Knowledge short-video pipeline (landscape · 56-second format)

A film's quality is composed of **topic 60% · footage 30% · technique 10%**. The process is fixed, the metrics are locked, and what remains is judgment.

## Five stages

| # | Stage | Output | Hard requirement |
|---|---|---|---|
| 1 | **Footage** | `footage.mp4` | 1920×1080 landscape; no watermark, station logo or burned-in subtitles |
| 2 | **Script** | `script.md` | 4.9 characters/sec; three acts; every paragraph tagged with its visuals and **motion elements** |
| 3 | **Voiceover** | `voiceover.wav` | **Measured** 4.9 characters/sec (±0.1); single voice |
| 4 | **Graphic cards** | `cardNN.png` | 1920×1080; one point per screen |
| 5 | **Composite** | `final.mp4` | −14 LUFS / true peak ≤−1.0 / bt709 / 30fps |

Ship these alongside the same batch: **covers (one 4:3 and one 3:4)**, publish copy (title ≤15 characters / description ≤50 characters), SRT subtitles.

## Last resort: the all-motion-graphics route (added later, downgraded to a last resort)

> **Clear question 0 first** (see the description; set by the user): for every claim, list the real footage first — a UI screenshot, an issue page, the original text of an official doc, a real terminal, a single frame from a tutorial all count as footage, so go and get it. **If you cannot find it, delete the sentence or change the claim**; do not switch straight to full procedural generation.
> Take the route below only when "this sentence genuinely has no verifiable real image and does not stand without it", and then: (1) report the procedural shot share in `00-delivery-notes.md` (e.g. "2 of 13 shots are procedural"); (2) when the user says "too dark / too ugly / change the background colour", audit the real-footage share yourself first — **changing colour is not changing content**. A past delivery failed exactly here: 12 of 13 shots were procedural, every technical metric passed, and the user judged the film "empty".

Software launches and pure-data topics often have **no first-hand video** (Bilibili only has creator voiceovers; official clips carry station logos). In that case:

- Generate 100% of the visuals procedurally (Pillow frame by frame → ffmpeg segmented encoding → concat); 13 scenes can carry 2.5 minutes with no watermark or station-logo risk.
- Then **do not write `_footage.mp4`** into the delivery, but state "no external footage" and the reason in `00-delivery-notes.md` so the next person does not go looking for a file that does not exist.
- `make_cover.py` depends on a `--bg` image and this route has none, so draw the cover yourself (a dark panel + numbers + a stamp is enough), still as two versions, 4:3 and 3:4, from the same visual system.
- Reference implementation: `<WORKSPACE>/<project>/` (render.py / kw_times.py / mix.py / cover.py); keyword timing is computed as "the word's character offset in the line ÷ segment length", with a measured error of ≤0.2s.
- **The pitfall you will hit**: PIL's `ImageDraw` writes pixels directly onto an RGBA image without alpha blending, so text with alpha=0 survives `convert("RGB")` as a "ghost" character. You must `alpha_composite` back onto the background and zero out pixels with alpha<8; wrapper functions such as `txt()` must also check the alpha carried in `fill`.

## Topic: clear the heat and participation gate first (revised later)

**The one-line standard: an ordinary person can connect it to their own life, can take a side in the comments, and can understand it in 3 seconds.**
Counterexamples: `etch selectivity 700:1`, `24-layer glass substrate` — technically airtight, editorially dead: an outsider will not click, and cannot join the conversation.

Six-item scoring (0/1 each); **≥5 points, and "participatory" and "clickable" must both be 1**:

1. **On the chart**: top 50 of the Douyin trending chart, still rising that day
2. **Participatory**: viewers can add "my…", "in my house…", "I bought one…"
3. **Clickable**: the title is clear in 3 seconds, no industry prerequisite knowledge
4. **Cost of projecting yourself in**: money / family / health / phone / salary / housing / children
5. **First-hand wording**: official bulletins, statements from the parties involved, checkable numbers
6. **Has an increment**: the ending lands on an action or a counter-intuitive number

Penalties (2 or more hits = change the topic): needs jargon; only insiders care; no disagreement in the conclusion; no first-hand footage available.

## Topic: three bonus conditions

1. **A counter-intuitive number** — one sentence that carries a quantity that makes people go "huh?"
2. **A specific person** — named, with actions, identifiable
3. **A verifiable source** — official release / authoritative outlet / the person's own words

These three are bonuses and cannot substitute for the two vetoes above. One more: **search once, and if the top three results are all press releases, change the topic**.

## Key parameters

```text
final      1920×1080 / 30fps / H.264 CRF16 / yuv420p / bt709 tv
audio      AAC 320k / 48kHz / stereo / −14 LUFS / true peak −1.5 dBTP
speech     4.9 characters/sec — this is an outcome, not a parameter
BGM        coverage ≤40%, entry point ≥6s, sidechain duck threshold 0.02 / ratio 8
palette    #0E0F12 base / #FF6B1A accent / #F5F5F5 body copy
cover      4:3 = 1920×1440, 3:4 = 1080×1440, both from one visual system
```

## Footage first (established after a past delivery failure; outranked only by topic)

**The fatal mistake: write the script first and fill every cell with animation at the end.** The film that comes out is 100% self-drawn illustration, the viewer has nothing checkable to hold on to, and changing the black background to white will not save it.

**Correct order**: list the footage → collect it all → then write the script → animation does transitions and emphasis only.

1. **List it first**: lay out every claim and write down "what is the real image of this sentence". Write the sentence only if you can find a source.
2. **Footage is a wider category than you think**: official doc pages, GitHub issues, official announcements, real terminal recordings, product UI screenshots, news footage, a single frame from a tutorial all count. Do not stare only at "video I can drop into the frame whole".
3. **If you cannot find it, delete the claim**; do not substitute an illustration. Better to cover one pitfall fewer than to pair every pitfall with an image I invented.
4. **Real footage share ≥60%** (counted by shot). Below that, go back and ask whether the script ran away.
5. **Screenshot layout**: after placing a screenshot in the layout, leave room for a Chinese annotation to its right or below; highlight key sentences with a "highlighter" (a semi-transparent fill must be `alpha_composite`d back onto the layer; `rectangle(fill=(r,g,b,60))` directly paints the text block out); the highlight needs an expansion animation, otherwise it looks like a static slide.
6. **Animation has only two jobs left**: explain concepts with no physical form (layers, order, before/after), and do transitions. Numbers may be emphasized with animation; content statements may not be replaced by animation.

**Footage technique**: direct download from Bilibili with yt-dlp is the most stable; Douyin / Xigua / Weibo need a login state, so do not burn time — use `video-downloader` or a screen recording for the clip instead. For watermarks, **crop the top 100–140px rather than delogo** — a blurred block looks worse than a crop. Burned-in subtitles in a broadcaster's final cut cannot be removed; change the source. For your own terminal and UI recordings use `ffmpeg -f gdigrab -i desktop` to record full screen, then crop the title bar and taskbar in post.

## Acceptance: first ask "are these 8 seconds worth watching"

All technical metrics (alignment, overflow, duration, loudness, LUFS) green ≠ the film is watchable. Check shot by shot before delivery:

- Does this shot contain something **I did not draw** (a screenshot, a recording, a document)?
- Can viewers pause, point at the frame and say "this is real"?
- If this shot were pulled and replaced with a text card, what would the viewer lose? If the answer is "nothing", delete it.

**Speech rate**: a TTS "rate parameter" and the actual characters/sec are two different things. The order is always: generate → measure with ffprobe → compute characters/sec → adjust and re-run. Guessing from the formula always drifts (measured deviation has reached 30%).

**Timeliness**: the first thing when writing is to establish whether the event is past, present or future tense. A future-tense script must hard-code its expiry date (a script about an upcoming event was void the moment its date passed and the run began).

## Cover

The dual-ratio, single-visual-system method and layout parameters are in `references/cover-design.md`; generation uses `scripts/make_cover.py`.
**Do not** ship only one 16:9 cover — the delivery requires a 4:3 landscape cover + a 3:4 portrait cover.

**Before starting, read the "platform measurements" section of `references/cover-design.md`** (a stratified sample of 11 Bilibili category charts × top 3): the cover subject is decided by category, not by faces; brightness follows the category (knowledge averages 102 mean / 31% dark, music 161 / 9%), so do not brighten everything or darken everything. A portrait cover must use portrait-composition footage; hard-stretching a landscape image to 1080×1920 goes soft. Sample images live in `<WORKSPACE>/outputs/<batch>/`.

## On-screen motion

Every paragraph of the script must tag its **motion elements**: numbers slamming in, cards flipping in, arrows and circled annotations, progress bars, keyword stickers. Motion elements sync with the spoken keywords (when the line says "500.01" the number must appear on that same frame); no decorative animation unrelated to the content.

**The full rules for shot rhythm and collage style are in `references/collage-and-motion.md`** (distilled from vox-director, MIT). Three to memorise first:

- **Two-shot beats**: split one beat into "wide shot (with title) + detail shot (without)"; a single shot runs 3–6s, **never over 7s**; 60s ≈ 12 shots rather than 6 long shots.
- **Adjacent shots must not share a motion**: alternate by family (push/pull ↔ pan ↔ static), and **reserve static for the payoff or key-line shot**.
- **The style is decided at the image-generation step**: torn paper / tape / halftone / big-type headlines must hold inside the image; write scenes as "layered collage blocks", otherwise parallax will not work later and all you have is a moving slide deck.

## Before you start

1. Read `<platform>/INDEX.md` to avoid repeating a topic
2. Read the latest `00-delivery-notes.md` for the previous round's specs and pitfalls
3. Verify the voiceover chain: `scripts/check_vo.py --srt <srt> --voice <wav>`

## Delivery checklist

```text
<WORKSPACE>/<platform>/<batch>/
  00-delivery-notes.md
  <YYYYMMDD>_<topic>_script.md
  <YYYYMMDD>_<topic>_footage.mp4
  <YYYYMMDD>_<topic>_final.mp4
  <YYYYMMDD>_<topic>_voiceover.wav
  <YYYYMMDD>_<topic>_cover_4x3.png
  <YYYYMMDD>_<topic>_cover_3x4.png
  <YYYYMMDD>_<topic>_cardNN.png
  <YYYYMMDD>_<topic>_subs.srt
  <YYYYMMDD>_<topic>_publish_copy.md      # title ≤15 chars + description ≤50 chars + hashtags
```

## Reference sample

`<WORKSPACE>/<platform>/<batch>/` holds one complete set to compare against (56.5s / 4.90 characters per second / −13.9 LUFS / dual cards / Doubao voiceover).
