Turn several segments in the rough cut (opening, feature summary, ending) intofull-screen 16:9 animated pages, which the user can directly use to cover the video track on the timeline, then overlay their own avatar and subtitles.
Architecture in one sentence: write the scene once (broll/scenes.js, string HTML + data-a declarative animation + semantic sound effects), rendered frame by frame by broll-core.js ; the preview page and Remotion run the same code, so what the user confirms in the preview is the final video. The template (layout and motion choreography / color scheme / fonts / sound palette / music) is a replaceable layer: the scene only writes content (use + data), and changing the template means changing an entire set of composition and rhythm, see theme presets。
Input
| Input | Required | Description |
|---|---|---|
| SRT subtitles | Required | Subtitles of the rough-cut talking-head video |
| Master video / talking-head mp3 | Auto-find | File with the same name as the SRT. Read frame rate, resolution, total frames; capture a frame to measure avatar and subtitle positions; cut the talking-head audio for preview sync |
| Time range | Optional | Users usually write it as HH:MM:SS or 分:秒:帧. If not provided, recommend one yourself; snap to subtitle boundaries |
| Theme | Optional | Use it if the user has selected one in the theme library; for the same episode, continue using the previous segment's theme; if neither, offer 2–3 sets in the preview |
| Assets | Optional | Official website / product page (captured with ego-browser), the user's own AI-generated videos, screenshots. Prefer real assets |
Anything missing is handled by default. Only two cases require asking: the SRT cannot be found, or the master is at a non-integer frame rate. Do not ask about resolution or frame rate if they can be read; web pages default to ego-browser; endings default to fade out.
Process
- Understand the subtitles and define segments. Follow read subtitles and select segments:
srt_segments.py listto read through, write an understanding within 200 characters, organize an errata table, identify brands, and collect logos (lobehub). Snap ranges to subtitle boundaries and list a table of "why it is cut this way". - Create the project.
python3 <skill>/scripts/init_project.py --srt <X.srt> --video <X.mov> --out <视频目录>/broll-remotion \ --seg "00:00:00-00:36:22=标题" ... --theme paper-signal [--from <上一段工程>]--themeFollow the B-roll architecture, generatesrc/segments.json(the single source of time data), a replacement mapping table, each segment's talking-head audio,src/broll/theme.lock.json、broll/scenes.jsstarter files, a silent placeholder mix, and run fonts and build once. For subsequent segments in the same episode, always use--from(symlink node_modules, reuse the theme and fonts). - Measure avatar and subtitles. Capture a frame from the master, measure the avatar circle and the subtitle line (in 1920 coordinates), and write them into
broll/overlay.json(The preview page's overlay toggle reads it). The layout still fills the frame as usual, only letting text and key information avoid these two areas. Measured in episode 414: avatar circle x1523–1858 y55–395, subtitle line x410–1510 y905–965, content area approximately 90,110 → 1830,920. - Prepare materials. Video clips
extract_clips.py(preview mp4 + final frame sequence), screenshots and logos go inbroll/assets/(build syncs to both preview and Remotion); for content not yet generated usesketchify.pyto make pencil storyboards, and swap to color original footage once the voiceover reaches it. - Write scenes → preview page. Follow preview page to write
broll/scenes.js: one thing per page, usecue:'字幕原文'to anchor time, sound effects are written in the scene'ssfx. Then:
local screenshot self-check (python3 <skill>/scripts/fetch_fonts.py <工程> python3 <skill>/scripts/build_broll.py <工程> --preview#s=段&t=秒), then publish with Artifactpreview/index.html(root=<工程>/preview,filesuse the list inpreview/files.json), and give the link to the user. When there is no Artifact tool (for example in Codex), run<工程>/previewunderpython3 -m http.server, and give the local address to the user.This is the only point where you stop and wait for confirmation. For changes, resend the same file_path; the link stays the same. - After confirmation, go all the way to delivery. Follow Remotion production:
python3 <skill>/scripts/build_broll.py <工程> --remotion <venv>/python <skill>/scripts/broll_audio.py <工程> node scripts/stills.mjs seg0:0,300,900 && python3 scripts/sheet.py ... # 看拼图 npm run render - Delivery. Follow delivery:
check_delivery.py <工程> --copy-to <素材目录>/B-roll成片. In the reply, list the files, state what was verified and what was not (no audio previewmust be stated explicitly).
Hard constraints
- Full screen, no shrinking the image. The image always fills 16:9, and frame 0 is the complete stage. The avatar and subtitles are only overlays: only avoid the measured avatar circle and that one subtitle line, leave no large safe area, and do not shrink into a small window.
- Do not use the default graphite pink-orange. By default use primary-selection paper white signal orange, or choose from the 10 sets in the theme library according to the topic; all segments in the same episode use the same theme, variant, timbre and loudness. Get the logo from lobehub and keep the brand colors.
- The image must have real content. Official website screenshots, works, real numbers, the user's AI clips; only large text and labels will be considered "monotonous"; replace abstract metaphors with concrete comparisons.
- After confirmation, finish it all the way. Do not stop again to write a plan; the user has already urged "get to work".
- Sound: theme foley + score, 16 dB below the voiceover, true peak ≤ -14 dBFS. Do not use booms, impacts, falls or glitches. The final cut does not contain the voiceover (unless the user explicitly requests it). See sound。
- One set of timing data. Ranges come from
segments.json; scenes usecue:'字幕原文'for anchoring; sound effects are written in the scenes, build exports the timeline, and the score plan follows the scenes. Do not hand-write frame numbers. - Frame counts and naming are exact. Each segment's frame count equals the range length; file names
{序号}_{标题}_{SRT起}~{SRT止}_字幕{a}-{b}.mp4, precise to the millisecond; include a replacement comparison table. Deliver MP4 only. - Copy is restrained. Only write conclusions stated in the voiceover, with consistent force; illustrative images (sliders, progress bars, clocks) should be noted as metaphors at delivery.
- Accept if it passes the test. The script can only prove frame count, naming, and loudness; you have to look at the visuals yourself to piece it together; if you haven't listened to the audio, say you haven't listened to it.
Resources
| Path | Purpose |
|---|---|
assets/themes/<id>/{theme.json,theme.css,layouts.js} |
10 sets of templates (_archive/ are candidates that were not selected and old presets) |
assets/engine/broll-core.js · base.css |
Frame-by-frame engine and component structure (shared by preview + Remotion) |
assets/engine/preview-shell.html · Broll.tsx |
Preview page shell; Remotion components |
assets/gallery/ |
Theme library page: local preview serve.py; build build.py <out>(used for publishing Artifacts); single-template self-check qa.py <id> <out> [--stress] |
assets/starter/ |
Remotion project template (TSX component library mg.tsx / stage.tsx is only used in highly customized comparison sections) |
scripts/srt_segments.py · init_project.py |
Full subtitle read-through / interval data; build project (--theme、--from) |
scripts/build_broll.py |
scenes.js + theme → preview page / Remotion engine.js, style.ts, timeline, clips |
scripts/extract_clips.py · sketchify.py · fetch_fonts.py |
Video frame sequence; pencil storyboard; font subset |
scripts/audio_lib.py · broll_audio.py · theme_demo_audio.py |
Voice library + soundtrack; final mix; theme library audition |
scripts/check_delivery.py |
Delivery check + copy |
references/pitfalls.md |
User's original wording corrections and technical pitfalls,read through once before starting |