从脚本生成动态图形视频
从HTML渲染的动态图形视频(动画文字、图表、截图、网页录制、图标、地图)的通用工作流。项目的品牌、色调、音乐和氛围存在于项目配置文件 VIDEO.md 中,不在此处。
脚本和模板位于仓库 C:\Mydrive\Claude Projects\motion-video\(scripts/、templates/)。
语言: 与Petr用捷克语交流。我们创建的所有文件(代码、注释、文档、配置文件、README)均为英语(简单英语,短句)。视频中出现的文字(字幕、标题)使用配置中的视频语言,通常是捷克语。故事板和播放器界面可通过 storyboard.json 中的 labels 本地化。
0. 项目配置文件
- 首先找到并阅读项目配置文件:项目文件夹中的
VIDEO.md或brand/video-profil.md,或其在 claude.ai 项目中的文本副本 (claude/video-profil.md)。 - 该配置文件会覆盖本技能的默认值(颜色、字体、Logo、音乐、语调、受众、措辞、标签、安全区域、示例位置)。
- 无配置文件:询问品牌和受众信息,然后从
templates/VIDEO.md创建一个。
1. 配置(唯一数据源)
脚本顶部的一个固定块。场景时间由此导出。
| 项目 | 示例 |
|---|---|
| 主题 | MultiModel in Meteoblue |
| 预设 | reel / video / feed 4:5 / square |
| 格式与设计分辨率 | 9:16 1080×1920 / 16:9 1920×1080 / 4:5 1080×1350 / 1:1 1080×1080 |
| 最终渲染 | 1080p,或4K(--scale 2 用于16:9) |
| 时长 | 60–75 秒 / 8 分钟 / … |
| 视频语言 | cs |
| 画外音 | 无 / 自有录音(词同步) |
| 字幕 | 硬编码 / 逐词 / SRT |
| 音乐 | 来自配置文件(文件 + 许可证) |
| 音效 | 是 / 否 |
| 实时网页录制 | 否 / 是(哪些网站及步骤) |
格式预设
| 预设 | 格式 | 时长 | 内容适应方式 |
|---|---|---|---|
| reel / short | 9:16, 1080×1920 | 最长3分钟(Reels、Shorts);检查FB Reels(通常引用90秒) | 一个想法,大号硬编码字幕,内容在安全区内(应用UI在顶部和底部),快节奏 |
| video | 16:9,设计1920×1080,渲染最高4K | 任意 | 分章节(每个章节的脚本和故事板,YouTube描述中的时间戳:第一个0:00,至少3个章节),可能需要画外音,更详细,节奏较慢 |
| feed 4:5 | 4:5, 1080×1350 | ~1–2分钟 | Instagram(以及LinkedIn)信息流帖子,比正方形高 |
| square | 1:1, 1080×1080 | ~1分钟 | 信息流帖子(FB、IG),字幕居中 |
“Reel”仅为一个预设:当Petr提到“reel”时,适用reel的时长、格式和节奏。
2. 工作流:脚本 → 故事板 → 审批 → 渲染
输出始终是一对 脚本 + 故事板,每次更改后都保持同步。 仅在有明确请求时进行最终渲染(“vygeneruj video”)。在此之前只有脚本、故事板和低分辨率预览。
- 在聊天中创建大纲:一个简短的部分编号列表(视频的章节)。保持简短。
- 逐部分开发: 时间、标题、屏幕上的确切字幕、画面、学到的内容、运动与过渡、声音。对于措辞问题,提供3-4个简短选项并推荐一个。仅润色用户的措辞以修正语法,并说明更改内容。
- 脚本 位于
<project>/<output>/scenar.md,并在 claude.ai 项目中保存相同副本。 头部 = 配置 + 上次渲染 + 故事板链接 + 状态。 - 故事板 = HTML 产物(一个链接,始终重新发布到同一个产物):
project/video.html包含场景和seek(t)(参见技术细节),即使在渲染之前也存在,project/storyboard.json:包含name、time、learn、motion、sound、items、changed的部分 (CHANGED 徽章仅用于自上次版本以来的更改),在最繁忙的时刻包含 1–6 个帧[time, caption], 可选的labels和lang用于界面语言,scripts/storyboard.py project/video.html project/storyboard.json sb/,scripts/player.py project/video.html sb/ --chapters project/storyboard.json [--audio mix.mp3]:故事板顶部的可播放预览, 带有章节时间线(类似YouTube)和评论:评论按钮 → 点击一个元素 → 包含时间、章节和元素的注释被复制到聊天中。音频必须是MP3(产物不提供.m4a),scripts/check.py project/video.html(参见检查);修复或报告发现的问题,- 使用
publish_files(模式replace)发布,包括截图、剪辑和MP3;将链接放入脚本中, - 以以下内容结束:“Storyboard je aktualizovaný. Napiš ‚vygeneruj video', nebo co změnit.”
- 每次评论后: 更新
video.html→storyboard.json→ 故事板 + 播放器 → 重新发布 → 更新两个副本中的脚本。简要回复更改内容。 - 仅应请求进行渲染,使用配置的分辨率。更改一个场景 = 仅重新渲染该场景。
输出名称不带变音符号,包含版本号(
reel1_multimodel_v5.mp4);在脚本中注明。 - 视频获批后,询问是否生成发布文案和缩略图(参见发布)。
3. 内容与节奏
- 一个输出 = 一个主要想法;在长视频中每个章节一个想法。
- 密度:每分钟约4–6个知识点和12–18个视觉变化;无静音超过约3秒, 但有足够时间阅读字幕(约每秒2–3个词)。
- 展示,而非罗列:图表、对比、因果关系、网站上的实际操作步骤。
- 验证关于网站、应用和功能的说法,需基于实时网站,而非记忆。不要虚构统计数据。
- 演示数据:在脚本中注明;是否在屏幕上标注由配置文件决定 (短格式:尽量少视觉噪音)。
- 过渡:默认为交叉淡入淡出;尽可能连接场景(图表变形为下一个场景,卡片扩展为一个场景)。
- 真实品牌和Logo必须真实且未经扭曲;切勿将第三方Logo放在演示数据上。
4. 检查
scripts/check.py project/video.html [--step 0.5] [--safe t,r,b,l]:检测安全区或画面外的文本、 溢出文本、低对比度(WCAG)、超过3秒的静音。默认安全区域按格式(9:16、4:5、1:1、16:9)设置; 配置文件可覆盖。scripts/keys.py project/video.html out t1 t2 …:在指定时间输出帧 + 联系表;查看它们。- 渲染后:从MP4中提取几帧(
ffmpeg -ss t -frames:v 1)、时长、响度。
5. 音频
- 音乐来自配置文件;将许可证(作者、标题、ID、来源)写入脚本。
scripts/mix_audio.py out/video_only.mp4 music.mp3 jingle.mp3 output.mp4 [--music-start s] [--jingle-len s] [--voice f] [--voice-start s] [--sfx f] [--target -14](无音乐则用-代替文件): 音乐在音乐之后降低音量,然后增强,在画外音下自动降低音量,最后淡出; 双通 loudnorm 至 −14 LUFS 和真峰值 −1.5 dBTP;视频不重新编码。- 跳过音轨的安静前奏(逐秒RMS),避免音乐后出现音量下降。
- 音效 配合内容,仅用于重要变化且音量远低于音乐:
scripts/sfx.py cues.json sfx.wav --dur <length>通过代码生成:whoosh(场景过渡)、click(帧)、 pop(卡片出现)、tick(标签)、swell(高亮)、riser(渐强)、thud(结论)。从时间线T和故事板中的 “sound” 字段获取时间(cues.json)。不存储音频文件;效果由代码生成。 在Claude Code中可选:earshot(MCP;252种声音作为代码,收听和同步检查),如果Petr安装了它(约1.1 GB模型)。 - 带词同步的画外音:
scripts/align_voice.py voiceover.wav project/ [--text script.txt](Whisper,捷克语) 创建vo.json、vo.js和vo.srt。在video.html中加载<script src="vo.js">并将图形与词同步:voAt('word')返回一个词的时间;逐词字幕使用wordCaption(el, t)(适用于9:16、4:5、1:1)。 录音是主时钟:从其获取时长和场景时间,绝不拉伸任何内容。 Whisper时间精度约十分之一秒;通过收听检查。--text比较实际文本与听到的文本。 - 库存音乐可能触发Content ID;使用许可证提出争议,而非“升级到申诉”。
6. 技术细节
- 页面
project/video.html(从templates/start.html开始):window.FORMAT={w,h}(设计分辨率), 场景作为<div class="scene">,时间线T={s1:[0,3.5],…},确定性seek(t)(无CSS动画、 计时器或Math.random();使用种子随机数),最后window.seek=seek; window.T=T;。 通过npm i @fontsource/<font>使用本地字体(播放器切换到Google Fonts)。将Logo内联为SVG。 - 实时网页录制(当需要展示网站操作过程时,替代静态截图):
scripts/record_web.py steps.json out/ [--width 1280 --height 800 --scale 2]:Playwright按照步骤 (click、type、hover、spot= 带暗淡背景的帧、zoom/unzoom、scroll、wait、mark) 浏览网站,带有滑动光标和点击波纹;输出web.mp4+ 包含步骤时间的marks.json。 在Petr的PC上运行(Claude Code);云沙箱无法访问正常网站。拒绝Cookie横幅。 在video.html中添加<video src="web.mp4" muted preload="auto">并使用vseek(video, time)(模板)移动; 渲染、检查和故事板需等待 seek 完成。 - 网站截图 使用Chrome中的Claude:
document.documentElement.style.transform='scale(2)'(原点0 0),将光标移开,save_to_disk;然后在视频中缩放和取景。 - 渲染
scripts/render.py project/video.html out/ [--scale S] [--only s3 s6] [--workers 4]: 每个场景并行生成一个MP4,CRF 18,concat-c copy。预览--scale 0.5,从1920×1080生成4K--scale 2。 - 音频
scripts/mix_audio.py(见上文)。
需要:Python 带 playwright、pillow、numpy,Chrome/Chromium,ffmpeg,Node(字体);对于画外音需要 faster-whisper。
7. 发布(获批并经同意后)
- 来自配置文件的社交媒体文本(Instagram、Facebook、YouTube):IG 3-5短行 + 末尾一个问题; FB单独上传(不从IG分享),文本更短;YouTube标题最多约60个字符,关键词在前, 描述(内容、位置、主要规则、相关视频、音乐),长视频的章节时间戳。 标签仅使用配置文件中的集合。保存到脚本中(“Texty k publikaci”部分)。
- YouTube字幕:上传
vo.srt(有画外音时)。 - 缩略图:reel 1080×1920 + 1280×720,视频 1280×720(YouTube);大号文字、主要图案、配置文件风格。 YouTube 可能不允许为 Shorts 设置自定义缩略图。