Communitygithub.com

EMzhe/explainer-video-series

系列讲解视频全流程制作(策划→HTML动画页/文案→讲解稿→配音→字幕→1080p 成片→抖音封面横竖双尺寸),内置四道用户确认门禁(开工五问、讲解稿审阅、音色试听、合成确认)与发音修正能力(如「老子」读 lǎo zǐ)。This skill should be used when the user asks to 做一期讲解视频、制作讲解视频系列、道德经/经典解读视频、课件讲解视频、把PPT做成带配音和字幕的视频、生成讲解视频、新一期视频开工、继续做下一期讲解视频、给课件加语音讲解、带动画效果的讲解视频、给视频做抖音封面/竖版横版封面。触发典型场景:用户要为某个主题/经文/章节制作带旁白字幕的系列讲解视频,或要求沿用上期风格继续出下一期,或要为成片配抖音上传封面。

explainer-video-series 是什么?

explainer-video-series is a Claude Code agent skill that 系列讲解视频全流程制作(策划→HTML动画页/文案→讲解稿→配音→字幕→1080p 成片→抖音封面横竖双尺寸),内置四道用户确认门禁(开工五问、讲解稿审阅、音色试听、合成确认)与发音修正能力(如「老子」读 lǎo zǐ)。This skill should be used when the user asks to 做一期讲解视频、制作讲解视频系列、道德经/经典解读视频、课件讲解视频、把PPT做成带配音和字幕的视频、生成讲解视频、新一期视频开工、继续做下一期讲解视频、给课件加语音讲解、带动画效果的讲解视频、给视频做抖音封面/竖版横版封面。触发典型场景:用户要为某个主题/经文/章节制作带旁白字幕的系列讲解视频,或要求沿用上期风格继续出下一期,或要为成片配抖音上传封面。.

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/EMzhe/explainer-video-series/tree/HEAD

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Full Pipeline for Creating Explainer Video Series

Turn a "topic" into a "finished video": Planning → Page Layout (HTML Animation) → Script → Voiceover → Subtitles → 1080p MP4 → Douyin Covers (Horizontal 16:9 + Vertical 9:16). The default style archive is derived from the practical experience of the "Tao Te Ching" explainer video series (New Chinese Ink Wash / Yunjian Male Voice / White Text with Black Glow Subtitles). The entire set is reusable, and each item can be overridden.

Visual Route (HTML animation by default since v2.0; Graphic-Text Collaboration in v2.1):

  • Default: HTML Animation Pages – Generate HTML presentation pages with entrance animations and cross-fade transitions between pages based on the script. Deterministic frame-by-frame rendering into a video; animations are 100% synced into the final video (see references/html-animation.md for the scheme and layout rules).
  • v2.1 Graphic-Text Collaboration: Built-in ink wash SVG scene library (water waves / solitary boat / ripples / mountains / ink bamboo / moon gazing / koi fish) + item icons + external image support. Automatically matches or explicitly specifies scenes based on the script. Unified arrangement of staggered graphic elements and text animations.
  • Fallback: Static PPT frames + xfade (used when native PPT tables/complex formatting is needed, or when the user explicitly requests a .pptx file).

v2.3 onwards, each episode includes standard Douyin covers: Horizontal 16:9 + Vertical 9:16. AI generates a set based on the topic (horizontal anchor point → user confirmation → vertical derived). Does not capture video frames; see Phase ⑥ and references/douyin-covers.md.

Five Startup Questions (Ask at the start of each episode; if the user says "same as last time" or "as usual", skip all and start directly)

  1. What is this episode about? (Topic / Chapter of scripture)
  2. Depth of content: Detailed explanation / Key points? (Default: Detailed explanation)
  3. Target video duration? (Default: 6-7 minutes)
  4. Keep the New Chinese Ink Wash PPT style? (Default: Yes)
  5. Keep Yunjian voice and white text with black glow subtitles? (Default: Yes)

Style Archive (Adopted directly if not specified by user)

ItemDefault Value
PPT StyleNew Chinese Ink Wash: Rice paper off-white + Ink black + Dark cyan + Cinnabar
FontTitle: SimSun (Songti), Body: Microsoft YaHei (Use English font-family in SlideDSL)
Visual ElementsSVG ink wash illustrations (no AI image generation, 100% fidelity, editable repeatedly)
AnimationHTML animation pages: Title blur-in / Items staggered fade-up / Page cross-fade / Cue key point emphasis (The "element animation rejected" issue was for the ffmpeg overlay solution; the HTML deterministic rendering route has been validated and implemented since v2.0)
Voicezh-CN-YunjianNeural (Yunjian · Male · Rich)
Speed+0% (Uniform across the whole video; only change if explicitly requested by user, do not segment by content density)
SubtitlesWhite text + black outer glow (blur 0.8), transparent background, bottom center
Aspect Ratio1920×1080 (16:9)
Pronunciation Correction"老子" → TTS reads as "Lǎo Zǐ" (classical third tone), subtitles still display "老子"
Douyin CoverHorizontal 16:9 + Vertical 9:16; Episode name in four large characters; AI-generated set (anchor chain), no video frames

Working Directory Convention

Create a video-working-directory/ in the workspace, with one sub-directory per episode (named after the topic):

video-working-directory/{episode-name}/
├── {BASE} script.json          # Single source of truth: title/voice/pronunciation corrections/script per slide (+ page text)
├── {BASE} script_editable.txt    # Exported by export_txt.py for user review in notepad
├── 01_deck/                    # deck.html (animation preview page) + deck.json (timeline manifest)
├── 01_html_frames/             # f_XXXXX.png per frame + frames_manifest.json (HTML route)
├── 01_frames/                  # frame_01.png ... (static PPT fallback route)
├── 02_audio/                   # slide_01.mp3 ... slide_NN.mp3 (per-page audio)
├── voice_preview/              # Multiple voice preview mp3s + voice_preview.html
└── 03_output/                  # Finished video {BASE}(with_subtitles).mp4

BASE = episode name (if it contains "script", it is automatically stripped). The script JSON is programmatically generated using Python json.dump; manually writing JSON with Chinese quotation marks is forbidden (it will cause escape errors). The cover canvas {episode-name}-douyin-cover.miora is placed according to the generated media delivery specification in the workspace root, with double-size PNGs in its _assets/ directory.

Step-by-Step Process (Includes 4 confirmation gates; proceed only after receiving user's response for each gate)

Before starting (first time or if environment is abnormal), run the environment check: python scripts/doctor.py. Fix any MISSING items before proceeding. Pacing baselines, gate list, BGM, and revision scope table are in references/pacing-and-gates.md. (Methodology integrated from liyupi/ai-promo-video-maker: strict pacing standards / data validation / dual gates / revision discipline).

Phase ① Content Planning (Gate 1: Five Startup Questions)

After determining the plan based on the five questions, produce a brief planning package (text structure / visual scheme / audio scheme). Once the user approves, proceed to ②.

Phase ② Page Layout (HTML Animation Route = Default)

  • No longer making PPTs: Directly programmatically generate {BASE} script.json, writing the script text per slide. Each slide may optionally include title (page title), points (screen item array), layout (title/bullets/quote/end), cues (key point emphasis, see below) — if missing, they are automatically derived from the script (rules in references/html-animation.md), but for formal production, it is recommended to specify them explicitly for better quality.
  • The number of pages depends on content depth (detailed explanation ≈ 8 pages); tables/data should still use the static PPT fallback route.

Phase ②′ PPT Production (Static Fallback Route)

  • Use workbuddy-pptx (SlideDSL) to create slides. Number of pages depends on content depth (detailed explanation ≈ 8 pages).
  • Speaker notes = per-slide script: Write once, reuse in multiple places (video voiceover / DOCX timeline / CapCut import).
  • Use English font names (SimSun / Microsoft YaHei); Chinese names will not render.
  • Colors and elements follow the style archive; tables/data pages should preferably use native PPT elements.

Phase ③ Script Finalization (Gate 2: Script Review)

  1. Extract the script from PPT notes, programmatically generate {BASE} script.json (structure below).

  2. Export editable text for review:

    python scripts/export_txt.py "{BASE} script.json"
    
  3. Clearly instruct the user to open the txt file in Notepad and review page by page; after the user returns their edits, sync back to JSON:

    python scripts/import_txt.py "{BASE} script.json" "{BASE} script_editable.txt"
    

    If the user only replies "the script is fine" without changes, skip the sync.

Phase ④ Voiceover (Gate 3: Voice Preview, Hard Gate voice_confirmed)

  1. Generate a preview page for the user to select a voice:

    python scripts/preview_voices.py voice_preview
    
  2. After the user selects, write to JSON and set voice_confirmed=true (without this, TTS and synthesis will directly refuse to execute):

    python -c "import json;p='{BASE} script.json';d=json.load(open(p,encoding='utf-8'));d['voice']='zh-CN-YunjianNeural';d['rate']='+0%';d['voice_confirmed']=True;json.dump(d,open(p,'w',encoding='utf-8'),ensure_ascii=False,indent=2)"
    

    The default speed +0% remains unchanged; only change if the user explicitly requests a speed change, and it must be uniform across the entire video.

Phase ⑤ Final Video Synthesis (Gate 4: Confirm with User Before Synthesis)

Order: Synthesize audio → Generate animation pages → Render frames → Compose video (HTML route); or Render frames → Audio → Video (static route).

HTML Animation Route (Default):

  1. Synthesize per-page audio (Must be done first – page duration is taken from actual audio duration):

    python scripts/tts_synth.py --narration "{BASE} script.json" --out 02_audio
    
  2. Generate animation preview page (deck.html can be previewed with #preview in the browser):

    python scripts/gen_html_deck.py --narration "{BASE} script.json" --audio 02_audio --out 01_deck
    
  3. Render frames (only renders the animation window, completes in minutes):

    node scripts/render_html_frames.mjs --deck 01_deck --out 01_html_frames
    
  4. Compose video (concat frame sequence + per-sentence subtitles, default white text with black glow style):

    python scripts/compose_html_video.py --deck 01_deck --frames 01_html_frames --audio 02_audio --narration "{BASE} script.json" --out 03_output
    

    Default output: {BASE}(with_subtitles).mp4; --also-plain adds a version without subtitles; --bgm <file> adds background music (auto ducking, lowers music volume when narration is active; music library from Mixkit, free for commercial use, must be selected after user preview).

Static PPT Fallback Route:

  1. Render slide frames (Preferred: PowerPoint COM, requires local PowerPoint installation):

    powershell -ExecutionPolicy Bypass -File scripts/export_frames.ps1 -Pptx "{BASE}.pptx" -OutDir 01_frames
    

    If a PDF already exists, use the pymupdf path: python scripts/pdf_to_frames.py "{BASE}.pdf" 01_frames 1920. After rendering, spot-check 3 pages (first page / a content-dense page / a table page) to confirm no font issues.

  2. Synthesize per-page audio: Same as tts_synth.py above.

  3. Compose video (static pages + xfade + per-sentence subtitles):

    python scripts/compose_video.py --frames 01_frames --audio 02_audio --narration "{BASE} script.json" --out 03_output
    
  4. Verify delivery: Check frames at entrance/transition points to confirm animations are normal, no black flashes; check frames mid-page to confirm subtitles; Run the output gate: python scripts/verify_output.py --video "03_output/{BASE}(with_subtitles).mp4" --deck 01_deck (All specs/duration/loudness/black frames/silence must pass before delivery); present_files delivery.

Phase ⑥ Douyin Covers (Standard for each episode: Horizontal 16:9 + Vertical 9:16)

Deliver covers along with the final video for easy upload to Douyin. Do not capture video frames – AI generates a set based on the episode's topic; deliver .miora canvas + double-size PNGs; See references/douyin-covers.md for prompt templates / image reference / quality checklist. Skip if the user explicitly says they don't need covers.

  1. Text: The episode name (four characters) is the only large text on the image (e.g., "有无相生"); do not add subtitles (will be unclear); zero text on the image besides the main text.
  2. Anchor Chain (Hard Rule): Horizontal anchor point (pure text-to-image 1920×1080) → User confirmation → Vertical version derived using the anchor point as reference image (1080×1920, vertical three-section layout); reuse style token from the original; forbid sending both images blindly.
  3. Visuals: Same style as the final video (rice paper off-white + ink black + dark cyan + cinnabar, ink wash diffusion, sparse white space); imagery taken from the episode's theme (e.g., "有无相生" → full moon + moon reflection in water).
  4. Exact Dimensions: The model may round to 1920×1072 / 1072×1920 (off by 8px); report this accurately; if the user needs exact dimensions, add padding to standard values.
  5. Delivery: Workspace root {episode-name}-douyin-cover.miora + double-size image cards; record cover text and dimensions in demand-confirmation.md.

(If 100% text control or cross-episode template reuse is needed, switch to editable design layout export; default is AI generation.)

Phase ⑦ Fine-Tuning and Iteration

  • Maintain demand-confirmation.md per episode directory: Five question answers + record of each revision round (file user's original words); record feedback first, then edit; only redo necessary steps (see references/pacing-and-gates.md for change scope → redo steps table).
  • Subtitle style/color adjustment → See references/subtitle-style.md (ASS color is BBGGRR reversed, must read).
  • Pronunciation issues → Only modify tts_replacements, rerun TTS + synthesis; subtitles remain unchanged.
  • Subtitle sync → compose preferentially reads 02_audio/timing_XX.json (TTS sentence-level real timeline, auto-generated by tts_synth).
  • Visual/animation issues (HTML route) → Modify the script JSON's title/points/visual/cues or gen_html_deck.py layout → Rerun: generate deck → render → compose (reuse audio unless script also changed).
  • Visual issues (static route) → Modify PPT and re-export frames; reuse audio.
  • Cover modifications → If text/imagery is incorrect, only regenerate the corresponding item; if the overall style is wrong, regenerate the anchor point and then derive (see references/douyin-covers.md).

Phase ⑧ Delivery Acceptance (Self-Checklist)

  • Visuals: No font/color anomalies; table pages (if any) rendered correctly
  • Animation: Title/item entrances natural, page transitions smooth, cue emphasis aligned with narration (HTML route)
  • Voiceover: Audible, no swallowed words, consistent speed throughout
  • Pronunciation: Classical readings correct (e.g., "老子" = lǎo zǐ)
  • Subtitles: Synced sentence-by-sentence with audio, uniform style, no overflow/cutting
  • Transitions: Cross-fade smooth, no black flashes, no blank frames
  • Duration: ≈ target duration (±10 seconds)
  • Format: 1920×1080 / H.264 / AAC / .mp4
  • Covers: Horizontal and vertical versions, four characters without missing strokes, consistent style, exact dimensions (checklist in references/douyin-covers.md)

Script JSON Structure (Single Source of Truth)

{
  "title": "Laozi Today-Understanding - Supreme Goodness Like Water",
  "voice": "zh-CN-YunjianNeural",
  "rate": "+0%",
  "voice_confirmed": true,
  "tts_replacements": { "老子": "老紫" },
  "slides": [
    { "idx": 1, "text": "Script for page one..." },
    { "idx": 2, "text": "Script for page two...",
      "title": "Three Virtues of Water", "points": ["Altruism, nourishing all things", "Non-contention, willingly taking the lower position"],
      "cues": [ { "t": 4.5, "dur": 0.9, "target": 0 } ] }
  ]
}
  • idx is sequentially numbered from 1, strictly corresponding to frame_XX.png (static route) / slide_XX.mp3.
  • Optional fields per slide for HTML animation route: title (page title), points (screen item array), layout (title/bullets/quote/end), cues (key point emphasis: t=relative seconds within page, target=item index starting from 0, duration=emphasis duration, action=pulse); Graphic-Text Collaboration (v2.1): visual (ink wash scene water/ripples/mountain/ bamboo/moon/fish, defaults to automatic matching based on script keywords), icons (item icons droplet/wave/mountain/moon/leaf), image (external image path, embedded in right column). If missing, they are automatically derived from the script; for formal production, it's recommended to specify them explicitly.
  • tts_replacements: Pronunciation correction table, only affects TTS input, subtitles and editable text retain the original characters. Use empty {} for generic series.
  • voice_confirmed defaults to false; set to true at Gate ③, otherwise the script will refuse to synthesize.

Common Failure Quick Reference

SymptomCauseResolution
Subtitle box color doesn't match expectationsASS color is BBGGRR reversedRed=&H000000FF Blue=&H00FF0000 Black=&H00000000
Classical reading pronounced as vernacular (e.g., 老子 lǎo zi)TTS defaults to colloquial pronunciationAdd to tts_replacements and rerun TTS
PPT font doesn't renderChinese font names not recognizedUse SimSun / Microsoft YaHei
One-step composition white screen / filter chain crashOverlay after xfade conflictsSplit into two steps: render base layer first, then overlay; escape commas with \,
Frames "generated" but not foundpymupdf silently failsScript uses abspath + post-write validation; or use export_frames.ps1
--rate -10% error "expected one argument"argparse misinterprets optionUse --rate=-10% or just modify the JSON rate field
Composition error "Audio not yet confirmed"Gate ③ was skippedSet voice_confirmed=true and rerun
JSON error with Chinese quotation marksManual escape errorsUse Python json.dump to generate programmatically
Deck generation error "missing audio"HTML route requires TTS firstRun tts_synth.py first, then gen_html_deck.py
Rendering error "cannot find Chromium"Browser path changedSpecify with --browser pointing to chrome.exe / msedge.exe
Title page not centeredCSS class selector writingUse .inner.layout-title (same-class elements), avoid descendant selectors
Items broken up (sequence number sentences become separate items)Short sequence sentences not mergedgen_html_deck.py has built-in merging; defining explicit points can completely avoid this
Last frame duration incorrectConcat quirk for the last filecompose_html_video.py has built-in repetition of the last file; do not delete
Cue emphasis not appearingCue exceeds page durationCheck if t in slides[].cues is less than the audio duration for that page
Cover large characters missing strokes/incorrect charactersAI unstable with long Chinese textKeep text within four characters and regenerate; if anchor point characters are wrong, regenerate anchor point first, then derive
Cover short side 1072≠1080Model roundingDeliver as-is (aspect ratio still ≈16:9/9:16); if precise, pad to 1920×1080 / 1080×1920
Two covers don't look like a setBoth generated independently from textMust use anchor chain: derive vertical version using horizontal anchor point as reference image

Complete pitfalls and architecture experience see references/pitfalls.md; HTML animation route details see references/html-animation.md.

Resources

  • scripts/doctor.py — Environment health check (run before starting each episode, fix MISSING items before proceeding)
  • scripts/verify_output.py — Output gate (specs/duration/loudness/black frames/silence, all pass before delivery)
  • scripts/gen_html_deck.py — Script → graphic-text collaborative animation HTML presentation page + deck.json manifest (HTML route entry)
  • scripts/render_html_frames.mjs — Playwright deterministic frame-by-frame rendering (only captures animation window, reuses last frame for static segments)
  • scripts/compose_html_video.py — Frame sequence + audio + real-time subtitle + BGM ducking composition (HTML route)
  • scripts/tts_synth.py — edge-tts batch synthesis (pronunciation correction + sentence-level real timeline + voice_confirmed gate)
  • scripts/compose_video.py — Static pages + xfade + per-sentence subtitle composition (static fallback route)
  • scripts/export_txt.py / scripts/import_txt.py — Bidirectional sync between script and editable txt
  • scripts/preview_voices.py — Five-voice comparison preview page (playable offline)
  • scripts/export_frames.ps1 — PowerPoint COM export 1920×1080 frame images (preferred static route)
  • scripts/pdf_to_frames.py — pymupdf render PDF to frames (static route fallback)
  • references/douyin-covers.md — Full Douyin cover process: text rules / prompt templates / anchor chain / quality checklist (standard horizontal + vertical for each episode)
  • references/html-animation.md — HTML animation route: feasibility conclusion / layout rules / pitfalls (must read)
  • references/pacing-and-gates.md — Pacing baselines / data validation / dual gates / BGM / revision scope table (must read)
  • references/playbook.md — Full process manual: confirmation items table / tech stack / optimization roadmap
  • references/pitfalls.md — Pitfall checklist and architecture experience
  • references/subtitle-style.md — ASS subtitle style manual (color reversal / glow effects / style presets)
  • assets/narration-template.json — Script JSON template

Dependencies: playwright-core (in skill root node_modules, already installed); Chromium detection order ms-playwright cache → system Edge; if both are missing, specify with --browser.

相关技能