Communitygithub.com

lian4211/video-flow

Transform any content (PDF, PPT, DOCX, Markdown, webpage, video, or a topic) into a code-rendered explainer video: plan the teaching structure, write storyboards and voiceovers, draw every frame with Canvas/HTML `render(t)`, capture screenshots via headless Chrome, encode with FFmpeg, and optionally add TTS narration, background music, soft subtitles, and a QA report.

What is video-flow?

video-flow is a powerful AI agent skill designed to convert diverse source materials—PDFs, PPTs, DOCX files, Markdown, web pages, videos, or even a bare topic—into visually compelling, code-rendered explainer videos. It operates on a rigorous, eight-stage pipeline that begins with analyzing the source to extract a clear teaching structure, then writing storyboard and script files, and finally rendering each frame programmatically using Canvas or HTML. The process leverages headless Chrome for frame capture, FFmpeg for video encoding, and optional TTS for narration, with support for multiple aspect ratios (16:9, 9:16, 1:1, 4:5), five built-in visual styles, and eight general-purpose scene types. This approach ensures pixel-perfect accuracy, complete reproducibility, and the ability to edit individual frames or adjust timing—advantages over generative AI video models. It is ideal for educational, product, or tutorial shorts where content clarity and data fidelity are paramount; it is not intended for generative video AI, live-action editing, or simple script writing without a video output.

Works with~Claude Code~Codex CLI~Cursor
npx skills add lian4211/video-flow

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

video-flow: Code-Rendered General Explainer Video Workflow

In a nutshell: First, think clearly about 'what to teach,' then turn that into a calculable timeline, and finally let the browser draw each frame. Final product = Canvas/HTML render(t) + headless Chrome frame capture + FFmpeg + optional TTS/music/subtitles.

This skill breaks down "a video" into 8 checkable stages. Each stage has an output and an acceptance checkpoint; do not proceed to the next step if any step is unsatisfactory.


0. When to Use / When Not to Use

Use:

  • Turn a PDF, PPT, DOCX, article, webpage, video, or a topic into a 1–5 minute explainer video;
  • Need a video where "text is clear, data is accurate, every frame is editable, and the process is reproducible" (structural advantage of code rendering over generative video models);
  • Need multiple versions (portrait/square/landscape) or multi-language versions;
  • Need narration, subtitles, music, and want the entire workflow repeatable.

Do not use:

  • Need real people/live-action/realistic footage → use video generation models or live footage; this skill only handles "the code layer";
  • Just want to cut existing footage → use editing tools/agents;
  • Only want to generate an MP4 without willing to define storyboards and script → the result will feel templated; it is recommended to do steps 1–2 first.

1. Hard Rules (Violate any, redo)

  1. Every frame is a pure function of time: The page exposes window.render(t); given t, the frame is uniquely determined.
    • Prohibit Date.now(), unseeded random, requestAnimationFrame driven state, CSS transition/animation, cross-frame caching.
    • For cumulative animations (particles/water), push from 0 to t with fixed steps or switch to analytical formulas.
  2. The timeline is the single source of truth: Storyboards, narration, music, sound effects, and subtitles all derive from the same timeline.json.
  3. Storyboard before code: Without storyboard.md and script.json, do not write scene code.
  4. Do not fabricate source facts: Numbers, years, names, and formulas must come from the source material; mark uncertainties with [to verify] and list them separately at delivery.
  5. No branding/watermarks by default: Only if the user provides a logo/brand name; default footer only shows course/topic information.
  6. Encode only once: Complete mixing and loudness in the WAV stage; perform only one final AAC encode; do not re-encode repeatedly.
  7. Must pass QA before delivery: Check for dropped frames, black frames, loudness, duration, subtitles, and audio-sync; see step 8.

2. Input and Output

Input (choose any, can be combined)

TypeProcessing Method
PDFscripts/ingest.py extracts text; for scans/garbled text, automatically rasterize to PNG and let the model "read the pages"
PPTXExtract title, body, and notes per slide; optionally export key slides as images
DOCX / Markdown / TXTDirectly extract as source/source.md
Web URLFetch main text; preserve source link
Videoffprobe metadata + key frame extraction; if no ASR, human supplements content
Bare TopicA sentence/outline from the user; first have the user confirm "facts that must appear"

Project directory contract

<project>/
  project.json          # Metadata: title/audience/goal/aspect ratio/style/voice/music/brand
  source/               # Source materials (source.md, pages/*.png, meta.json)
  storyboard.md         # Storyboard table: what each scene covers, visuals, duration, narration, key points
  script.json           # Machine-readable: scenes[] (type/script/visuals/vo/duration)
  build/                # index.html + lib.js + theme.js + scenes.js + timeline.js
  audio/                # vo/*.wav, bgm, mix.wav
  frames/               # Frame-by-frame JPEGs
  out/                  # final.mp4 / final.srt / poster.png
  qa/                   # report.md + contact sheets + key frames

Use scripts/init_project.py to generate the skeleton at once.


3. Workflow (8 Steps)

Step 0: Environment Check

python scripts/check_env.py

Required: Python 3.10+, FFmpeg/ffprobe, a Chromium-based browser, numpy/scipy. Recommended: edge-tts (online neural voice), pypdf, python-pptx, python-docx, Pillow. Install what is missing per the output prompts; if not installable, degrade (no narration/system voice/hand-written audio).

Step 1: Read Source Material, Extract "Teaching Structure"

Answer 5 questions (write into project.json's brief):

  1. Who is the audience? What do they already know?
  2. After watching, they should be able to say/do what? (1–3 testable goals)
  3. What is the most easily misunderstood/hardest point?
  4. What facts/formulas/data must appear? What are the sources for each?
  5. Duration and aspect ratio? Platform (classroom/mobile/social media)?

Do not follow the original page order. Restructure using one of the 4 storytelling structures from references/storytelling.md:

  • Causal chain (recommended for science/engineering);
  • Problem → Solution → Validation;
  • Misconception → Correction → Transfer;
  • Timeline/process.

Step 2: Choose Style and Aspect Ratio

Select 1 set from references/styles.md (silicon / paper / blueprint / neon / swiss), and define the aspect ratio from references/formats.md. Rules:

  • Content leaning toward "chips/engineering/data" → silicon / blueprint;
  • Leaning toward "humanities/biology/history" → paper;
  • Leaning toward "launch/marketing/youthful" → neon / swiss;
  • One screen, one concept; portrait mode must re-layout, do not crop landscape to portrait.

Step 3: Write Storyboard and Script

Output storyboard.md (for humans) and script.json (for machines). Each scene must include:

  • type (title/concept/process/compare/formula/bars/quote/recap/custom)
  • kicker (subtitle), headline (one-sentence conclusion), points (≤3 items)
  • vo (voiceover, 1–2 sentences; leave blank if no narration)
  • visual (specific data for charts/tables/flows/formulas)
  • duration (can be empty, automatically determined by narration length)

5 hard constraints for writing copy:

  1. On-screen text ≠ narration script: On-screen only key words/conclusions; narration explains.
  2. At most 1 conclusion + 3 supporting points per screen; title ≤ 18 chars, body text ≤ 22 chars per line.
  3. Change every 2–4 seconds (element/camera/emphasis), but no particle explosions.
  4. Write a "forbidden list" first: gradient background + centered big text, fade-in for all elements, full-screen small text, meaningless glows.
  5. Mark factual sentences with sources individually; add [to verify] for uncertainties.

Step 4: Generate Narration and Timeline

# Optional: skip if no narration, just write `duration` for each scene
python scripts/tts.py --project . --voice zh-CN-XiaoxiaoNeural --rate +3%
python scripts/timeline.py --project .
  • tts.py outputs audio/vo/<id>.wav (48 kHz), automatically applies light EQ/compression; supports --from-dir for human recordings.
  • timeline.py uses measured narration durations to generate build/timeline.js and timeline.json: scene.duration = head + voDuration + tail; for scenes without narration, use explicit duration.
  • Afterwards, only modify script.json and re-run these two steps; do not manually edit the timeline.

Step 5: Build the Page and Implement Scenes

Using the template:

python scripts/init_project.py --dir my-video --title "..." --format 16:9 --style silicon
# Edit build/content, generated by timeline.py; generic scenes are already implemented, just modify script.json
  • Generic scenes (8 types) are in build/scenes.js reading CONTENT; sufficient for most explainer videos.
  • For specialized graphics (chips/circuits/anatomy/maps/molecules), write build/custom.js:
    window.CUSTOM['s3'] = function(u, D, sc, ctx){ /* use helpers from lib.js to draw */ };
    
    Set the scene's type to custom in script.json.
  • Work on one scene at a time: first render 3 still frames (scripts/render.py --still 1.2,2.4,3.6), check for text overflow/overlap/subject size, then continue.

Step 6: Rendering

python scripts/render.py --project . --fps 30
# Render only a segment: --start 8 --duration 4
# Reuse an existing Chrome: --cdp http://127.0.0.1:9333
# Let the script launch Chrome: --launch-chrome

Outputs frames/f00000.jpg..., supports resumable rendering (skips existing frames >2KB).

Headless Chrome and sandbox: If the runtime environment prohibits Chrome's IPC/pipe, run in an allowed environment, or connect to an already launched Chrome via --cdp.

Step 7: Music, Sound Effects, Mixing, Subtitles

python scripts/audio.py --project .            # Synthesize BGM + place narration + duck + master
python scripts/srt.py --project .              # Generate out/final.srt
  • No narration: audio.py --no-bgm or use only user-provided music.
  • User provides music: place in audio/music.*; audio.py automatically loops/cuts and ducks.
  • Target loudness default: -14.2 LUFS, true peak ≤ -1.5 dBFS; encode audio only once.

Step 8: Encoding + QA + Delivery

python scripts/encode.py --project .           # frames+mix+srt → out/final.mp4
python scripts/qa.py --project .               # qa/report.md + contact sheet of key frames

QA must fully pass (see references/qa.md):

  • Duration/aspect ratio/frame rate/audio track/subtitle stream correct;
  • No black frames ≥0.25 seconds; key frames have no blanks, overlapped text, or overflow;
  • Loudness within target ±1 LU, true peak ≤ -1.5 dBFS;
  • First frame is not pure black; last scene has a conclusion;
  • Fact list matches source materials; [to verify] items listed separately.

Delivery: out/final.mp4, out/final.srt, poster.png, storyboard.md, script.json, qa/report.md, rendering time, and known shortcomings.


4. Generic Scene Types (Implemented in Template)

typeUse CaseKey Fields
titleOpening/chaptertitle/subtitle/kicker
conceptOne concept + 3 key pointsheadline/points/visual
processProcess/steps (3–5 steps)steps[]
compareSide-by-side comparisonleft/right
formulaFormula + explanationformula/notes[]
barsData comparisonitems[{label,value}]
quoteKey quote/conclusionquote/author
recapSummary mapnodes[]/takeaway
customSpecialized graphicWrite your own custom.js

When a new type is needed: add a window.SCENES_IMPL['type'] in scenes.js and document the data contract in references/pipeline.md.


5. Aspect Ratios and Safe Zones

Aspect RatioDimensionsSafe ZoneTitle Font SizeBody Font Size
16:91920×1080Left/Right 96 / Top/Bottom 6472–12028–40
9:161080×1920Left/Right 64 / Top/Bottom 16064–9632–44
1:11080×1080All sides 7256–8828–40
4:51080×1350All sides 8060–9230–42

Portrait mode requires re-layout: title at top, graphic in middle, conclusion at bottom; do not compress horizontally. The template uses layout() to switch based on aspect ratio; see references/formats.md.


6. Common Failures → Fixes

SymptomRoot CauseFix
Black/white screenJS error, render undefined, canvas size 0render.py --still, check console; explicitly set canvas width/height
Wrong font/first frame fallback fontFont not loadedWait for document.fonts.ready before setting READY=true; use system fallback for CJK
Same t gives different results / flickers during parallel executionUsed rAF/timer/random/cross-frame stateConvert to pure function; hash(seed); closed-form spring
Text overlap/overflowNo per-scene still frame check3 still frames per scene + 360px wide key frame for portrait
Audio-video desyncAudio starts from 0 vs video starts at some point; TTS per-sentence concatenationSame timeline; whole-segment TTS; -ss placed before -i
Loudness inconsistencyMultiple loudnorm/transcodingOnly static gain in WAV stage; one AAC encode
Rendering too slow4K/subframes/brush/WebGLFirst render 960×540 sample; subframes only for fast motion; parallel workers
Chrome fails to startSandbox limits IPC/pipeRun in allowed environment, or use --cdp to connect to an already running Chrome

7. Extension Points

  • New style: copy templates/styles/*.json, modify color palette/fonts/background type; add a row in styles.md.
  • New scene: register in build/scenes.js; or write specialized graphics in build/custom.js.
  • Human voice-over: Place recordings as <scene-id>.wav into audio/vo_human/; tts.py --from-dir only does resampling/light processing.
  • Multi-language: one script.<lang>.json + corresponding TTS voice; timeline can reuse the same visuals (note text length differences).
  • Multi-aspect ratio: same script.json, re-init/render with different project.format; layout adapts via layout().
  • Branding: provide logo text/colors/footer in project.json.brand; disabled by default.

8. Reference Documents

  • references/pipeline.md: Full technical pipeline, render(t) contract, CDP rendering, FFmpeg parameters, timeline data model.
  • references/inputs.md: Extraction and OCR fallback for PDF/PPT/DOCX/URL/video.
  • references/storytelling.md: 4 teaching structures, pacing table, copy rules.
  • references/styles.md: Color palettes, fonts, animations, and suitable topics for the 5 style sets.
  • references/formats.md: Aspect ratios, safe zones, portrait re-layout rules.
  • references/audio.md: TTS options, human recording, music synthesis, ducking, loudness, single encode.
  • references/qa.md: Acceptance checklist and automated check commands.

Related Skills