A pure-code, beat-synced showcase-video skill — every frame drawn with HTML/Canvas/SVG/Three.js, every sound synthesized with Python, assembled by FFmpeg. No video, image or music generation models.
An Agent Skill for producing 30–90 s "style showcase" films: an 8 s opening, eleven style segments with 1 s big cards between them, an eight-flash montage, and a cinematic ending — all reproducible frame by frame.
中文简介:这是一个「用代码做视频」的 Agent Skill:画面用 HTML/Canvas/SVG/Three.js 逐帧渲染,配乐用 Python(numpy/scipy)合成,最后由 FFmpeg 合成 30–90 秒的卡点风格展示片,全程不调用任何视频、图像或音乐生成模型。仓库里包含剪辑结构公式、11 种风格配方、大字卡系统、120 BPM 配乐方案、Playwright 渲染管线、质检清单和可运行模板。完整中文说明见 中文。
一键安装 / Install in one sentence
把这句话发给你的 Agent:「把这个仓库安装成 Agent Skill:
git clone https://github.com/Moessif/code-video-showcase.git ~/.dsh/skills/code-video-showcase(Claude Code 换成~/.claude/skills/,通用 Agent 用.agents/skills/),装好后读一遍SKILL.md确认可用。」Send this to your agent: "Install https://github.com/Moessif/code-video-showcase as an Agent Skill: clone it into
~/.dsh/skills/code-video-showcase(~/.claude/skills/for Claude Code,.agents/skills/for generic agents), then readSKILL.mdto confirm it works."
Changelog / 更新历史:CHANGELOG.md · GitHub Releases
There is no finished demo video in this repository, and the reference sample file is not distributed. The previews are analysis artifacts of the 61 s reference showcase the skill was reverse-engineered from, plus a placeholder still rendered from the shipped big-card template.
1 fps contact sheet (8×8 tiles) of the reference film: the typing opening, eleven big-card / style-segment rounds, the eight-flash montage and the ending. Generated by scripts/analyze-reference.sh.
One representative frame from each of the eleven style segments: flat-science, Fourier math, product launch, whiteboard, cyber glitch, ink-wash, data race, 8-bit, code screencast, Three.js clay, vertical short.
All twelve big cards — eleven "what do you want to make?" prompts plus the "还有更多?" card — across four alternating layouts: accent-colour, paper, dark centred, dark left-aligned.
Log-frequency spectrogram of the reference soundtrack: sparse intro (0–8 s), full-band groove from 8 s, visible 4 s structural seams, near-silent tail from 60.4 s.
templates/big-card.html rendered through templates/render-segment.mjs at 1920×1080: dark layout, "想开 / 产品发布会?" card, STYLE 03 / 11. Placeholder content — replace the copy, keep the timing.
The skill is a production recipe, not a model. It packages the structure measured off a real 61 s showcase: a timeline formula, a big-card system, eleven art-direction/technical/sound recipes, a 120 BPM synthesized score, a deterministic Playwright → FFmpeg pipeline, a QA checklist and runnable templates — full style palettes and six-beat animation maps live in references/style-recipes.md. Because every frame is a pure function of t, renders are deterministic: the same second always produces the same frame, on any machine.
| Property | Default target | Notes |
|---|---|---|
| Format | 1920×1080, 30 fps, 1× device scale | one HTML page per segment |
| Length | 61.0 s = 1830 frames | generalized by the formula below |
| Video | H.264 High, yuv420p, libx264, 2-pass ≈ 3.4 Mbps |
final file ≈ 26 MB |
| Audio | 48 kHz stereo AAC 192 kbps | synthesized, no samples |
| Tempo | 120 BPM — 0.5 s per beat, 2 s per bar | 1 s card = 2 beats, 3 s style segment = 6 beats |
| Brand | coral #d97757 on #0e0e0d |
placeholder; replace per project |
| Type | OFL fonts only, served locally | Noto Sans/Serif CJK SC, Inter, JetBrains Mono, Orbitron, Playfair Display, Ma Shan Zheng, Long Cang, ZCOOL KuaiLe, ZCOOL QingKe HuangYou, Press Start 2P |
| Determinism | frame = f(t) | no CSS animation, rAF, Date.now, Math.random; no burned-in subtitles |
Measured on the reference sample: container 61.013 s / video 61.000 s, 1830 frames, 60 scene cuts, H.264 ≈ 3.53 Mbps, AAC 48 kHz stereo ≈ 196.8 kbps, 26.9 MB. Source data in assets/scene-cuts.txt and assets/audio-analysis.json.
0 ── opening (O = 8 s) ── 8 ── N × 4 s rounds = 44 s ── 52 ── "还有更多?" card 1 s ── 53
── eight flashes 2 s (8 × 0.25 s) ── 55 ── ending (E = 6 s) ── 61
total = O + N·R + 1 + 2 + E # 8 + 11×4 + 1 + 2 + 6 = 61 s
Each round R = 4 s = one big card (1 s / 2 beats) + one style segment (3 s / 6 beats). The first frame of every style segment is the beat hit. Frame check: each segment is round(duration × 30) frames and the whole film must total 1830.
- Lock the brief — topic, brand placeholder
{{BRAND}}, duration, number of stylesN, one line per style, ending CTA. - Write the edit table — every segment as
[start, end, type, style, t0, speed]in one JSON/Markdown constant file; all later scripts read it. - Prepare the environment — Node, Playwright/Chromium, FFmpeg, numpy + scipy, local fonts; see
references/render-pipeline.mdfor the cross-platform setup. - Scaffold the project — static server,
common.js, segment / card / render / concat / audio templates. - Implement segments one at a time (an 11-segment outer loop): scene → 5–6 stills → contact sheet → full render →
ffprobeframe count. - Opening (8 s) — character-by-character typing, three scrolling code columns, particle burst, white flash.
- Big cards — four layouts rotating, 2 beats each: slam-in, speed lines, echo type,
STYLE 0X / 11. - Eight flashes + ending (optional) — eight 0.25 s micro-posters, then a 6 s cinematic ending.
- Score the film — 120 BPM, A minor, sharing the exact timing constants of the edit table; verify against a spectrogram.
- Assemble and QA — segment MP4s → concat → mux → 2-pass encode → contact sheets + spectrogram + human review.
The mandatory inner loop for every segment:
design -> write HTML -> stills at t=0.2/0.8/1.4/2.0/2.6 -> contact sheet
-> full render -> ffprobe frames == duration*30 -> log -> next segment
Do not write all eleven segments and then render once; get one segment perfect and copy it.
| Layout | Background | First line | Keyword | Underline |
|---|---|---|---|---|
| A | accent colour | black 70 px | black 170 px | black 8–12 px |
| B | paper #f4efe6 |
black 70 px | black 170 px | accent 8–12 px |
| C | dark #0e0e0d, centred |
white 70 px | accent 170 px | none |
| D | dark #0e0e0d, left-aligned |
white 70 px | accent 170 px | none |
- Beat 1 (
t=0): first line slams in; beat 2 (t=0.5): keyword + suffix slams in. - Slam = scale
1.7 → 1, blur16 → 0px, 0.11 s,outExpo; plus accent speed lines, radial glow and 6 px / 12 px screen shake. - Background: 600 px outlined echo text drifting horizontally;
STYLE 0X / 11bottom-right; music drops to 6% during the card, then the style segment opens with its own hit. - Pre-render blur layers once and cross-fade with
globalAlpha— never runctx.filterper frame.
Pure numpy/scipy synthesis — no samples, no audio model:
- Instruments: kick (sine sweep), snare, clap, hat, crash, sub boom, noise riser, reverse crash, whoosh, plucked string, FM e-piano, FM bell, supersaw, 808, square/triangle leads, flute.
- Harmony: A minor, one chord pair per 6-beat segment — Am/F, C/G, F/G, C/F, Am/G, Am/Em, Dm/E, C/G, Dm/G, F/G, Am/F.
- Arrangement: pad + typing clicks → sub boom at 4.55 s, kick crescendo → 8th hats from 5.5 s → snare roll 6.5–7.95 s → reverse crash at 7.45 s. Cards drop the music to 6%; the first frame of each style segment is a six-layer hit.
- Mix: kick-envelope sidechain (55% duck), 2.2 s synthetic convolution reverb,
tanhsoft clip, normalize to −0.6 dBFS. - Reference measurements: 120.0 BPM, phase 0.0 s, 86.3% of 102 strong onsets inside ±30 ms of the grid (median error 0 ms); card hits measure 8–9× the previous 300 ms of energy, style-segment hits 2.8–3.5×.
- Serve the project root over HTTP (fonts, KaTeX and Three.js all same-origin; never
file://). render-segment.mjslaunches headless Chromium, waits fordocument.fonts.readyandwindow.__ready, then for each frame callspage.evaluate(t => renderFrame(t)), captures via CDPPage.captureScreenshot({ format: 'jpeg', quality: 95 }), and pipes the JPEGs toffmpeg -f image2pipe -framerate 30 -i pipe:0 -c:v libx264 -preset medium -crf 16 -pix_fmt yuv420p.concat-and-encode.shconcatenates segment MP4s (-f concat -safe 0 -c copy), muxes the WAV, and runs a 2-pass encode at 3400 kbps with AAC 192 kbps.- Every segment is verified with
ffprobe -count_frames; the total must equal 1830.
Picture — no console errors, no 404s (including favicon); every font passes document.fonts.check() with no missing CJK glyphs; 5–6 stills per style segment and a 1 fps contact sheet for the whole film; grep proves no CSS animation/rAF/Date.now/Math.random; no per-frame ctx.filter or large shadowBlur; coordinates cached before camera transforms (getBoundingClientRect is affected by transforms); 1920×1080 at 1×, preserveDrawingBuffer: true, WebGL via SwiftShader.
Audio — spectrogram shows every hit within 30 ms of the edit table; cards drop out, style segments hit on frame one; 5.5–6.0 s fade-out; peak −0.6 dBFS with no clipping.
Assembly — every segment's frame count equals duration × 30, total 1830; audio and video aligned (-shortest, -t 61 if needed); H.264 yuv420p + AAC 48 kHz, ≈ 26 MB; a cover frame is extracted and a one-page spec sheet (frame rate / duration / styles / fonts / toolchain) is written.
The templates are a scaffold, not a finished film. From this repository:
# 1) create a project and copy the templates into it
mkdir -p my-showcase/segments my-showcase/shared my-showcase/fonts my-showcase/audio my-showcase/out
cp templates/* my-showcase/
cp scripts/* my-showcase/
cd my-showcase
cp segment.html segments/01.html # your first style segment
cp common.js segments/ # segment.html imports ./common.js
npm i playwright # or playwright-core; the renderer accepts either
# 2) draft stills first (cheap) — t=0.2,0.8,1.4,2.0,2.6
node render-segment.mjs --page /segments/01.html --still 0.2,0.8,1.4,2.0,2.6 --outdir out/stills
# 3) render one 3 s segment; the renderer starts its own ephemeral static server
node render-segment.mjs --page /segments/01.html --out out/01.mp4 --duration 3
# 4) verify segment frame counts (h264 / yuv420p / 1920x1080 / fps / frames)
./qa-check.sh out 30
# 5) synthesize the soundtrack (8 s demo out of the box)
python3 synth_audio.py --out audio/demo.wav
# 6) concat + mux + 2-pass encode (defaults: duration 61, 30 fps, 3400 kbps, AAC 192k)
./concat-and-encode.sh segments.txt audio/mix.wav out/final.mp4segments.txt is the concat demuxer list, one line per segment:
file 'out/00-opening.mp4'
file 'out/01-card.mp4'
file 'out/02-style-01.mp4'
...
Notes:
render-segment.mjsembeds a small static server, so a local path is enough (--page /segments/01.html); a full URL is used verbatim. Style segments take--t0 0.35 --speed 1.4— for a relative page the renderer appends?seg=1&t0=&speed=&dur=, andcommon.jsmaps clip timeuto scene timet = t0 + u·speed.- Rendering needs no separate server: the renderer embeds one. For manual browser previews only, serve the project root on port 4600 yourself —
references/render-pipeline.md§3 documents an optionaltools/server.mjs(node tools/server.mjs --port 4600) that is not shipped, because the renderer already contains an equivalent. - The templates expect a local
shared/fonts.csswith@font-facerules for OFL fonts you download yourself. Fonts are not bundled. - Useful env vars:
CHROME_EXE/FFMPEG_EXEfor the renderer;FFMPEG/FFPROBE/VIDEO_BITRATE/AUDIO_BITRATEfor the shell scripts (plusPYTHONforqa-check.sh).node render-segment.mjs --helplists every flag. synth_audio.pyis a toolkit plus a runnable 8 s demo; extendbuild_arrangement()to the full 61 s timeline usingreferences/audio-recipes.md.
The repository is a self-contained skill folder: SKILL.md carries the YAML frontmatter (name, description, license: MIT, compatibility, allowed-tools) and the code agent reads it before acting.
# DeepSeek Harness
cp -r code-video-showcase ~/.dsh/skills/
# Claude Code
cp -r code-video-showcase ~/.claude/skills/
# Generic SKILL.md-compatible agents
cp -r code-video-showcase .agents/skills/Once installed, the skill auto-triggers on prompts such as 卡点视频 / 风格展示视频 / 纯代码做视频 / 「类似 Opus 5.5 或 DeepSeek 风格展示」 / 逐帧渲染 / 用代码做视频 / HTML Canvas 视频 / 程序化视频 — and on the English equivalents ("beat-synced showcase video", "render video frame by frame in code"). The agent then follows the ten-stage workflow, copies the templates and renders locally.
| Component | Requirement | Why |
|---|---|---|
| Node.js | ≥ 20 (24 recommended) | renderer script + playwright |
| npm packages | playwright or playwright-core (optional: katex) |
headless Chromium driver, browser |
| Browser | Playwright bundled Chromium, Chrome for Testing, or Edge | frame capture; WebGL via SwiftShader args |
| FFmpeg + ffprobe | libx264, AAC, image2pipe; tile/showspectrumpic for analysis |
encode, concat, 2-pass, contact sheets, spectrogram |
| Python | ≥ 3.10 with numpy + scipy | soundtrack synthesis, audio analysis, QA script |
| Fonts | all OFL, downloaded and served locally | CJK + display type; no CDN at render time |
- Windows: the renderer tries
CHROME_EXEif set, then Playwright's bundled Chromium, then Edge (channel: 'msedge'); setCHROME_EXEto point at a specific build. - WSL / Linux: if the bundled download is slow, use Chrome for Testing and
executablePath; headless Chromium may needlibnss3/libnspr4/libasound2, obtainable without root viaapt-get download+dpkg-deb -xinto~/.local/opt/chromium-libsandLD_LIBRARY_PATH. - Keep
node_modules, Python venvs, browser caches and scratch frames on the Linux filesystem: in the reference measurements/mnt/ewrote ~2000 small files in ~4.9 s versus ~0.05 s on ext4. Frames are piped straight to ffmpeg and never hit disk; rendering is local and CPU-bound, with no cloud service or generation API involved.
code-video-showcase/
├─ SKILL.md # the skill itself — workflow, constraints, index
├─ README.md # this file
├─ LICENSE # MIT
├─ .gitignore / .gitattributes # ignore build output / enforce LF line endings
├─ references/
│ ├─ original-brief.txt # the original 61 s brief — copy and rebrand
│ ├─ reference-film-analysis.md # measured breakdown of the reference (cuts/frames/audio)
│ ├─ style-recipes.md # 11 styles: art direction + technique + sound
│ ├─ big-card-and-typography.md # 4 card layouts, type scale, slam parameters
│ ├─ audio-recipes.md # 120 BPM arrangement, synthesis formulas, mix chain
│ └─ render-pipeline.md # Playwright / FFmpeg / cross-platform setup and commands
├─ templates/
│ ├─ common.js # easing, seeded random, noise/fbm, segment mode, impact
│ ├─ segment.html # style-segment skeleton (Canvas + optional Three.js)
│ ├─ big-card.html # big-card skeleton (4 layouts, slam, echo type)
│ ├─ render-segment.mjs # frame-by-frame renderer -> ffmpeg image2pipe
│ ├─ concat-and-encode.sh # concat + mux + 2-pass encode
│ └─ synth_audio.py # numpy/scipy instrument library + arrangement demo
├─ scripts/
│ ├─ analyze-reference.sh # any reference MP4 -> contact sheet/cuts/spectrogram/analysis
│ └─ qa-check.sh # verify segment MP4s (codec/pix_fmt/size/fps/frame count)
└─ assets/ # evidence images and measured data
├─ contact-1fps.jpg # 1 fps contact sheet of the 61 s reference
├─ opening-tiles.jpg / style-tiles.jpg / card-tiles.jpg / flash-tiles.jpg / ending-tiles.jpg
├─ template-demo-segment.jpg / template-demo-card.jpg # stills rendered from the templates
├─ audio-spectrogram.png # log-frequency spectrogram
└─ audio-analysis.json / scene-cuts.txt / colors-per-second.json # measured data
| # | Style | Core technique | Key elements | Signature sound |
|---|---|---|---|---|
| 01 | Flat-science explainer | Canvas 2D layered circles / triangles / dashed orbit | sun, earth, light beam, label capsules | marimba |
| 02 | Math animation | Canvas 2D + DFT epicycles + KaTeX | golden heart, formulas, live N/θ | FM e-piano arpeggio + pad |
| 03 | Minimal product launch | canvas type + Three.js LatheGeometry |
metal ring, LED halo, "Nova Ring" | per-beat sub + bells |
| 04 | Hand-drawn whiteboard | SVG stroke-dashoffset + turbulence |
bulb → code → clapper, red circle | ukulele + marker noise |
| 05 | Cyber glitch | Canvas gradients / perspective grid + RGB split | striped sun, city, glitch slices | distorted 16th saw + four-on-the-floor |
| 06 | Ink-wash (guofeng) | Canvas fbm ridges + paper texture | mountains, red sun, boat, vertical calligraphy | guzheng pentatonic + taiko + flute |
| 07 | Data visualisation | Canvas bar race + CSS 3D perspective | bars, year counter, glass card | square arpeggio + ticks |
| 08 | 8-bit pixel | 240×135 canvas, pixelated 8× | robot, coins, slime, pixel HUD | chiptune + jump/coin SFX |
| 09 | Code screencast | Canvas editor + typed code | file tree, line numbers, live preview | lo-fi e-piano + vinyl noise |
| 10 | Three.js 3D | Lathe/TorusKnot + PhysicalMaterial |
clay studio, glass and metal spheres | bell arpeggio + boings |
| 11 | Vertical short | Canvas phone frame + pop-in UI | 9:16, step cards, comments and likes | 808 + supersaw + trap hats |
Every style segment carries the same chrome: a top-left capsule with the coral index and style name, a bottom-right 3-second countdown, a faint brand watermark, one or two in-style labels, and no bottom subtitles.
- Deterministic frames. Every frame is a pure function of
t. Forbidden: CSStransition/animation,requestAnimationFramein the page,Date.now(),performance.now(),Math.random(). Usemulberry32(seed)and value noise/fbm instead. - The renderer drives time. A page exposes
window.DURATION,window.renderFrame(t),window.__ready(and optionallywindow.__bootError); the renderer callsrenderFrame(i/fps)— the page never schedules itself. - No baked subtitles. All text is part of the composition (capsules, HUD, labels); bottom subtitle bars are banned.
- WebGL specifics.
{ preserveDrawingBuffer: true }, launch flags--use-angle=swiftshader --enable-webgl --ignore-gpu-blocklist --enable-unsafe-swiftshader, camera motion by parameter, never by wall clock. - Cheap frames. Pre-render blur/noise/paper layers once, cross-fade with alpha, and inspect five stills before a full render; avoid per-frame
ctx.filterand wideshadowBlur(per-frame filters are 10×+ slower under software rendering); cache layout coordinates before camera transforms. - One page, one segment. No shared runtime state between pages; visuals and audio import the same timeline constants.
- OFL fonts only, served locally. Load with
document.fonts.load(...)for every family and weight, thendocument.fonts.ready, then setwindow.__ready.
Released under the MIT License — see LICENSE.
Credits and provenance:
- The structure, timing and visual grammar come from a frame-by-frame analysis of a 61 s reference style-showcase video. The analysis is documented in
references/reference-film-analysis.md, with evidence inassets/. - The production brief that this skill operationalizes is included verbatim as
references/original-brief.txt. - No third-party code or media assets are bundled. All artwork is meant to be drawn at runtime; the soundtrack is synthesized.
- Fonts are not bundled — download OFL-licensed font files yourself and serve them locally.
- The coral
#d97757brand colour and the sample copy are placeholders; replace them with your own brand and script.
This README is bilingual: English first, Chinese below. SKILL.md itself is written in Chinese and is the authoritative source for the workflow. 跳到中文.
这是一个「用代码做视频」的 Agent Skill: 画面由 HTML/Canvas/SVG/Three.js 逐帧绘制,配乐由 Python(numpy/scipy)纯合成,最后交给 FFmpeg 合成 30–90 秒的卡点风格展示片。全程不调用任何视频、图像或音乐生成模型,每一帧都是时间 t 的纯函数,可复现、可逐帧检查。
它不是模型,而是一套可复用的制作方法。内容来自对一支 61 秒风格展示样片的逐帧拆解:剪辑结构公式、4 套大字卡版式、11 种风格的「美术 + 技术 + 音色」配方、120 BPM 配乐、Playwright 逐帧渲染管线、质检清单,以及可直接运行的模板。样片的结构是固定句式:开场 8 秒 → 11 轮 × 4 秒(大字卡 1 秒 + 风格段 3 秒)→ 「还有更多?」卡 1 秒 → 八连闪 2 秒 → 结尾 6 秒,合计 61 秒 / 1830 帧。公式可推广到任意风格数 N,30–90 秒的短片都能套用。
- 十阶段工作流:从需求定稿、剪辑表、环境准备,到逐段实现、配乐、合成与质检(见
SKILL.md)。 - 时间结构公式:总时长 =
O + N·R + 1 + 2 + E;每段帧数round(duration × 30),全片合计必须为 1830。 - 大字卡系统:强调色底 / 米白底 / 黑底居中 / 黑底左对齐 4 套版式;砸入缩放 1.7→1、模糊 16→0 px、0.11 秒
outExpo;速度线、径向光晕、6/12 px 抖动、600 px 描边回声字。 - 11 种风格配方:每种都给出调色板、构图、6 拍动效表、技术实现要点和专属音色。
- 120 BPM 配乐方案:A 小调、纯 numpy/scipy 合成;大字卡音乐压到 6% 形成 drop-out,风格段第一帧是六层叠加的「啪」;侧链 55%、2.2 秒混响、
tanh软削波、归一化到 −0.6 dBFS。 - 渲染管线与质检:服务器 → Playwright 无头 Chromium → CDP 截帧 JPEG q95 →
image2pipe→ libx264 crf16 → concat → 2-pass 3400 kbps + AAC 192k;质检覆盖画面、音频、合成三组检查项,外加 1 fps 接触表、频谱图与ffprobe帧数复核。 - 参考样片拆解与原始任务书:
references/reference-film-analysis.md记录实测切点、画面与音频数据;references/original-brief.txt是可改品牌直接复用的完整任务书。
仓库里没有提交成片视频,参考样片文件也不随仓库分发。预览素材是样片拆解图和模板占位实拍帧,图注与说明见上方英文 Preview 一节:assets/contact-1fps.jpg(全片 1 fps 接触表)、style-tiles.jpg(11 种风格各取一帧)、card-tiles.jpg(12 张大字卡)、audio-spectrogram.png(音频频谱)、template-demo-card.jpg(模板占位实拍)。
模板是脚手架,不是成片。在本仓库根目录执行:
# 1) 建项目并复制模板
mkdir -p my-showcase/segments my-showcase/shared my-showcase/fonts my-showcase/audio my-showcase/out
cp templates/* my-showcase/
cp scripts/* my-showcase/
cd my-showcase
cp segment.html segments/01.html # 第一段风格片
cp common.js segments/ # segment.html 里 import 的是 ./common.js
npm i playwright # 或 playwright-core,渲染器两者都接受
# 2) 先出静帧(便宜)—— t=0.2/0.8/1.4/2.0/2.6
node render-segment.mjs --page /segments/01.html --still 0.2,0.8,1.4,2.0,2.6 --outdir out/stills
# 3) 渲染一个 3 秒片段;渲染器会自启临时静态服务器
node render-segment.mjs --page /segments/01.html --out out/01.mp4 --duration 3
# 4) 校验分段帧数(h264 / yuv420p / 1920x1080 / fps / 帧数)
./qa-check.sh out 30
# 5) 合成配乐(默认先跑 8 秒 demo 验证环境)
python3 synth_audio.py --out audio/demo.wav
# 6) 拼接 + 混音 + 2-pass 输出(默认 61 秒、30 fps、3400 kbps、AAC 192k)
./concat-and-encode.sh segments.txt audio/mix.wav out/final.mp4补充说明:
render-segment.mjs自带静态服务器,--page传本地路径即可,完整 URL 原样使用。风格段可传--t0 0.35 --speed 1.4:相对路径会自动拼成?seg=1&t0=&speed=&dur=,common.js按t = t0 + u*speed把片段时间映射为场景时间。- 渲染不需要另起服务器(渲染器已内置)。只有在浏览器里手动预览时才需要自己起一个监听 4600 端口的服务器;
references/render-pipeline.md第 3 节记录了一个可选的tools/server.mjs(node tools/server.mjs --port 4600),它没有随仓库分发,因为渲染器内已有等价实现。 templates/里的 HTML 引用/shared/fonts.css,需要你自己下载 OFL 字体并写@font-face;字体不随仓库分发。常用环境变量:渲染器的CHROME_EXE/FFMPEG_EXE,脚本的FFMPEG/FFPROBE/VIDEO_BITRATE/AUDIO_BITRATE。synth_audio.py是「音色库 + 8 秒可运行 demo」,完整 61 秒编排按references/audio-recipes.md扩展build_arrangement()。
整个仓库就是一个技能目录,SKILL.md 带 YAML frontmatter(name、description、license: MIT、compatibility、allowed-tools)。把文件夹复制到对应技能目录即可:DeepSeek Harness 为 ~/.dsh/skills/,Claude Code 为 ~/.claude/skills/,通用 SKILL.md 兼容 agent 为 .agents/skills/。
安装后,提到「卡点视频」「风格展示视频」「纯代码做视频」「类似 Opus 5.5 / DeepSeek 风格展示」「逐帧渲染」「用代码做视频」「HTML Canvas 视频」「程序化视频」时会自动触发;Agent 会按十阶段工作流执行、复制模板并在本地渲染。
| 组件 | 要求 | 用途 |
|---|---|---|
| Node.js | ≥ 20(推荐 24) | 渲染脚本与 playwright |
| npm 包 | playwright 或 playwright-core(可选 katex) |
无头 Chromium 驱动 |
| 浏览器 | Playwright 自带 Chromium、Chrome for Testing 或 Edge | 逐帧截图;WebGL 走 SwiftShader |
| FFmpeg + ffprobe | 含 libx264、AAC、image2pipe;分析需 tile / showspectrumpic |
编码、拼接、2-pass、接触表、频谱图 |
| Python | ≥ 3.10 + numpy + scipy | 配乐合成、音频分析与质检脚本 |
| 字体 | 全部 OFL、本地文件 | 中文与展示字体;渲染时不依赖 CDN |
平台要点:Windows 下渲染器会依次尝试自带 Chromium → Chrome for Testing → Edge(channel: 'msedge');WSL/Linux 下若浏览器下载慢可用 Chrome for Testing + executablePath,缺 libnss3/libnspr4/libasound2 时可用 apt-get download + dpkg-deb -x 解到用户目录并设 LD_LIBRARY_PATH。node_modules、venv、浏览器缓存和临时帧建议放 Linux 文件系统:实测 /mnt/e 写 2000 个小文件约 4.9 秒,ext4 约 0.05 秒;逐帧渲染直接管道给 ffmpeg,不落盘。整个过程在本地 CPU 完成,不调用云端服务。
| # | 风格 | 核心手法 | 关键元素 | 专属音色 |
|---|---|---|---|---|
| 01 | 扁平插画科普 | Canvas 2D 分层圆 / 三角 / 虚线轨道 | 太阳、地球、光束、标签胶囊 | 马林巴 |
| 02 | 数学动画 | Canvas 2D + DFT 本轮 + KaTeX | 金色心形、公式、实时 N/θ | FM 电钢琶音 + 铺底 |
| 03 | 极简发布会 | Canvas 大字 + Three.js LatheGeometry |
金属戒指、LED 环、Nova Ring | 逐拍重低音 + 钟声 |
| 04 | 手绘白板 | SVG stroke-dashoffset + turbulence |
灯泡 → 代码 → 场记板、红圈 | 尤克里里 + 马克笔摩擦 |
| 05 | 赛博故障 | Canvas 渐变 / 透视网格 + RGB 分离 | 条纹落日、城市、故障切片 | 失真锯齿 16 分 + 四拍底鼓 |
| 06 | 水墨国风 | Canvas fbm 山峦 + 宣纸纹理 | 远山、红日、渔舟、竖排书法 | 古筝五声 + 太鼓 + 笛 |
| 07 | 数据可视化 | Canvas 条形赛跑 + CSS 3D 透视 | 条形图、年份、玻璃卡 | 方波琶音 + 滴答 |
| 08 | 8-bit 像素 | 240×135 低分辨率 + pixelated | 机器人、金币、史莱姆、像素 HUD | 芯片音乐 + 跳跃/金币 |
| 09 | 代码录屏 | Canvas 编辑器 + 逐字代码 | 文件树、行号、实时预览 | lo-fi 电钢 + 黑胶噪声 |
| 10 | Three.js 三维 | Lathe/TorusKnot + PhysicalMaterial |
粘土影棚、玻璃球、金属球 | 钟声琶音 + 弹跳 |
| 11 | 竖屏短视频 | Canvas 手机壳 + 弹出动画 | 9:16、步骤卡、评论/点赞 | 808 + 超级锯齿 + trap 镲 |
每段统一装置:左上角珊瑚编号胶囊标签、右下 3 秒倒计时、右上淡色品牌水印、1–2 个风格内小标签;不使用底部字幕。
- 画面是
t的纯函数:禁止 CSStransition/animation、页面内requestAnimationFrame、Date.now、performance.now、Math.random;随机一律用mulberry32(seed)。 - 页面只暴露
window.DURATION、window.renderFrame(t)、window.__ready(可选window.__bootError),由渲染器逐帧驱动,页面自己不做动画循环。 - 字体只用 OFL、本地同源加载;渲染前逐个
document.fonts.load(),再等document.fonts.ready。 - 模糊、纸纹、噪声等重图层预渲染一次再交叉淡化;避免逐帧
ctx.filter和大面积shadowBlur;镜头变换前缓存坐标。 - 一个 HTML 只做一个片段;画面和音频共用同一份剪辑表时间常数。
以 MIT License 发布,详见 LICENSE。
- 方法、时间结构与视觉语法来自对一支 61 秒参考样片的逐帧拆解,分析见
references/reference-film-analysis.md,证据图在assets/。 - 驱动整个技能的原始任务书完整保留在
references/original-brief.txt,可改品牌直接复用。 - 仓库不包含任何第三方代码或媒体素材;画面在运行时绘制,配乐实时合成。
- 字体不随仓库分发,请自行下载 OFL 字体并在本地提供服务。
- 珊瑚色
#d97757与样片文案是占位示例,正式制作时替换成自己的品牌与脚本。
Star History 图的生成与嵌入方法参考:如何拥有漂亮的 GitHub Star History 折线图(CSDN)。




