解说视频,统一风格
每个视频共享一种外观和一种运动语言,最初为CRM解说视频构建。
黄金参考是 reference/desk-crm-explainer.html(84.5 秒,9 个场景,一个名为 Desk CRM 的虚构产品)
及其帧网格 reference/contact.png。如有疑问,请打开参考文件并复制模式。
此技能中的文件:
| 路径 | 说明 |
|---|---|
templates/explainer-template.html | 从这里开始。包含完整助手工具包及 3 个示例场景(标题、带光标点击的卡片、结尾)。 |
templates/apply-theme.mjs | 将 themes/ 中的主题应用到视频的 HTML 中(--theme studio --html explainer.html,--list)。原地运行。 |
themes/*.json | 每个主题的外观和声音(house、studio、ember、tide):颜色、渐变、字体、卡片圆角、标志标记、音乐调性、进行、节奏、琶音。house 是默认值。 |
templates/render.mjs | Playwright 帧步进器管道到 ffmpeg。视频、海报、联系表、静态帧。原地运行,从不复制。 |
templates/compose.py | Numpy 音乐背景及与场景本地时间同步的音效,母带处理并混流。每个视频复制一份。 |
templates/voiceover.sh | 可选的 macOS say 画外音,在音乐下方闪避。带参数原地运行。 |
checklist.md | 评审清单。交付前每项必须通过。 |
reference/ | 参考 HTML 及其联系表。请勿编辑。 |
examples/tidy-tasks/ | 基于模板构建的短成品视频(20 秒):HTML、其 compose.py 和联系表。 |
每台机器一次性安装:在技能文件夹中(包含 package.json)执行 npm install 和 npx playwright install chromium,外加 ffmpeg 和带 numpy 的 Python 3。render.mjs 会在无法启动时说明缺少什么。
外观
一种运动语言,多种外观。以下描述默认主题 house。主题更改调色板令牌、渐变、字体、卡片圆角、标志标记和音乐;它从不更改运动、光标、字幕或清单。相同主题加相同场景产生相同的视频,帧对帧。主题位于 themes/*.json(house、studio、ember、tide);node $SK/apply-theme.mjs --list 显示它们,--theme <name> --html explainer.html 将一个主题印入 HTML 顶部的 THEME 块。compose.py 从同一块读取音乐设置。简报指定主题;如果没有指定,使用 house。对于新主题,复制一个 json,更改令牌,保持 gr、am 和 rd 可识别为绿色、琥珀色和红色,选择一个在渲染机器上存在的字体,并在使用前检查联系表的对比度。
每个场景的主题(可选):将更多主题对象粘贴到 THEMES 中,并给场景指定 theme: 'studio'。调色板、渐变和卡片圆角在 1 秒的交叉淡入淡出中变化;字体和标志标记在边界处切换;音乐保持第一个主题的。当视频本身是关于多样性时使用它;通常使用一个主题。
舞台:1920x1080 SVG,字体 'Avenir Next', 'Helvetica Neue', Helvetica, Arial, sans-serif(主题 font)。
背景,三层,在主题内从不更改:
- 径向渐变,中心位于 50% / 30%,r 75%:
#172638->#111b26(60%)->#0f1720 - 点网格:40 px 图案,r 1.6 点
#22303f不透明度 70% - 字幕条:底部 200 px(y 880..1080)渐变为
#0b121a不透明度 90%
调色板令牌(模板中的 C,保持名称不变):
| 令牌 | 十六进制 | 用途 |
|---|---|---|
| bg | #0f1720 | 页面,淡出到黑色目标 |
| s1 | #141d27 | 卡片表面 |
| s2 | #1b2733 | 行、内嵌、内部面板 |
| bd | #2a3a4b | 边框、网格线、空点 |
| tx | #e6edf3 | 主要文本 |
| mu | #a0b1c5 | 次要文本、列标题 |
| bl | #3b82f6 | 操作、选择、数据包、光标爆发、品牌强调词 |
| gr | #2fca73 | 完成、实时、增益、成功 |
| am | #f59e0b | 注意、热点、异常值 |
| rd | #ef4444 | 仅限损失或错误 |
| off | #3a4a5c | 非活动状态点 |
| paper / ink | #f3f6fa / #1b2733 | 浅色文档页面 |
| light blue | #93c5fd,核心 #dbeafe | 套索、高亮、数据包核心 |
| click spark | #ffd166 | 点击爆发的备用辐条 |
渐变:logoG 蓝色 #3b82f6 到绿色 #2fca73(对角线)用于标志磁贴和下划线栏;hotG 琥珀色到红色用于“热点”栏;blueBar #2563eb 到 #3b82f6;areaG 绿色 38% 到 0 在图表下方。
形状:
- 卡片:圆角 26,填充 s1,2 px bd 描边,阴影
dy 16, blur 20, black 42%(card())。 - 行:圆角 14..18,填充 s2,高度 52..80,间距 64..96 px。
- 标签:完整药丸形,高度 40,颜色填充 16%,标签 24 px / 600 使用该颜色(
chip())。 - 主要按钮:圆角 22,高度 84,纯色 bl,白色 34 px / 700 标签,柔和光晕脉动直至点击。
- 图标和药丸的小阴影:
dy 8, blur 8, black 45%(#shs)。 - 应用窗口(参考
dashboard()):66 px 顶部栏,s2,交通灯点 r 8(rd、am、gr 不透明度 80%),214 px 侧边栏#111922,导航项高 48 圆角 14,活动项 bl 不透明度 20%,KPI 磁贴圆角 18。 - 状态点 r 14;头像环 4 px 加 25% 光环;挂锁来自
lock()。 - 品牌标志:logo 46 px 加名称 28 / 700 位于 (56, 40),不透明度 85%,从场景 2 开始显示直到结尾。
字号(px / 字重):字标 132 / 700(结尾 96),标语 58 / 500 mu,结束语 56 / 600,字幕 50 / 600,大数字 52..64 / 700 表格数字,卡片标题 34..40 / 700,行文本 26..28 / 600,标签和标签 24 / 600,没有低于 22 的。字标字母间距 -1%。
构图规则:
- 内容位于 y 120..860 和 x 140..1780 区域内。字幕条和品牌标志角保持清晰。这包括静止的光标:保持其尖端在 y <= 800(箭头在尖端下方约 75 px 处)。
- 任何由文本决定大小的元素(划线、下划线、高亮框、药丸)其宽度来自
textW(str, size, weight),绝不使用猜测的常量。 - 永远不要让帧的三分之二为空。当内容左右分割时,用流程线、数据包或扇形页面连接中间。移动整个场景组(
G(s, {x: SX}))以重新居中。 - 一个场景一个想法。最多并排放置两张卡片加一个详情卡片。
- 数据总是虚构的:Client A、Northwind、Maple Ridge、Bluebird、Harbor Point、ACC 01。
运动语言
缓动工具包(在模板中):E 立方缓入缓出(所有内容的默认值),EO 立方缓出(稳定),EB 回弹缓出,约 10% 过冲(弹出:卡片、标签、徽章、图标),esine 用于绘制路径,fadeIO(t, a, b, 0.35) 用于光标不透明度,五次方缓出 1 - (1 - x)^5 用于计数器。
确定性:仅使用 rng(seed),绝不使用 Math.random 或挂钟时间。
入场:
- 卡片:0.5 秒淡入加 20 px 上升 0.6 秒,或缩放
mix(0.92, 1, EB)0.7 秒。 - 列表行:交错 0.08..0.12 秒,从 x -20 / -30 或 y +16 滑入,每行 0.5 秒。
- 弹出:
EB0.5..0.7 秒。徽章缩放 0.7 -> 1。 - 字标:从中心开始的剪辑擦除展开 0.8 秒并伴有 34 px 上升;logo 标记使用
pathLength绘制。
光标工具包(drawCursor,curPos):
- 白色箭头路径
ARROW,#0b11183.4 px 轮廓,投影 dx 4 dy 7 blur 4 不透明度 50%,基本缩放 1.1。 keys: [[t, x, y], ...]以本地秒为单位,(x, y) 是箭头尖端。滑动使用立方缓入缓出加上侧向弧线,弧线距离的 12%(最大 110 px)。倾斜跟随水平速度(每 px 0.35 度,最大 14 度)。- 典型滑动 0.7..1.5 秒。从帧外 (1880, 1080) 进入,约在场景开始后 1.5 秒。
- 在点击前至少 0.15 秒到达,并精确坐在控件的中心。
- 点击:在点击时(窗口 0.34 秒,从提前 0.1 秒开始),横向挤压 +16% 纵向 -22%,然后是一个 0.6 秒的爆发:蓝色环 r 8 -> 54 变细 6 -> 1 px,加上 8 条辐条交替白色 /
#ffd166。 - 被点击的控件用
press()缩放到 0.93,其光晕脉动停止。 - 动作后,滑动到安静的休息点(卡片之间,例如 (1010, 800))并保持。随场景一起淡出。
trail在绘制时添加一个 12 点的蓝色彗尾;pos替代keys用于自定义路径(套索)。
标志性动作(要复制的参考场景):
- 套索:光标用
esine绘制一个摇摆椭圆,虚线#93c5fd5 px(16 12,流动),闭合时实线并伴有 0.35 秒光晕闪光和 7% 填充,然后图标沿曲线路径飞入一个幽灵框架,该框架固化为应用窗口(sBefore)。 - 数据包:发光点(r 22 光晕加 r 12
#dbeafe核心)带有 6 点彗尾,沿 S 曲线运动,立方缓入缓出 1.2..1.45 秒,虚线引导线以 24 px/s 流动,发送方闪烁蓝色,到达时绿色环(packet(),sClose)。 - 状态点:灰色 -> 绿色,伴有环爆发(r 14 -> 40,0.6 秒)和 1.25x 弹出,然后呼吸光晕
0.25 + 0.2 sin(3t)。警告:琥珀色,每 1.3 秒重复环,短暂抖动(statusDot(),sStatus)。 - 图表绘制:
pathFrom1.5..3.7 秒内揭示线条,6..7 px 绿色,areaG填充,发光头部点(r 18 光晕加 r 10 白色)。条形图从零开始,交错 0.18 秒增长。热力图单元格交错弹出(sAlgos,sHistory)。 - 计数器:使用五次方缓出在 1.0 秒内计数,表格数字。
- 页面扇形:页面离开按钮,穿过中心成扇形展开(旋转 -10、-3.5、3.5、10 度,60 px 跳跃),然后每个跳跃 110 px 进入一个托盘,缩放 0.56,交错 0.55 秒;托盘满时发光绿色(
sReports)。 - 组织扇形:线从点击的头像绘制到团队列,锁扣关闭,虚线轮廓将办公桌分组(
sBook)。 - 清单(模板工具包):
checkbox()圆形复选框点击时下压,弹出绿色并绘制对勾;strike(x, y, textW(...) + 8, u)划掉标签;每个勾选发送一个packet()给progressRing(),该环每次到达时缓进一步,并在关闭时发光。一个列表场景是复选框 + 划线 + 数据包 + 环(参见examples/tidy-tasks/)。
过渡:场景背靠背。每个场景在其最后 0.5 秒淡出,下一个在其前 0.5 秒淡入,并带有 0.985 -> 1 的缩放稳定(通过背景的下沉)。第一个场景从实心开始,结尾以自身 0.6 秒淡出到 bg 结束。过渡帧故意接近空白;不要“修复”它。
保持和空闲运动:每一帧都有东西在移动。使用流动的虚线偏移、呼吸光晕(sin(3t))、bob() 浮动 3..5 px、慢速旋转器(60 度/秒)、漂移图标(18 / 14 px)。在场景最后一个节拍后至少保持 1.5 秒的停留,以便字幕完成阅读。
文案规则
- 英文字幕,句子大小写,以句号结尾。一行或两行,每行最多约 48 个字符。
- 屏幕显示时间(字幕在 0.45..1.05 秒内淡入,在
dur - 0.75时淡出)必须至少每 4 个单词 1 秒,且绝不能低于 2.5 秒。实际上,一个场景从不会短于约 5 秒。 - 字幕或屏幕上不得使用破折号作为标点(不允许长破折号、短破折号或空格连字符)。使用逗号和句号。
- 仅限真实的声明。屏幕上的数字(客户、账户、间隔)来自用户或产品,绝不虚构。模板中的数字标记为占位符。没有真实数字(预告片,虚构产品)?使结尾
STATS为纯文字,如['Simple lists', 'Daily focus', 'Clear progress']:标签弹出而不是计数。 - 无真实客户数据:无真实姓名、账户号码、余额、电子邮件或客户标志。使用虚构集合。
- 标题和结尾不承载字幕;标语和结束语完成该工作。
架构
- 一个自包含的 HTML 文件,无网络,无库。SVG 舞台加一个 IIFE 脚本。
render(t)是纯函数:它仅根据 t 重建#frameinnerHTML。公开为window.renderAt(t),并包含window.TOTAL_DURATION和window.SCENES_INFO。如果 URL 中没有#manual,则以实时循环运行。SCENES = [{ id, start, dur, fn, cap }],背靠背。保持每个条目在一行内,按此键顺序书写,并将const TOTAL = <number>;作为字面量:compose.py使用正则表达式解析两者。- 一个场景是
fn(lt, dur) -> { svg, cursor? },使用本地时间lt。场景内的所有节拍时间都是本地常量(click、send(i)、onT(i)),音频脚本镜像此模式。 - 助手:数学(
clamp lin E EO EB mix f rng fadeIO bob),svg(T G R Ci card chip check avatar lock logo wordmark textW),图表(pathFrom walk scalePts spark areaChart bez),运动(ring statusDot packet press progressRing checkbox strike),光标(curPos drawCursor),caption。当不透明度约为 0 时,G()返回 '',因此隐藏层是免费的。 - 绘制顺序:场景内容、字幕、品牌标志、光标最后。
const STATS = [...]保持在一行的开头:compose.py读取它用于结尾声音。
工作流程
- 简报。受众、产品、3..6 个包含真实数字的真实声明、时长(完整版 60..90 秒,预告片 20..40 秒)、发布位置以及主题(
house、studio、ember、tide或一个新的 json)。 - 故事板。一个表格,包含场景 ID、持续时间、字幕、视觉隐喻、光标动作和节拍时间。 弧线:钩子(logo,标语)-> 之前(痛点)-> 每个功能一个场景 -> 结尾(统计或文字标签,结束语)。 在构建前根据文案规则检查字幕计时。
- 构建。在工作文件夹中,将
SK设置为此技能的templates文件夹 (例如SK=~/.claude/skills/explainer-video/templates):cp $SK/explainer-template.html explainer.html && cp $SK/compose.py .切勿编辑技能副本。 应用主题:node $SK/apply-theme.mjs --theme <name> --html explainer.html(house主题跳过此步)。 设置BRAND,替换示例卡片场景,在标记块中添加场景,更新start和TOTAL, 设置STATS。从参考中提取模式。 - 预览。在浏览器中打开 HTML(它会循环播放),然后在每个点击、着陆和边界处渲染静态帧:
node $SK/render.mjs --html explainer.html --stills 3.2,4.9,8.6 --stills-dir critique/v1。 - 渲染。
node $SK/render.mjs --html explainer.html --out name.mp4写入 MP4、-poster.png和-contact.png。 - 评审。对照
checklist.md阅读联系表和静态帧。每项必须通过;修复,重新渲染,重新评审。 - 音乐。运行
python3 compose.py name.mp4:它会为每个场景生成音乐和音效,与视频混流,输出name-music.mp4。 要添加 macOS 画外音:bash $SK/voiceover.sh --text "First line. Second line." --timing 2.5,5.8 --out name-vo.aiff然后传入$SK/compose.py --voiceover name-vo.aiff。 - 交付。最终文件:
<product>-<theme>-<name>.mp4,加上-poster.png和-contact.png。