ayst-z/music-code-mv

music-code-mv

DSH plugin: render code-driven music videos (music-code-mv) — deterministic Canvas2D/Three.js shots, headless-Chrome or browserless skia engine, ffmpeg AV1/HEVC up to 4K/120fps/12-bit

Uncategorizedcanvasdeepseek-harnessffmpeg

dsh-music-code-mv

Render music videos by writing code. / 把一支 MV 写成代码。

A DeepSeek Harness plugin that turns a storyboard into a deterministic, frame-accurate video. No video-generation model, no stock footage, no timeline editor — every frame is drawn by Canvas2D or Three.js code, captured in headless Chrome, and encoded with ffmpeg. 一个 DeepSeek Harness 插件:把分镜表变成逐帧确定的视频。不用视频生成模型、不用素材库、不用时间线编辑器——每一帧都由 Canvas2D 或 Three.js 代码画出,无头 Chrome 逐帧截取,ffmpeg 合成。

dsh plugin --profile demo add dsh-music-code-mv
dsh --profile demo

仓库已打上 dsh-plugin 话题(GitHub 话题页会收录本插件);收录进 awesome-deepseek-agent 的条目见 docs/awesome-deepseek-agent-entry.md。 The repo carries the dsh-plugin topic, and a ready entry for awesome-deepseek-agent lives in docs/awesome-deepseek-agent-entry.md.

中文优先 / Chinese-first. 工具卡片与返回文本以中文为主、英文并列;浏览器端的操作面是对话视图环里的「MV 工坊」原生标签页——首屏就是「一键进入子代理」,状态、清晰度/风格/帧率预设、联系表直渲与风格画廊全在其中,不内嵌任何网页;右侧边栏另有一块只读的原生状态镜像(无 iframe),也仍可直接用浏览器打开工作室地址。 Tool cards and returned text lead with Chinese; the browser half ships a Chinese MV Studio page in the DSH right sidebar, also reachable directly in a browser.


Why code / 为什么是代码

video model / 视频生成模型music-code-mv
reproducibility / 可复现none, every run differs / 没有,每次都不一样every frame is a pure function of t / 每帧都是 t 的纯函数
iteration / 迭代re-generate the whole clip / 整段重抽frame cache: only changed frames re-render / 帧缓存:只重渲变过的帧
typography / 排版unreliable, text gets mangled / 不可靠,文字会糊text is text / 文字就是文字
resolution / 分辨率model-limited / 受模型限制any size, up to 4K60, plus HDR10 / 任意尺寸,最高 4K60,另支持 HDR10
cost / 成本per-generation billing / 按次计费your own CPU/GPU / 用你自己的 CPU/GPU

The core constraint that buys all of this: renderAt(t) is a pure function. Same t, same pixels, in any order. 换来这一切的核心约束:renderAt(t) 是纯函数。同一个 t 就是同样的像素,与调用顺序无关。


Features / 功能

Rendering / 渲染

  • Deterministic virtual-time rendering — no requestAnimationFrame, no wall clock / 虚拟时间确定性渲染——不用 requestAnimationFrame,不读墙钟
  • Canvas2D stage with the code-MV look baked in (scanlines, bloom, chroma split, slice glitch, grain, vignette) / Canvas2D 舞台内置代码 MV 质感(扫描线、bloom、色差分离、切片故障、颗粒、暗角)
  • Optional Three.js shots via import map, with preserveDrawingBuffer handled for you / 可选 Three.js 镜头(import map 接入),preserveDrawingBuffer 已替你处理
  • Per-scene FX override so flat UI shots skip the expensive post passes / 按场景覆盖后期开关,扁平 UI 镜头可跳过昂贵的后期链

Performance / 性能 (all measured on an Intel Core Ultra 5 125H + Arc iGPU / 全部实测于 Intel Core Ultra 5 125H + Arc 核显)

  • Parallel frame rendering across N Chrome workers — measured 8.9× at 4K (71.3s → 8.0s for 60 frames) / 并行分帧渲染:N 个 Chrome worker,4K 实测 8.9×(60 帧 71.3s → 8.0s)
  • Hardware GL with an automatic blank-frame probe that falls back to software / 硬件 GL:自动探测,画面全黑则回退软件渲染
  • Hardware encoding — auto-selects QSV → NVENC → AMF → x264. QSV AV1 measured better than software x264 (PSNR 43.59 vs 42.91 avg) and produced a smaller file / 硬件编码:自动选择 QSV → NVENC → AMF → x264。QSV AV1 实测优于软件 x264(PSNR 43.59 vs 42.91 平均)且文件更小
  • Incremental re-render — a frame is reused when its render signature is unchanged. Signatures come from the scene's own file plus its transitive import graph, so editing scene A never invalidates scene B, but editing a shared module invalidates everything that imports it / 增量重渲——签名不变就复用帧。签名取自场景自身文件加它的传递 import 图:改 A 场景不会波及 B,改共享模块才会让它全部失效
  • Real-time progress bar with throughput and ETA / 实时进度条:吞吐与 ETA
  • HDR10 output: 10-bit HEVC, Rec.2020, PQ — with a real SDR→PQ conversion (zscale), not just re-tagging / HDR10 输出:10-bit HEVC、Rec.2020、PQ——走真实的 SDR→PQ 变换(zscale),不是只打标签
  • HDR10 ✓ / HDR Vivid ✗ — HDR10 is delivered: 10-bit HEVC, Rec.2020, PQ and static mastering metadata (QSV cannot embed mastering metadata, so the renderer warns and --encoder=libx265 gives a compliant master). HDR Vivid (CUVA TU-068 dynamic metadata) is not supported: the stock ffmpeg build here ships no CUVA encoder — an external CUVA toolchain would be required — so no doc or video copy claims it. / HDR10 ✓ / HDR Vivid ✗——HDR10 已交付:10-bit HEVC、Rec.2020、PQ 与静态母版元数据(QSV 无法嵌入母版元数据,渲染时会告警,合规母版请用 --encoder=libx265)。HDR Vivid(CUVA TU-068 动态元数据)不支持:本机 stock ffmpeg 没有 CUVA 编码器,需外部 CUVA 工具链,因此任何文档与视频文案都不声称支持。

图形界面 / GUI (0.2.0)

  • 右侧边栏「MV 工坊」页面:首次自动打开一次,之后从标签栏的 + 里选 / a right-sidebar MV Studio page, auto-opened once, re-openable from the tab strip's +
  • 对话视图环标签页「MV 工坊」:与「对话」「轨迹」平级的原生标签(conversation.view,仅激活时挂载),首屏是「一键进入子代理」主色大按钮 + 当前预设回显,没有标题栏小按钮、没有右下角悬浮窗 / a native tab in the conversation view ring (peer of 对话/轨迹, mounted only while active) whose first screen is the primary one-click subagent button plus the current-preset readout — no title-bar chip, no floating dock
  • 工程浏览:自动扫描工作区里的 MV 工程(project.json + index.html),显示分辨率、帧率、时长、场景数、缓存帧数 / project discovery with resolution, fps, duration, scene and cached-frame counts
  • 预览:联系表 PNG 直接看,成片 MP4 带 Range 流式播放(拖动进度不用整段下载)/ contact sheets inline, films streamed with range requests
  • 渲染:联系表 / 静帧 / 视频三种模式,宽高、时长、关键帧、并行数都能改;进度条 + 实时日志 + 取消 / render from the panel with live progress, log and cancel
  • 文本:一键读 storyboard.md 与 lyrics.lrc / one click to read the storyboard and lyrics
  • 全部中文,纯手写浏览器包(无构建步骤);file:// 环境下自动退化为「在浏览器打开」提示 / Chinese copy, hand-written browser bundle with no build step, graceful fallback under file://

Authoring / 创作

  • Timeline with overlapping scenes and local-vs-global time made explicit / 时间线支持场景重叠,局部时间与全局时间界限明确
  • Seeded PRNG (no Math.random() in draw code) and hash1/hash2 helpers / 种子化 PRNG(绘制代码里没有 Math.random())与 hash1/hash2 工具
  • LRC lyric parsing with karaoke-ready timing / LRC 歌词解析,自带卡拉 OK 级时间精度
  • Contact-sheet self-check loop — the highest-value step in the whole pipeline / 联系表自检循环——整条管线里回报最高的一步

Requirements / 依赖

Node.js ≥ 18 · Google Chrome or Edge · ffmpeg

npm install three puppeteer-core ffmpeg-static

⚠️ Recent npm versions block lifecycle scripts by default and will silently skip the ffmpeg-static binary download. Either run npm approve-scripts ffmpeg-static, or install @ffmpeg-installer/ffmpeg, which ships a prebuilt binary and needs no install script. 新版 npm 默认拦截生命周期脚本,会静默跳过 ffmpeg-static 的二进制下载。用 npm approve-scripts ffmpeg-static,或改装自带二进制的 @ffmpeg-installer/ffmpeg。


Install / 安装

git clone https://github.com/ayst-z/music-code-mv
cd music-code-mv
dsh plugin add .
dsh --profile demo --dump-config | grep dsh-music-code-mv   # should show a "# == dsh-music-code-mv" layer
# Windows / Windows 下等价写法:
# dsh --profile demo --dump-config | findstr /C:"dsh-music-code-mv"
dsh --profile demo

This package ships plain JavaScript, so there is no build step and no allowBuilds authorization prompt. 本包发布的是纯 JavaScript,没有构建步骤,也不会触发构建授权提示。

Other routes / 其他方式:

dsh plugin --profile demo add github:ayst-z/music-code-mv#<sha>  # from git, pinned / 从 git,锁 commit
pnpm pack && dsh plugin --profile demo add ./dsh-music-code-mv-0.2.0.tgz   # from a tarball / 从 tarball
dsh plugin --profile demo remove dsh-music-code-mv                   # uninstall / 卸载

Tools / 工具

The plugin registers seven tools on ctx.tools. / 插件在 ctx.tools 上注册七个工具。

music_mv_guide

Read the bundled authoring guide. Call this before directing a video. / 读取内置创作指南。指导一支视频之前先调它。

paramtyperequireddescription
topicstringnoskill (default) · styles · techniques · threejs · environment · lineage / 主题,默认 skill

music_mv_probe

Check the machine: Node, Chrome/Edge, ffmpeg, puppeteer-core, three.js, and a live WebGL context. Prints READY or names exactly what is missing. / 检查本机环境:Node、Chrome/Edge、ffmpeg、puppeteer-core、three.js 与真实 WebGL 上下文。打印 READY,或明确列出缺什么。

paramtyperequireddescription
projectDirstringnodirectory to probe for a local node_modules / 要探测 node_modules 的目录,默认当前目录

music_mv_init

Scaffold a project: timeline, seeded PRNG, Canvas2D stage, lyric parsing, and a working 21-second six-shot demo. / 生成工程骨架:时间线、种子化 PRNG、Canvas2D 舞台、歌词解析,以及可直接跑的 21 秒六镜头 demo。

paramtyperequireddescription
dirstringyesproject directory to create / 要创建的工程目录
forcebooleannooverwrite a non-empty directory / 覆盖非空目录

music_mv_render

Render a contact sheet, stills, or a full MP4. Frames are cached, so a re-run resumes instead of starting over. / 渲染联系表、静帧或完整 MP4。帧有缓存,重跑是续渲而不是从头开始。

NumPy 引擎的 hi-res / HDR 通道(render-np.py,与上表同契约):

能力命令说明
流式输出--stream帧直管道给 ffmpeg,frames/ 零字节(4K120 一次渲省 17–18 GB);代价是不能断点续渲
hi-res--w=3840 --h=2160 --fps=120 --format=jpegCLI 覆盖工程参数;frames/.renderpass 档位指纹防止复用错档缓存;jpeg 比 png 快约 3 倍
HDR10--depth=10 --hdr10强制走流式:v*257 → rgb48le → yuv420p10le + BT.2020/PQ + libx265
HDR Vivid--hdr-vivid自动升 10-bit,逐帧算动态元数据写 <out>.hdrvivid.json(本机 ffmpeg 无 CUVA 编码器,SEI 由下游合入)

实测:4K120 HDR10 流式 51 ms/帧、落盘 0;apply_fx 优化后 76→16 ms(bloom 走 1/4 分辨率)。详见 skill/reference/numpy-pillow.md。

paramtyperequireddescription
projectDirstringyesproject directory containing index.html / 含 index.html 的工程目录
modestringnocontact (default) · stills · video · sheet / 渲染模式,默认 contact
outstringnoe.g. out/video.mp4 / 输出路径,如 out/video.mp4
stillsstringnocomma-separated timestamps, for mode=stills / 逗号分隔的时间戳,配合 mode=stills
width heightnumbernoframe size / 帧尺寸
fps durationnumbernotiming / 帧率与时长
keysnumbernokeyframes in a contact sheet (default 12) / 联系表关键帧数,默认 12
audiostringnoaudio file to mux / 要合入的音频文件
forcebooleannoignore the incremental cache / 忽略增量缓存
keepFramesbooleannokeep the frames directory (it is the cache) / 保留帧目录(它就是缓存)
workersnumbernoparallel Chrome processes, default 1 / 并行 Chrome 进程数,默认 1
glstringnoauto(default) · gpu · soft / GL 探测策略,默认 auto(仅 chrome 引擎)
enginestringnochrome(default) · node / 渲染引擎;node = 无浏览器 skia 快速路径(需 @napi-rs/canvas)
formatstringnojpeg(default) · png / 帧容器格式;jpeg 快约 3×,png 无损
qualitynumberno1-100,默认 95 / JPEG 质量
orientationstringnolandscape · portrait / 未同时给宽高时的 4K 方向默认
depthnumberno8(default) · 10 · 12 / 输出色深;12 = HEVC main12(自动切 libx265)

music_mv_lyrics

Write lyrics into a project and point project.json at them. Malformed LRC reports the line number; zero cues refuses to write. / 把歌词写进工程并把 project.json 指向它。畸形 LRC 报出具体行号,0 条 cue 拒绝写盘。

paramtyperequireddescription
projectDirstringyesdirectory containing project.json / 含 project.json 的工程目录
lrcstringyesfull LRC text, one [mm:ss.xx] cue per line / LRC 全文,一行一条时间标签
modestringnoreplace(default) overwrites lyrics.lrc; append adds cues / 覆盖或追加

Output: { path, cues, firstCue, lastCue } (times in seconds) / 输出:路径、cue 数、首尾时间(秒)。

music_mv_diff

Determinism / difference check between two rendered frames: sha1 byte-compare first, then PSNR. Missing frames name the exact file. / 两帧之间的确定性与差异校验:先 sha1 字节比较,再算 PSNR;缺帧会报出具体文件名。

paramtyperequireddescription
projectDirstringyesdirectory containing frames/ / 含 frames/ 的工程目录
anumberyesfirst frame index (non-negative) / 第一帧帧号(非负整数)
bnumberyessecond frame index / 第二帧帧号

Output: { frameA, frameB, identical, psnr, note } — identical frames return psnr: null / 输出:帧号、是否一致、PSNR;完全一致时 PSNR 为 null。

music_mv_studio

「MV 工坊」图形界面的入口:返回工作室地址、挂载状态、工程数量与当前渲染任务。 / The MV Studio entry point: returns the studio URL, mount state, project count and the current render job.

paramtyperequireddescription
actionstringnostatus(默认摘要)· url(只要地址)· job(只看当前任务)/ status · url · job

没有 webServer 的 profile(例如只装 @deepseek-ai/dsh-base)里,图形界面不挂载,工具会说明原因;七个工具本身照常可用。 In a profile without webServer the GUI is not mounted and the tool says so; the other tools keep working.


图形界面 / MV Studio GUI

宿主半边把工作室挂在 DSH 自带 webServer 的 /music-mv 前缀上;浏览器半边注册一个右侧边栏页面类型,主体是原生 DOM 的状态镜像(工程数、渲染状态、离线交接),不含 iframe、不调 window.open——所有交互都在 codeMV 弹层里完成。 The host half registers the studio under /music-mv on the DSH webServer; the browser half adds one right-sidebar page type whose body is a native-DOM status mirror (project count, render state, offline hand-off) with no iframe and no window.open — every interaction happens inside the codeMV popup.

route作用 / purpose
GET /music-mv/studio中文工作室页面 / the Chinese studio page
GET /music-mv/api/state工作区 + 工程列表 + 当前任务 / workspace, projects, current job
POST /music-mv/api/probe跑一次环境自检 / run the environment probe
POST /music-mv/api/render开始渲染({ project, mode, width, height, duration, keys, workers })/ start a render
POST /music-mv/api/cancel取消当前任务 / cancel the running job
GET /music-mv/api/job任务快照(进度 + 日志尾部)/ job snapshot with progress and log tail
GET /music-mv/api/file?path=<rel>预览联系表 / 成片(支持 Range、download=1)/ preview or download an artifact
GET /music-mv/api/text?path=<rel>读 storyboard.md、lyrics.lrc 等文本 / read a text file

控制面板 / the control panel(全新)—— 对话视图环标签页「MV 工坊」:首屏 hero「一键进入子代理」主色大按钮 + 四级降级说明 + 当前预设回显;下面依次排开三节:总览(状态:工作区 / 工程数 / 任务·进度·速度·预计·状态五条分条)、工程进度(每个工程一行:缩略图 + 名称规格 + 右侧原生进度条与「61% · 386/630 帧」;正在渲染的行描主色边;算不出就显示「—」不画假条——进度口径是「运行中→任务实测 pct,否则→帧缓存覆盖率 frames÷(时长×帧率)」)、渲染状态(全局进度条),再加预设区(清晰度含自定义档、风格 17 档、帧率 6 档、⇄ 横竖屏)与钉底三动作(渲染联系表 / 风格画廊 / 复制路径):

codeMV control panel

这张图是 node tools/make-panel-shots.mjs 用真实 lib/client.js 组件(连样式都由真实代码 ensureEntryStyle() 注入)经迷你 React 运行时挂载后截的——结构、文案、CSS 全部来自仓库源码;状态数据是写死样例(工作区路径掩码为 <workspace>、无渲染任务),所以它是组件渲染图,不是运行中 GUI 的抓图。可复现:同一条命令重跑即得。 Captured from the real component (the shot tool mounts lib/client.js with a minimal React runtime and lets the real code inject its own CSS), so structure, copy and styles come from the repository's source. The state is a fixed sample with a masked workspace path — a component render, not a live-shell capture.

工作室 HTTP 面 / studio HTTP surface(深色 / 浅色,配色跟随 DSH 的 DeepSeek 主题):

深色 / dark 浅色 / light

操作面只有一个:标签页 / one working surface: the tab。对话视图环里的「MV 工坊」标签页(role="region",标题即 type.label)承载全部交互——没有标题栏小按钮、没有右下角悬浮窗,也不需要展开/收起外壳:标签页本身就跟对话、轨迹平级,铺满视图区。全部用标准 DOM 标签 + DSH 设计令牌实现,不创建自定义元素、不内嵌网页。

第一屏是 hero 主舞台:**「一键进入子代理」**主色大按钮 + 「四级降级…每一级都如实回报」说明行 + 当前预设回显(如 当前预设:标准 1280×720 · DeepSeek 蓝黑 · 30 帧/秒,未选时如实写「按工程默认开工」)。点之前就知道会用什么参数开工。

状态区读 /music-mv/api/state 的实测值;接口不可达就如实写「离线」,不摆占位数据。动作:

动作位置降级链 / fallback chain
一键进入子代理(hero 主按钮)首屏宿主原生 agentTeams.spawnTeammate → POST /music-mv/api/kickoff → 当前会话发出「以子代理/队友形式开工」→ 复制开工指令到剪贴板;每一级都如实回报走到哪一级,绝不谎报成功
渲染联系表钉底插件自己 POST /music-mv/api/render(不经模型);没有工程就说没有,失败就报失败,渲完同源 <img> 直接预览
风格画廊钉底17 套预设的离线内置展示图(384×216 WebP data-URI,零网络零路由);回落链:内嵌图 → 宿主真实配色渐变 → 灰块+如实标注,绝不编颜色
复制工作区路径钉底剪贴板被拦时如实报「复制失败」

预设区:清晰度(含自定义档,宽/高 16–7680,localStorage 记忆)、风格(17 档,中文名三级回落:宿主 title 中文段 → 内置中文名 → 英文 id)、帧率(跟随工程 / 24 / 25 / 30 / 60 / 120),下拉右侧 ⇄ 横竖屏切换(先尝试对上内置档,对不上落自定义;非法输入不写进开工提示词)。三者都会写进开工提示词。

The tab is the only working surface — no title-bar chip, no floating dock, no shell to expand: it sits alongside 对话/轨迹 in the conversation view ring and fills the view. Its first screen is a hero stage with the one-click subagent button, the four-stage fallback note and a readout of the presets that will be used, so you see the parameters before you click. Below it live the measured /music-mv/api/state values (or an honest offline), the preset controls and three pinned actions.

两处原生入口 + 一处只读镜像 / two native surfaces plus a read-only mirror:

  1. 对话视图环标签页「MV 工坊」 —— 注册进宿主 conversation.view(order:20,与「对话」「轨迹」并列),标签条按注册项自动生成、宿主 activateView 切换、仅激活时挂载;role="region"、不劫持焦点,铺满视图区,全部交互都在这里。
  2. 右侧边栏「MV 工坊」 —— 只读原生状态镜像(无 iframe),首次激活自动打开一次;提示文案指向标签页。
  3. (另可浏览器直连)http://127.0.0.1:<port>/music-mv/studio,或让模型调 music_mv_studio 拿地址。

标题栏没有小按钮、右下角没有悬浮窗——源码有反向断言防止回归。

The only interactive surface is the MV 工坊 tab in the conversation view ring (conversation.view, order:20, mounted only while active, role="region", never steals focus); the sidebar stays a read-only native status mirror, and the HTTP studio URL remains available for browsers and the music_mv_studio tool. Reverse assertions in the tests keep the title-bar chip and the floating dock from coming back.

无服务也能用 / works without the service:没有 webServer 的 profile(headless、TUI、纯 base)里,工作室状态拿不到,侧栏状态镜像与弹层自动进入离线模式——不轮询、不发请求,「把要求交给模型」用一段以 /music-code-mv 开头的交接提示走队友/子代理降级链;渲染完成后联系表会作为图片直接回到对话里。HTTP 路由只是给状态与直渲加速的可选项,不是插件的必需品。 In a profile without webServer the studio page is absent and the sidebar body switches to offline mode: no polling, no requests, actions go straight to the model (kickoff still falls back through the teammate/subagent chain), and contact sheets return to the chat as image blocks. The HTTP routes are an optional accelerator, never a requirement.

边界 / boundaries:所有路径都解析到工作区内,.. 越界一律 403;只允许读,不在界面上改工程源码;同一时刻只跑一个渲染任务。界面路由直接挂在 webServer 上,因此只监听回环地址(127.0.0.1)。 Every path resolves inside the workspace root and .. escapes are rejected with 403; the GUI never edits project sources; one render job at a time. The routes sit on the loopback-only webServer.


预设 / Presets

17 个开箱即用的预设:一条命令拿到配色、后期、时长、分镜与占位歌词,生成即可渲染。4 个氛围 + 12 个主流 AI 模型品牌配色 + 1 个角色智能体(品牌色取自官网 CSS 与官方 logo SVG),下面是全部的实拍联系表。 17 ready-to-use presets: one command yields palette, post-processing, duration, storyboard and placeholder lyrics. Four mood presets, twelve mainstream AI-model brand palettes and one character agent (brand colours pulled from official CSS and logo SVGs); below are real renders of all of them.

claude 橙白deepseek 蓝黑doubao 蓝橙dusk-lofi 落日低保真
claudedeepseekdoubaodusk-lofi
gemini 渐变gpt 黑白grok 黑橙ink-paper 纸墨
geminigptgrokink-paper
kimi 蓝llama Meta 蓝midjourney 墨蓝mistral 暖橙
kimillamamidjourneymistral
neon-rain 霓虹雨夜phosphor 磷光终端qwen 紫zhipu 智谱 三色
neon-rainphosphorqwenzhipu

角色智能体预设 / character agent preset —— 配色 + 风格 + 性格一次配齐,既是色表也是一位能对话的创作伙伴(persona 字段写死特质、说话方式、外形约束与工作规矩):

fairy 仙灵 / Fairy
fairy
node skill/scripts/init.mjs my-mv --preset=deepseek  # 套用预设 / apply a preset
node skill/scripts/init.mjs --list-presets           # 列出 17 个预设 / list all 17
node tools/make-docs-images.mjs                      # 重出上面这些图 / regenerate these images
python skill/scripts/audit-presets.py                # 配色纪律测试 R1–R4 / palette discipline test

细节见 skill/reference/presets.md。


展示短片 / Showcase short

feature-demo 是一支 76 秒的全功能巡礼短片:开场 codeMV 字标弹性归位 → 16 预设色卡巡游 → 显示器家族六连拍(CRT 磷光 / VFD 荧光 / LED 点阵 / 机械翻牌 / 电子墨水 / VHS)→ 手写透视 3D 与后期通道逐个点亮 → 双引擎分屏同绘 → CRT 关机塌缩收尾。旁白由 MiMo TTS 六段合成,每段都先合成、量到真实时长再排分镜,最后按镜头起点摆位混成一条音轨。

规格 / spec —— 母版 3840×2160 · 120fps · AV1 + AAC · 76.00s(953 MB,属渲染产物,不入库);下面是派生的文档小样 1280×720 · 30fps · h264 · 2.2 MB,已按体积纪律放进 reference/video/。

下载这支短片 / download the clip

分镜联系表(12 张等距关键帧,自检用)/ storyboard contact sheet:

feature-demo showcase

node skill/scripts/init.mjs feature-demo --preset=deepseek            # 脚手架 / scaffold
node skill/scripts/tts.mjs --batch=narration.json                     # 六段旁白 / six narration clips
node skill/scripts/render.mjs --project=feature-demo --contact --w=480 --h=270   # 自检 / self-check
node skill/scripts/render.mjs --project=feature-demo --out=out/video.mp4 \
  --audio=narration/track.wav --workers=10                            # 成片 / master

机器自检会把三处分开报:webgl(能力门)、gpu (hardware GL)(实际在用的显卡)、encoder (live test)(真编一帧后的编码器)。详见 skill/reference/techniques.md 的 GPU 加速一节。The probe reports WebGL capability, the GPU actually in use, and the encoder after a real test frame — see the GPU section in techniques.md.


3D 能力展示 / 3D capability showcase

showcase-3d 是一支全 3D 的 31 秒短片,用新的 fairy 预设配色,按 reference/threejs.md 的豪华场面清单逐条打底——共享渲染器 + EffectComposer + UnrealBloom,2D 只负责排版与收边(fx: FX3D 关掉重复的 bloom/色差/扫描线):

Six shots, all WebGL: ① 30k-particle nebula with an expanding shock ring → ② 120 instanced emissive pillars over a mirrored floor, lit wave sweeping through → ③ a glowing ring tunnel with a gate flash → ④ a metallic knot with two sweeping lights → ⑤ seven halos snapping into alignment under a crisp codeMV title → ⑥ 24k particles collapsing to an ember, then a clean power-off.

#镜头 / shot事件 / the one event
1粒子星云 swarm金色冲击环从中心扩出
2发光柱林 pillars点亮波沿 z 推进,柱子逐根亮起
3发光隧道 tunnel相机穿过的门环炸亮
4金属结 knot高光扫过表面
5光环阵 halo七环对齐到同一平面
6坍缩 collapse塌成一点余烬 → 关机

下载 / download the 3D clip

3D 联系表 / storyboard contact sheet:

3D showcase

实测性能 / measured performance:930 帧 720p → 17.3s(8 workers,约 54 fps 吞吐、18.5 ms/帧),编码器日志自动带 [hardware verified — test frame encoded]。同一分辨率下 Canvas2D 全 FX 约 255 ms/帧——走硬件 GL 的 3D 反而更快,因为 FX3D 把重复的2D 后期关掉了,辉光在 GPU 上由 UnrealBloom 一次做完。930 frames of 720p in 17.3s (8 workers, ~54 fps, 18.5 ms/frame) versus ~255 ms/frame for Canvas2D with the full 2D FX chain — hardw