mkt-hyperframe-talking-head-video-16-9
专用的 16:9 (1920×1080) 横屏编辑器 —— 输入是一个工作区文件夹,包含 voiceover.mp3 + source.mp4 + script.txt,输出是同一个文件夹,被完整搭建为 HyperFrames 预览项目,可直接运行 npx hyperframes preview。
这是编排器 mkt-full-video-with-11-hyperframe-heygen-16-9 下的一个操作层。编排器处理阶段 1(TTS)+ 阶段 2(HeyGen 头像)→ 将文件夹移交给该技能以处理阶段 3(转录 + 搭建 + 代码检查 + 预览)。
该技能产生的内容
<workspace_folder>/
├── voiceover.mp3 # 输入(未修改)
├── source.mp4 # 输入(HeyGen 头像唇同步,未修改)
├── script.txt # 输入(未修改)
├── transcript.json # 生成——Whisper 逐词输出
├── transcript-cleaned.json # 生成——越南语拼写纠正
├── scenes-outline.json # 生成——检查点前的场景大纲(5 个场景)
├── scenes.json # 生成——每个场景的最终元数据
├── index.html # 生成——根合成 1920×1080
├── compositions/
│ ├── scene-1.html # 每个场景一个文件,无论 N 是多少
│ ├── scene-2.html # 由并行 LLM 子代理创作(阶段 3d)
│ ├── scene-3.html # 不是由 Python 模板生成的(已弃用)
│ ├── ...
│ └── scene-N.html
├── sfx/ # 来自技能资产的 6 个音效符号链接/复制
│ ├── camera-flash.mp3
│ ├── Whoosh sound effect (1).mp3
│ ├── búng tay.mp3
│ ├── Laser.mp3
│ ├── ting.mp3
│ └── Discord Notification - Sound Effect.mp3
└── (可选) infographics/
├── 1.png 2.png 3.png # 如果使用 --with-infographics
└── prompts.md # 每个场景的奶油纸编辑风格提示
画布:
- 根元素:
data-width="1920" data-height="1080"。 - 头像框默认 SPLIT:
top:100, left:1290, width:540, height:880, borderRadius:32。 - 头像框 PIP 角标:
top:600, left:1540, width:320, height:420, borderRadius:20。 - 幻灯片挂载点:
1200×1080SPLIT,可动画化为1920×1080(PIP 期间)。 - 每个合成的固有尺寸:
data-width="1200" data-height="1080"(填充挂载点 100%,挂载点变宽时扩展)。
需要的输入(工作区文件夹约定)
| 文件 | 必需 | 说明 |
|---|---|---|
voiceover.mp3 | 是 | ElevenLabs TTS 输出(Hoàng 的声音)。 |
source.mp4 | 是 | HeyGen 头像唇同步。当前为 9:16 竖屏——横屏框使用 object-fit: cover; object-position: center 25% 进行合理裁剪。参见 references/source-mp4-cropping.md。 |
script.txt | 是 | 产生 voiceover.mp3 的越南语脚本。用于拼写纠正和场景标题推导。 |
scenes-outline.json | 否 | 如果用户预定义了 5 个场景,则跳过自动检测。模式:参见步骤 3。 |
Slug = 工作区文件夹的基本名称(无需推导)。所有脚本在该文件夹内读写。脚本接受 --workspace <path> 参数,默认使用当前工作目录。
管道(顺序脚本调用)
voiceover.mp3 + source.mp4 + script.txt
│
▼
1. transcribe_audio.py ── Whisper 越南语 → transcript.json(逐词)
│
▼
2. clean_transcript.py ── 去除 Whisper 伪影,应用越南语词典
│
▼
3. detect_scenes.py ── 转录 + script.txt → scenes-outline.json(5 个场景)
│
▼
4. [可选 CHECKPOINT] ── 用户审查大纲 / 编辑开场白、标题
│
▼
5. scaffold_project.py ── 写入 scenes.json(完整模式),创建 sfx/ + logos/ + avatar.jpg + yt-lower-third.html
│
▼
6. 🔥 LLM 子代理扇出 🔥 ── 编排器在一次消息中生成 N 个并行的通用
代理(每个场景一个),每个代理从
visual-plan.json + references/composition-patterns.md
创作 compositions/scene-{num}.html。
不是 generate_compositions.py(Jinja2 生成器
已弃用——会坍缩为 5 个原型,无法适应
场景特定的隐喻,破坏列表类 6+ 场景)。
│
▼
7. generate_root_index.py ── 写入 index.html,包含幻灯片挂载点(挂载 scene-{num}.html
用于所有场景,无 kind→fs-lesson 映射)+
头像框(claude-orange #d97757 品牌边框)+
GSAP 时间线(SPLIT↔PIP、呼吸、punch-in、
PIP_EVENTS、混合钩子缩放)+ 6 个音效连接 +
根层的奶油纸 b-roll 图片层(全 1920×1080)
│
▼
8. [可选] scaffold_infographic_slots.py
── 添加 <img onerror> 占位符 + 写入 prompts.md
(每个场景隐喻的奶油纸编辑风格)
│
▼
9. lint_and_preview.py ── npx hyperframes lint → 0 错误,然后预览
│
▼
交接——打印 Studio URL;用户审查;编排器决定渲染。
预览优先规则(不可协商): 技能在步骤 9 结束,输出 Studio URL。只有在用户明确确认后才会运行 MP4 渲染——该步骤属于编排器或用户手动操作。
步骤 1: transcribe_audio.py
python3 scripts/transcribe_audio.py --workspace <folder>
如果本地可用,则包装现有技能 mkt-ai-video-extract-srt-segment;否则直接回退到 whisper CLI:
whisper voiceover.mp3 --model medium --language vi --word_timestamps True \
--output_format json --output_dir .
绝不对越南语音频使用 --model medium.en——.en 会翻译而不是转录。始终使用 --language vi。
输出:transcript.json —— {text, start, end} 逐词条目的数组。
步骤 2: clean_transcript.py
重用来自兄弟 9:16 编辑器(mkt-hyperframe-talking-head-video/scripts/clean_transcript.py)的逻辑。去除 U+FFFD,应用越南语逐词和短语级别词典(alphabit→Alphabet, Cod→Code 等),分组为 3-5 个单词的短语。输出:transcript-cleaned.json。(无 caption-groups.json——16:9 中关闭字幕。)
步骤 3: detect_scenes.py
读取 transcript-cleaned.json + script.txt → 使用标准知识视频骨架推断 5 个场景边界:
| # | 种类 | 默认开场白提示 | 变体 |
|---|---|---|---|
| 1 | 钩子 | 脚本的第一句 | tier-row(通过 kind=hook 实现后叠层感觉) |
| 2 | 问题 | 脚本过渡到“ChatGPT/AI cũ”、“khó”、“đứt mạch”、“vấn đề”…的地方 | chats-stack |
| 3 | 解决方案 | 脚本介绍工具/方法的地方 | hero-orb |
| 4 | 回顾 | 脚本显示数字结果的地方(“X tiếng”、“Y khách hàng”) | counter-row |
| 5 | 行动号召 | 带有评论/保存/关注触发的最后一句 | terminal-row |
如果脚本没有明确的 5 个部分,则输出更少(最少 3 个)并警告用户。启发式方法:按句子边界将转录分割为约 5 个块,场景 3 权重为 1.5 倍(解决方案通常最长)。
输出 scenes-outline.json:
[
{ "num": 1, "kind": "hook", "start": 0.07, "end": 13.73, "kicker": "...", "heading": "...", "variant": "tier-row" },
{ "num": 2, "kind": "problem", "start": 13.73, "end": 27.37, "kicker": "...", "heading": "...", "variant": "chats-stack" },
{ "num": 3, "kind": "solution", "start": 27.37, "end": 47.75, "kicker": "...", "heading": "...", "variant": "hero-orb" },
{ "num": 4, "kind": "recap", "start": 47.75, "end": 53.80, "kicker": "...", "heading": "...", "variant": "counter-row" },
{ "num": 5, "kind": "cta", "start": 53.80, "end": 60.68, "kicker": "...", "heading": "...", "variant": "terminal-row" }
]
CHECKPOINT —— 打印大纲供用户审查。用户可以内联编辑开场白/标题/变体,然后继续。如果技能以 --auto(编排器模式)调用,则跳过检查点。
步骤 4: scaffold_project.py
读取 scenes-outline.json → 为每个场景丰富:
accent_words—— 从标题派生(提取数字 + 最后 2-3 个名词)content—— 特定于模式的模式(参见assets/templates/)badges—— 每个场景 1-3 个浮动徽章brollEnd,hasBreath—— 用于 SPLIT↔PIP 调度pip_events—— 从场景内accent_words时间派生
写入 scenes.json。还会将技能包中的这些自包含资产自动复制到工作区:
| 资产 | 来源 | 目标 | 用途 |
|---|---|---|---|
| 6 个音效文件 | assets/sfx/ | <workspace>/sfx/ | 节拍声音(相机闪光、嗖、弹指、激光、叮、Discord 通知) |
| 品牌徽标 | assets/logos/{chatgpt,gemini,claude,claude-code}.{png,jpg} | <workspace>/assets/logos/ | 自动附加到合成(聊天堆头像、英雄光球、层级行工具徽章) |
| 头像 | assets/avatar.jpg | <workspace>/assets/avatar.jpg | yt 下三分之一订阅横幅的频道缩略图 |
| YT 下三分之一 | assets/compositions/yt-lower-third.html | <workspace>/compositions/yt-lower-third.html | 订阅横幅挂载点,视频最后 3 秒 |
如果技能包中缺少源资产,则会静默回退到旧版工作区路径(workspace/assets/...)。如果两者都找不到,则跳过该资产(合成优雅降级——文本头像代替徽标,无下三分之一)。
步骤 5: 🔥 LLM 子代理扇出(合成创作)🔥
generate_compositions.py 已弃用。 请勿调用它。Python Jinja2 生成器将每个场景坍缩为 5 个固定原型之一(钩子→tier-row,问题→chats-stack,解决方案→hero-orb,回顾→counter-row,行动号召→terminal-row),无法适应场景特定的隐喻(例如“scroll-tape-wasted”、“two-clock-comparison”、“right-tool-vehicles”),并且会破坏列表类 6+ 场景(多个 tip-N 坍缩为相同文件名→覆盖)。
规范方法: 编排器(或用户)在一条消息中生成 N 个并行的 general-purpose 代理(每个场景一个),以便它们并发运行。每个子代理:
- 从
visual-plan.json(路径:<workspace>/visual-plan.json,场景索引num-1)读取其场景块 - 从编排器技能读取参考:
references/composition-patterns.md(8 个生产交付的模式)、references/slide-design-tokens.md(调色板 + 排版) - 为其场景的隐喻选择正确的模式——自由调整(hero-orb 可以变成 vault+spokes,stats-3card 可以变成 two-clock-comparison)
- 从头开始创作
compositions/scene-{num}.html,包含:1200×1080 视口、通过[data-composition-id="scene-{num}"]限定的 CSS、注册到window.__timelines["scene-{num}"]的 GSAP 时间线、无!important、无嵌入式image-slot(奶油纸图像仅位于根层)
结果是:每个场景都会获得一个独特的、符合隐喻的合成文件。无冲突,无无聊的 5 原型锁定。
有关完整的子代理提示模板,请参见编排器的 mkt-full-video-with-11-hyperframe-heygen-16-9/SKILL.md 步骤 4d。
合成中的品牌徽标(子代理引用这些)
子代理在其模式需要时嵌入品牌徽标。徽标位于 <workspace>/assets/logos/:
| 模式用法 | 品牌元素 |
|---|---|
| 钩子 tier-row“之后” | tool-badge 药丸(右上角)——Claude 徽标 + 名称。 |
| 问题 chats-stack 失败行 | 当 name 匹配关键字(chatgpt/gpt → chatgpt.png;gemini/google → gemini.jpg)时,自动附加 ChatGPT/Gemini 徽标。 |
| 解决方案 hero-orb / vault | 光球辉光内的品牌徽标(默认为 Claude)。 |
| 行动号召 terminal-row | 默认无徽标。 |
如果 assets/logos/ 不存在,子代理会回退到文本头像(无闪烁)。
模式参考(8 个原型,子代理选择 + 调整)
编排器的 references/composition-patterns.md 提供了 8 个经过生产测试的模式:
| 模式 | 最适合 | 内部主题 |
|---|---|---|
tier-row before-after | 钩子对比 | 2 个层级行(之前玫瑰红/红 + 之后酸橙绿/绿),包含字母 + 项目 |
chats-stack | 问题 / 失败 / 编辑-重新生成演示 | 用户行 + 2-3 个 AI 失败行 + 断链印章 |
hero-orb + spec-trio | 解决方案 / 机制 / 中央保险库 | 发光球体 + 任务图标 + 3 个规格层级行 |
counter-row | 回顾 / 数字证明 | 大计数器(从 → 到)+ 客户 + 增量标签 |
comment-terminal | 行动号召 / “评论 X” | 层级字母 + macOS 终端模拟 + 2 个礼品卡 |
stats-3card | 知识介绍 / 3 个事实揭示 | 3 列落地风格,带 // LBL + 渐变数字 |
comparison-2col | “何时使用哪个” | 2 列是/是芯片 |
image-slot | (已弃用——图像位于根层) | — |
子代理自由调整:例如,hero-orb → “vault + 5 chat spokes”,stats-3card → “two-clock-comparison”,comparison-2col → “3-tier vehicle cards”。模式文档提供骨架(HTML + CSS + GSAP),LLM 进行创意定制。
步骤 6: generate_root_index.py
读取 scenes.json + 来自转录的 total_duration → 渲染 assets/templates/index.html.j2:
- 1920×1080 根元素,包含
#slide-bg、#heygen-bg、#avatar-frame > .avatar-breathing > .avatar-punch > #v-source <audio id="a-source">跟踪原始 source.mp4 音频(轨道 1)- 6 个
<audio>音效,使用绝对data-start连接(场景边界) - 左上角品牌标记
- GSAP 块:
- 初始入场(头像淡入、品牌淡入)
- SPLIT/PIP 常量 +
goPIP(t)/goSplit(t)辅助函数 - 由来自 scenes.json 的每个场景
pip_events驱动的PIP_EVENTS数组 .avatar-breathing上的 "混合钩子"视觉缩放策略:- HOOK 场景:在整个场景持续时间内缓慢从 1.0 缩放到 1.10(戏剧性构建,
power2.in) - HOOK→BODY 过渡:从 1.10 快速重置到 1.0(释放张力,0.5s
power3.in) - BODY 场景(2..N-1)在 PIP-IN 事件时:1.06 节拍冲击(节奏,
power2.out→power3.out) - CTA 场景:温和地从 1.0 缩放到 1.04(收尾,
sine.inOut)
- HOOK 场景:在整个场景持续时间内缓慢从 1.0 缩放到 1.10(戏剧性构建,
- 每个场景开始时的
.avatar-punch小冲击(1.06)用于转场
…
[截断以进行翻译]