SaaS 推广视频(模板:“skill 1”)
此技能从一个配置文件 promo.json 生成一个完整的推广视频:经典的 ~11 秒版本,或当 promo.json 包含 chapters 时生成 ~50 秒的长版本。每个画布场景在无头 Chrome 中逐帧绘制。无需使用素材视频、AI 视频或模板服务:
- 图片: 用户自己的截图、应用 UI、设计稿或视频静帧。内置的 UI 卡片会填补任何空缺。
- 文字: 用户自己的文本。
- 声音: 每个提示点都有音效,外加原创合成背景音或用户自己的曲目。
结构固定,并模仿参考样片(skill 1 .MP4,一个 TikTok SaaS 机构样片)的节奏。仅复制其技术手法,绝不使用其素材、文字、品牌或水印。
| 时间 | 场景 |
|---|---|
| 0-0.5 秒 | 大号 glyph(# < @ ! ?)在中央闪烁;紫色和青柠色霓虹条和四角星芒在暗淡的点阵 glyph 场上频闪 |
| 0.5-3.3 秒 | text.typed 随光标打字出现;26 张卡片从远方飞入并围绕单词形成一个 3D 环(先显示半色调点,再显示真实图片);环加速、飞越摄像机并模糊消失 |
| 3.3-6.45 秒 | 带有云朵、鸟类和蝴蝶的彩绘草地,先呈现水彩效果,然后饱和度升高;三张卡片从右侧滑入,其余卡片飞入形成一个 12 卡片的 bento 墙。bento[0] 在英雄卡片上打字,bento[1] 在一张高玻璃卡片上垂直打字,两张卡片交换图片,bento[2] 在一张白卡上打字。然后摄像机拉近到该卡片 |
| 6.45-~8.8 秒 | 暗色点波场;一个发光渐变球体弹入并向左滑动;headline 逐字出现(模糊到清晰),然后 sub 擦入;所有元素失焦 |
| ~8.8-11.1 秒 | 故障效果(色相偏移、切片)进入英雄画面:一张长曝光蓝/白花朵图片,背景为蓝到橙的天空,飞散 ! @ # $ % * 符号和数字雨。from 淡入淡出,然后 to 伴随重击声出现,可选 Logo 显示在下方。影片以淡出到黑屏结束 |
时长约为 11.1 秒。如果标题较长,时长会略有增加,因为副标题始终有大约 0.85 秒的屏幕显示时间。
长版本(约 50 秒):chapters
添加 "chapters"(每个产品、项目或主题一个),相同的四个场景会作为拍段重复,每个 1.5 小节,结尾部分占用 2 小节:
| 拍段 | 播放内容 |
|---|---|
| intro | 开场(typed + 所有内容的旋转)→ 墙(所有图片,bento)→ 球体(headline / sub) |
| 每个 chapter | 开场(该 chapter 的 typed,其图片在旋转中;如果无 typed 则跳过)→ 墙(其图片优先,其 bento,其 wall 外观)→ 球体(其 headline / sub / orb 颜色) |
| end | 结尾(from / to / url / logo),2 小节 |
四个 chapter 包含三个打字开场共 23 小节,在 109 BPM 下约为 50 秒。
- 图片: 为每张图片添加
"tag"以归类到其所属的 chapter。 - 墙的外观:
"meadow"(白天)、"dusk"(日落)或"dark"(该 chapter orb 颜色下的暗色点波场)。交替使用它们可以使各 chapter 区分开来。 - 音乐同步:
- 当提供
music时,assets.py会测量歌曲的节奏及其高潮点(能量最大提升点,对齐到底鼓)。视频会调整开始时间,使得 intro 旋转后的第一个剪辑点落在高潮点上,之后每个剪辑点都位于小节网格上。 - 检查打印的
music: … bpm, drop at … s行。如果不对,请自行提供bpm和musicDrop(以秒为单位)。 - 使用
sfxLevel(例如 -4)来让音效位于歌曲之下。
- 当提供
- 版权: 商业歌曲可能导致视频在发布时被静音或版权声明。请提及这一点,并建议公开发布时使用平台自己的音效库。
要求:ffmpeg、Node 22+、Google Chrome 或 Chromium(CHROME_PATH),以及安装了 numpy 和 scipy 的 Python(PROMO_PY;promo.sh 会自动查找)。
工作流程
1. 收集推广视频所需内容
- 卡片(8-20 张图片): 产品、网站、应用或仪表盘的截图;设计作品;或用户视频的静帧。图片和视频都可以。视频会选取
"at"秒或视频长度 30% 处的静帧。横向图片会放入宽插槽,纵向图片放入高插槽。少于 8 张时,内置 UI 卡片会填补剩余位置(搜索栏、表单、图表、渐变球体、药丸等,并标记text.labels)。先查看图片,剔除大部分为空白的图片。 - 文字: 保持简短,因为场景会以固定速度打字和显示。
typed:一个单词或带标点的名称,约 4-8 个字母(例如 "SaaS."、"KumNit.")。bento:三个短词组(1 个、2-4 个和 2-3 个单词)。headline:5-8 个单词。sub:一行最多约 90 个字符。from/to:结尾的 "从… / 到…" 对。- 对于高棉语(
"lang": "km"),请使用自然的高棉语。在headline、from和to中希望逐块显示的块之间加空格。Kantumruy Pro 字体已包含。
- 可选:
logo:显示在最后一行下方。不透明的 logo 会变为圆角应用图标。text.url:结尾卡上的网站链接行。hero:用户自己的结尾图片,替代花朵。backdrop:替代彩绘草地的图片。music:用户自己的曲目。在长版本中,其高潮点会落在第一个剪辑点上;设置musicStart可以覆盖。chapters:约 50 秒的长版本,包含每个 chapter 的tag、typed、bento、headline、sub、wall和orb。sfxDir:用户自己的音效文件夹。colors:霓虹、球体、天空和符号的品牌颜色。
2. 编写项目
创建一个项目文件夹,将 examples/kumnit-saas.json(或 -km.json)复制为 promo.json,然后编辑它。每个键的描述见 references/config.md。路径相对于项目文件夹。
3. 预览(约 10 秒)
<skill>/scripts/promo.sh <project>/promo.json --preview
此步骤会准备图片(并测量音乐),然后渲染 12 帧静帧(长版本中每个拍段一帧)到 out/<name>-preview.png。查看它并检查:
- 打字单词与卡片之间没有重叠。
- 没有文字被挤压:长文本会自动缩小以适配,但可读性会变差。
- 英雄卡片(大、左侧)显示良好的图片:它会取
cards中的第一张横向图片。 - 结尾文字在花朵或英雄图片上清晰可读。
4. 渲染(经典版不到一分钟;长版本约 4 分钟,建议后台运行)
<skill>/scripts/promo.sh <project>/promo.json
阶段按以下顺序运行:assets、plan(时间线和来自场景的音效提示)、render(3 个 Chrome 渲染器,--jobs N)、mix、encode。
--from mix重新混合声音并重新编码,无需重新渲染帧。--from render重新绘制画面。
输出:out/<name>-1080p60.mp4 和 out/<name>-contact.png(视频中约 30 帧的概览)。
5. 交付前检查
- 查看联系表。
ffprobe应显示约 11.1 秒(经典版)或拍段总时长(长版本;build/cues.json列出每个拍段)。混音标准化为 -14 LUFS / -1 dBTP:使用ffmpeg -i out.mp4 -af ebur128 -f null -测量。- 混音阶段会打印有多少音效来自
sfxDir,有多少是合成的。 - 你无法听到结果,因此请告知用户你已检查的内容,并请他们试听。intro 点击声和草地冲击声是音量最大的时刻。
调优
- 时间:
scripts/scene.mjs顶部的plan()保存了经典场景时间。beatSpecs()布局拍段:mapT()将这些时间移动和拉伸到每个拍段中。cuesFor()中的音效提示会自动跟随,因为audio.py会从build/cues.json读取它们。
- 外观:
- 颜色来自
colors。 - bento 布局是
scene.mjs中的SLOTS表。 - 草地、花朵和球体分别在
buildMeadow、drawFlower和drawOrb中绘制。
- 颜色来自
- 声音:
sfxDir中尝试的文件名是scripts/audio.py中的SFX表,每个提示点会选取变体。背景音乐的和弦和段落位于make_bed()中。 - 尺寸: 仅限 1920×1080,如模板所示。垂直 9:16 版本需要自己的布局。