埃及宣传视频
完全在本地机器上构建一个约 60-70 秒的垂直宣传视频:
script.json ──► 旁白 (Gemini TTS, 免费) ──► 逐行片段 ──► 时间线
screenshots ──► promo.html (seek(t) 动画) ──► puppeteer 帧 ──► ffmpeg
synth.cjs (原创节拍 + SFX) ──► 侧链压缩混音 ──► loudnorm −14 LUFS ──► MP4 + WhatsApp 副本
每个场景的时长恰好等于其对应台词的长度,因此更改一个单词或语音会自动重新调整整个视频的时间。
经过验证的示例(餐厅点餐系统:繁忙的电话挂断 → WhatsApp 痛点 → 揭晓 → 菜单 → 购物车 → 二维码桌台 → 订单追踪 → 仪表板 → 统计数据 → 品牌 + 行动号召)是默认模板。对于其他产品,只需更改场景,无需改动引擎。
你需要什么
- Node 18+,ffmpeg/ffprobe 已加入 PATH 环境变量,Google Chrome(或设置
CHROME_PATH)。 - 在 build 文件夹中:
npm i puppeteer-core qrcode msedge-tts@2(如果在 C 盘,请将npm_config_cache和TEMP指向其他盘)。 - 一个 免费 的 Google AI Studio 密钥用于语音 (aistudio.google.com/apikey)。用户需要自己将其粘贴到
VIDEO/.env中,格式为GEMINI_API_KEY=…——只需创建文件并将密钥留空,永远不要在聊天中要求用户粘贴或打印密钥。首次调用可能会提示该项目的 Generative Language API 未启用:向其提供来自错误信息的控制台链接,让其点击 启用,然后在一分钟后重试。
文件夹结构
在用户的项目内创建 VIDEO/(例如 marketing/video-<brand>/):
VIDEO/.env GEMINI_API_KEY= (用户填写)
VIDEO/script.json 复制自 assets/script.example.json 并编辑
VIDEO/build/ 从此技能获取的 scripts/* + assets/template/*
VIDEO/build/img/ promo.html 使用的截图和 Logo
VIDEO/vo/ s01.wav … s10.wav (语音片段)
VIDEO/out/ 渲染输出, sheet.jpg, timeline.json
工作流程
1. 需求简述(仅询问无法自行找到的信息)
产品及其功能、目标受众(谁购买)、品牌名称 及其发音、配色方案 + Logo(在用户代码中查找:tailwind 配置、icon.svg、Logo 组件)、行动号召(CTA)、联系方式(如有)。默认格式:9:16,60-70 秒,埃及方言,男性充满活力的声音。
2. 脚本 → script.json
十行台词,每行对应一个场景。已验证的结构如下:
- 钩子 (0–4 秒):观众能识别出的痛点问题(例如“كام أوردر ضاع منك النهارده… عشان التليفون كان مشغول؟”)。
- 痛点:当前的糟糕方式,以损失结束。
- 揭晓:“طب تخيّل…” + 产品(此处节拍落下)。 4–9. 每个场景一个功能,每个都配有真实截图。
- 品牌 + 行动号召:谁提供的,邀请订阅/联系。
voice 是 TTS 阅读的内容:按埃及人的 说法 编写(عامية,“…” 表示呼吸,“?” 表示疑问语气,数字用词语表示如“أربعة وعشرين”,“QR” 写作“كيو آر”)。subtitles 是观众阅读的内容(数字“٢٤”,“QR”,品牌用拉丁字母)。headlines 是场景 1-9 的 2-5 字动态标题;用 *…* 包裹要强调的单词。
不要编造统计数据、百分比、价格、奖项或推荐信——观众和客户无法验证,而且会带来法律风险。陈述明了的好处就足以推销。
带有 V/P/G 的品牌名称:阿拉伯语没有 V,因此“نوفيكس”被读作“NOFIX”。在 voice 中用 ڤ 写作“نوڤيكس”或用拉丁字母写作“NOVIX”,然后在步骤 4 中用 check-v.cjs 验证。
3. 截图(真实产品,手机尺寸)
使用 puppeteer 设置 390×844, deviceScaleFactor 3(→ 1170×2532)并保存到 build/img/。模板期望的文件名为:phone-home.png, phone-sweets.png, phone-restaurant.png, phone-options.png, phone-cart.png, tracking.png, dashboard-cancel.jpg, dashboard-stats.jpg, dashboard-products.jpg——根据产品重命名/替换(参见 references/template.md)。
- 品牌重塑 / 通用演示:使用
evaluateOnNewDocument+MutationObserver注入脚本,重写旧品牌名称、替换 Logosrc、隐藏电话号码并替换品牌图片,然后检查innerText以查找残留内容。 - 已登录页面(仪表板):使用用户已登录的应用内浏览器窗格(切勿输入其密码),模拟 375×812 视口,使用
javascript_tool应用相同的 DOM 替换,并在那里截图(它会保存一个文件,你可以复制)。该窗格可能在任务进行中重置大小——在每次截图前重新应用移动视口。 - 真实客户数据:在截图前模糊化屏幕上的姓名/电话。如果需要真实状态(新订单、取消请求),创建标记清晰的演示记录,截图,然后删除这些记录并确认已删除。
4. 旁白
免费的、自然的埃及语音来自 Gemini TTS (scripts/vo-gemini.cjs):
gemini-3.8-flash-tts拥有 92 种原生埃及语音 (ar-eg-*,例如ar-eg-concierge-1年轻/明亮,ar-eg-commercial-11广告语音,ar-eg-storyteller-3随意)。免费层:该模型每天仅 10 次请求。gemini-3.1-flash-tts-preview有单独免费配额,但只有通用语音(Puck乐观男声——用户的选择,Orus坚定男声,……)通过风格文本引导至埃及风格。- 命令(从
VIDEO/build运行):node vo-gemini.cjs voices→ 列出ar-EG语音。node vo-gemini.cjs sample <voice> [voice…]→ 每个语音的钩子行保存到vo/samples/(每次请求一个)。转换为 mp3 并发送给用户,让他们通过听觉选择——你无法听到。node vo-gemini.cjs all <voice>→ 一次请求 整个脚本,在停顿处分割成 10 个片段(节省配额,听起来像一次连续录制)。旧片段会被备份。node vo-gemini.cjs line <voice> <n>→ 重新录制单行。- 使用
GEMINI_TTS_MODEL=gemini-3.1-flash-tts-preview切换模型。
- 谨慎使用样本(5 个语音 = 5 次请求)。如果 3.8 的配额用尽,提供选项:等待重置(大约太平洋时间午夜),或使用 3.1 在今天录制。不要建议创建额外的 Google 帐户来获取更多配额——Google 的 API 条款禁止规避限制,这可能导致两个帐户被暂停。
- 备用方案:
vo-edge.cjs(Microsoftar-EG-ShakirNeural,无限制,无需密钥——用户认为机械感强/非埃及风格),或用户用自己的手机录制台词,然后你修剪/标准化为vo/sNN.wav。ElevenLabs 非常好但需要付费。
验证每段录音——你无法听到:
node transcribe.cjs [s05 s06…]使用 Gemini 文本模型转录每个片段。每段转录必须与其脚本行匹配。如果下一行的词出现在片段末尾,则剪切过晚:使用ffmpeg -af silencedetect=noise=-38dB:d=0.1查找停顿,并将尾部移动到下一个片段(参见 gotchas 中的-ss陷阱)。从vo/take/的原始文件修复。node check-v.cjs s10询问品牌辅音是 /v/ 还是 /f/(每个片段两次)。包含已知有问题的录音作为对照,以确保检查有效。
5. 主题化模板
模板还需要 img/qr.png(使用 node -e "require('qrcode').toFile('img/qr.png','<site url or brand>',{errorCorrectionLevel:'H',margin:1,width:680})" 生成——观众可以扫描它,因此指向真实地址或纯文本),img/rest-logo.svg(演示业务的 Logo)和品牌图标(示例中为 img/novix-icon.svg)。
assets/template/promo.html 是 NOVIX 风格(深蓝色 #0B1020,蓝色→紫色渐变)。通过编辑 :root 变量、舞台背景和发光颜色、.hl 渐变、芯片/环/字幕胶囊、二维码卡片以及最终场景(Logo、文字商标、标语、行动号召、功能列表)来重新主题化。references/template.md 列出了每个部分的位置以及场景的连接方式。
6. 检查、预览、渲染
从 VIDEO/build:
node build.cjs --check—— 运行约 2000 帧但不使用截图;在数秒内捕获 JS 错误,而不是等待 5 分钟的渲染后。node build.cjs --preview 3→out/sheet.jpg。查看它(读取图像):标题换行、内容超出画布、对比度问题(例如橙色卡片上的橙色文字)、残留的旧品牌信息。node build.cjs(在后台运行,约 5 分钟生成 66 秒视频)。它会报告视频与音频时长(必须匹配)以及响度(≈ −14 LUFS)。- 使用 SendUserFile 发送 WhatsApp 副本(完整文件通常 > 30 MB,仅在桌面端显示),告知用户两个文件的位置,并明确说明你已通过转录/帧检查但无法聆听。
7. 音乐
synth.cjs 创作一首原创的 98 BPM 中东陷阱节拍(darbuka、808、D Hijaz 调式的弹拨乌德琴风格主旋律),在揭晓场景处有节拍落下,并包含忙音/嗖嗖/叮/哔/泡泡音效。有许可的库(例如 Epidemic Sound 连接器)可能只允许预览,不允许下载——预览未获得广告许可,因此不要使用。
交付
- 最终文件:
out/<name>-9x16.mp4(1080×1920, 30 fps, H.264, AAC, −14 LUFS) 和out/<name>-9x16-whatsapp.mp4。 - 提及任何占位符(例如结束卡片上缺少的电话号码等),并提供明显的下一步操作(添加联系信息、横向版本、嵌入到其网站)。
- 如果截图必须公开托管(仅云视频工具需要),告知用户位置并提供删除选项。
在运行任何内容之前阅读 references/gotchas.md——它列出了构建此内容时遇到的所有失败及其修复方法。