Skip to content

feat: shorten a run from a request to the MP4 - #45

Merged
umiyosh merged 6 commits into
masterfrom
feat/issue-44-faster-runs
Nov 5, 2026
Merged

umiyosh merged 6 commits into
masterfrom
feat/issue-44-faster-runs

Conversation

@umiyosh

@umiyosh umiyosh commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Why

In #44's benchmark, a 2-minute explainer took 17 min 20 s, Claude's own writing took about 75% of it, and writing the HTML film alone took 8 min 37 s. The narration and sound effects were also generated one at a time.

With this PR the same benchmark film takes about 11 min 35 s.

What changed

  • Narration and sound effects run in parallel. TTS runs 4 scenes at a time and ElevenLabs runs 3 effects at a time. An HTTP 429 now waits for the delay the API asks for (Gemini RetryInfo, Retry-After) and does not use up an attempt.
  • BGM and sound effects run in the background. The skill makes the sound effects from plan.md while the film is still being written. An effect is keyed by prompt and duration, so moving its at later costs nothing.
  • Scenes are written in parallel. Claude first writes <work>/plan.md, the storyboard with every motion's film.at seconds, and the shared index.html. Subagents, one per two scenes (at most 7), then write film/scenes/NN-name.html at the same time. The runner puts these files in at the <!-- scenes --> line. motion-render check <film> <file> checks one file's scenes alone.
  • Kit parts (kit/parts.css, plus film.light, film.ticks and film.caption) for the shapes every explainer redraws: step rows, cards, time lanes, rulers and captions.
  • motion-render times <work> prints a per-step table. Each command logs its span to <work>/steps.jsonl, and the time between commands is counted as Claude's.
  • references/pipeline.md says which step waits for which, and how to add a step. This is the handoff to Plan the music with the animation and score the BGM to its timing #42.

Kit fixes found by the scene writers

  • A ruler tick was centered with transform, which film.spot does not count, so a chip sent to a tick landed half a tick off. Ticks are now centered with a negative margin. A test checks that a chip sent with film.spot lands on the tick.
  • On a lit .card, .card-body text (--muted) fell to 4.1:1 contrast. Three writers hit this separately. The body now darkens to --ink as the card lights. The test fails without the fix.
  • plan.md should name places by id, not by coordinates: the step cards' centers in the first plan were off because one card is wider. html-film.md now says so.

Fixes found by making the v1.1.0 promo with this branch

  • check now prints the page's own errors as runner … lines, as stills already did. A scene writer built an SVG path from NaN. The path drew nothing but broke no layout rule, so check, which is the only check the writers run, passed it.
  • times printed 179.6 s as "2 min 60 s". It now rounds to the whole second first.

The promo (121 s, 14 scenes, 7 writers) took 14 min 11 s from an empty work dir. The slowest writer took 8 min 16 s (29 tool calls), and the other six took 3 min 28 s to 5 min 25 s.

CI runner (#46)

ubuntu-latest moved to Ubuntu 26.04, and playwright-core 1.56.1 has no Chromium for it, so CI failed at the Chromium install on every PR. The job is pinned to ubuntu-24.04. The bundled Chromium is unchanged, so rendering and #29 are unaffected. Upgrading Playwright is left to #46.

Verification

  • tsc, ESLint, Prettier, quality baseline (no new violations), quality-gate tests (21 pass)
  • Vitest: 133 pass, coverage 97% (new: inParallel, rate-limit waits, the step log and the times command, scene files and per-file check, kit parts)
  • Both benchmark films pass check with layout: ok, and the stills of all 14 scenes show nothing broken across the writers' file boundaries
  • ffprobe: video and audio tracks, 116 s

Benchmark

This is the #44 benchmark film: the motion-render pipeline, in Japanese, 14 scenes, an HTML film with narration, BGM and sound effects, on the same 14-core Mac. The new film is 116 s long (the old one was 119.8 s) and has 53 sound effects in 8 distinct sounds (the old one had 44). Neither run needed any BGM rework.

Step 1.0.0 (#44) Run 1: 4 writers Run 2: 7 writers
Prep and script 2 min 13 s 20 s ¹ (same as run 1)
Narration (14 scenes) 1 min 14 s 16 s (same)
BGM 29 s, in parallel 28 s, background (same)
Plan and shared index.html (new) — 3 min 34 s (same)
Sound effects (8 sounds) 27 s 6.5 s, background (same)
Write the scenes 8 min 37 s 9 min 24 s (slowest writer: 8 min 40 s) 5 min 31 s (slowest: 5 min 15 s)
check with fixes 1 min 4 s inside the writers' step inside the writers' step
Stills review and fixes 1 min 58 s 54 s 38 s
build 1 min 31 s 1 min 7 s 1 min 6 s
Total 17 min 20 s 15 min 46 s ≈ 11 min 35 s ²

¹ The skill had already been read and the scenes outlined before the clock started (the clock starts when the work dir is made). If prep took as long as in 1.0.0, run 2's total would be about 13 min 30 s, which is still 3 min 50 s shorter.
² Run 2 reused run 1's script, audio, plan.md and index.html, and re-ran the scene writing, review and build after the docs were tuned. Its total is run 1 up to the scene step (4 min 21 s) plus run 2 from that step on.

Raw motion-render times output

Run 1 (from an empty work dir):

Start Step Time
0:00 Claude 20.0 s
0:20 narrate 15.6 s
0:35 Claude 11.5 s
0:47 kit 0.3 s
0:54 bgm (background) 28.0 s
3:22 sfx (background) 6.5 s
0:47 Claude 3 min 33 s
4:20 check 1.1 s
4:21 Claude 3 min 7 s
7:28 check 2.1 s
7:30 Claude 11.0 s
7:41 stills 4.2 s
7:45 Claude 30.7 s
8:16 check 2.2 s
8:18 check 2.9 s
8:20 Claude 6.9 s
8:27 stills 6.6 s
8:33 stills 4.8 s
8:38 Claude 59.1 s
9:37 check (failed) 2.3 s
9:39 Claude 10.6 s
9:50 check 3.3 s
9:53 Claude 8.2 s
10:01 stills 7.1 s
10:09 Claude 15.8 s
10:24 check (failed) 3.3 s
10:28 Claude 10.2 s
10:38 check 2.5 s
10:40 Claude 9.5 s
10:50 stills 9.7 s
10:59 Claude 1 min 48 s
12:47 check 4.1 s
12:51 Claude 8.5 s
13:00 stills 7.7 s
13:07 Claude 37.3 s
13:45 check 9.4 s
13:54 Claude 12.1 s
14:06 stills 7.5 s
14:14 Claude 24.5 s
14:38 build 1 min 7 s

total 15 min 46 s: Claude 13 min 3 s, waiting on commands 2 min 43 s

Run 2 (from the copied plan; scene writers start at about 0:40):

Start Step Time
0:00 kit 0.3 s
0:00 Claude 2 min 25 s
2:25 check 2.4 s
2:28 Claude 16.8 s
2:44 check (failed) 3.2 s
2:48 stills 3.9 s
2:52 Claude 3.3 s
2:55 check 2.4 s
2:58 Claude 7.1 s
3:05 stills 6.1 s
3:09 check (failed) 3.2 s
3:13 Claude 5.9 s
3:18 check (failed) 2.1 s
3:21 Claude 1.3 s
3:22 check 3.2 s
3:26 check 2.2 s
3:28 Claude 2.2 s
3:30 check 2.3 s
3:33 Claude 1.8 s
3:34 check 2.7 s
3:37 Claude 7.5 s
3:45 stills 16.4 s
3:50 stills 17.8 s
3:56 stills 14.4 s
4:01 stills 11.9 s
4:13 Claude 44.7 s
4:58 check 2.6 s
5:00 Claude 18.2 s
5:18 stills 8.8 s
5:27 Claude 21.0 s
5:48 check 2.2 s
5:50 Claude 20.4 s
6:11 check 7.6 s
6:18 Claude 7.6 s
6:26 stills 9.3 s
6:35 Claude 13.8 s
6:49 build 1 min 5 s

total 7 min 55 s: Claude 5 min 17 s, waiting on commands 2 min 38 s

What the two runs showed

  • Four writers with 3–4 scenes each were no faster than one writer. Each subagent spends a fixed time reading the docs, and the slowest one also kept re-checking its stills (31 tool calls). Run 1's film step took longer than in 1.0.0 because the new plan step added to it.
  • Two scenes per writer, and one stills pass each, cut the scene step to 5 min 31 s. The other six writers returned in 2 min 24 s to 3 min 45 s. html-film.md now records this rule and these numbers.
  • Cost: each writer uses about 120–150k tokens, so the seven writers spend about 900k tokens per film. html-film.md says so, so the speed-up is a known trade.
  • build is bound by the encoder, not by capture. Capture alone took 28.7 s and capture with x264 medium took 54.7 s for 3,480 frames. With veryfast it took 48.0 s, at 54.5 dB PSNR against medium, and the timings varied by more than 10 s between runs. That saves about 1% of a run, so this PR leaves the encoder as it is. Because build is unchanged, build: two builds of the same html film differ slightly (PSNR about 60 dB) #29 (two builds of the same film differ) is not affected.

Not verified

  • Listen to the finished MP4 (I have not listened to it)
  • A full run from an empty work dir with the final docs (run 2 started from run 1's plan; see note ² above)

Closes #44

@umiyosh
umiyosh merged commit 68037b3 into master Nov 5, 2026
1 check passed
@umiyosh
umiyosh deleted the feat/issue-44-faster-runs branch November 5, 2026 18:04
@umiyosh umiyosh mentioned this pull request Nov 5, 2026
2 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shorten the time from a request to the finished MP4

1 participant