video-narrado 是做什么的?
输入: 一个 .md 文件。 输出,按以下顺序:
- 详细视频 16:9(2 到 4 分钟),完整覆盖整个 MD 内容。
- 短视频版本 9:16(2 或 3 个,每段少于 60 秒):每个版本选取详细视频中的一个发现点。
- 每个片段一个
publicacion.md文件(标题、描述、话题标签和替代文本)。
全部采用选定的语音、字幕和自有背景音乐。
- 引擎:
motor/,位于此技能内部(Playwright 1.63.0 + ffmpeg;Python 3 无额外依赖)。MOTOR为该文件夹的绝对路径。 - 项目:每个视频一个文件夹,例如
videos/AAAA-MM-DD_tema/,每个片段一个子文件夹:largo/、short-1-…/、short-2-…/。每个片段包含其storyboard.json。 - 安装(一次性):参见
README.md。
选定语音
默认使用 HeyGen 的克隆语音“audio_pmm”:
create_speech 字段 | 值 |
|---|---|
voiceId | b088805628184836963fa5d2881bb23b |
engine | elevenlabs |
settings | {"model_id": "eleven_v4"} |
language | es |
如果要求视频的人想要其他语音,请先用 mcp__heygen__list_voices 搜索并确认后再生成。
流程
1. 读取 MD 并提议片段
读取完整 MD 文件。定义详细视频的路线(所有发现点,按顺序)以及每个短视频版本的一个发现点(最强的先展示)。在编写故事板之前先显示片段列表。
2. 故事板 → 审批
每个想法一个场景。详细视频包含 8 到 16 个场景;一个短视频版本包含 4 到 7 个场景,第一个场景带有钩子(destacado)。完整示例:motor/ejemplos/storyboard-desalacion-16x9.json。
{"id": "03-sesiones", "tipo": "barras", "kicker": "各案例会话数", "titulo": "讨论最多的地点",
"items": [{"etiqueta": "Caleta Chañaral", "valor": 6}], "destacar": 0, "nota": "来源…",
"subtitulo": "Chañaral de Aceituno 是会话最多的案例。",
"voz": "Chañaral de Aceituno 是会话最多的案例。"}
故事板头部:titulo、serie(显示在“Rizoma ·”旁边的内容)、formato(详细视频用 "16:9",短视频版本用 "9:16")、fuente_md,以及可选的 musica(参见步骤 5)。
场景类型(所有类型均支持 kicker、tono: "oscuro" 和 lluvia: true):
| 类型 | 字段 | 用途 |
|---|---|---|
portada | titulo、bajada | 打开详细视频 |
cifras | titulo、items[{valor, prefijo?, sufijo?, texto, detalle?}](1 到 3 个)、destacar | 数字向上计数 |
barras | titulo、items[{etiqueta, valor, rotulo?}](最多 8 个)、destacar、nota | 比较数量 |
hito | fecha、etiqueta、titulo、texto、progreso{i, n} | 时间线中的事件 |
lista | titulo、items[{marca?, texto, alerta?}](最多 6 个) | 论点或步骤 |
cita | fecha、texto、quien、nota | 某人所说的话 |
destacado | texto、bajada | 需要记住的句子;短视频的钩子 |
cierre | bajada、url、fuente | 标志和来源 |
编辑规则:
- 仅使用 MD 中的事实。MD 标记为可疑的内容要么排除,要么如实说明。
voz是朗读内容:数字、年份、百分比和缩写必须用文字表述(texto_voz.py会拒绝数字)。subtitulo是显示内容,可包含数字。texto是hito、cita和destacado场景的屏幕文本。- 短句,中性智利西班牙语,约 2.9 词/秒。一个短视频版本不超过约 140 个口语词。
- 从自动转录中获取的内容需标记为转述(
nota)。 - 发布内容不得提及客户或内部平台。结尾必须包含来源。
以表格形式展示每个故事板(场景 · 类型 · 显示内容 · 叙述内容),并等待批准:每次叙述会消耗语音配额。
3. 语音(每个片段一次调用)
python3 $MOTOR/texto_voz.py <pieza>
将输出文本(每个场景的语音以 <break time="1.2s"/> 连接)传递给 mcp__heygen__create_speech,使用选定的语音。使用返回的 audio_url:
python3 $MOTOR/bajar_voz.py <pieza> "<audio_url>"
下载音频并通过查找停顿将其按场景切割。如果报告缺少停顿,可以在已下载的音频上使用更低的阈值重新运行:python3 $MOTOR/bajar_voz.py <pieza> <pieza>/voz/narracion.wav --pausa 0.7(实际上 ElevenLabs 可能会略微缩短某些停顿)。如果仍然失败,说明语音未遵循 <break>:请在重新生成之前询问。在出错后切勿单独重试生成。
4. 构建和渲染
bash $MOTOR/producir.sh <pieza> # 完整视频
bash $MOTOR/producir.sh <pieza> --hasta 15 --salida prueba.mp4 # 短测试
每个场景的时长等于其语音时长。MP4 文件生成在 <pieza>/salida/video.mp4;耗时大约等于视频时长。
5. 背景音乐
自动:使用 ffmpeg 合成的环境背景音(无第三方版权),低于语音 14 dB,带有柔和的闪避效果,最终混音至 -16 LUFS。在故事板中:"musica": {"bajo_voz_db": 18} 可降低音量;{"archivo": "pista.mp3"} 使用自有音轨(仅限免费使用,并注明许可证);false 关闭背景音乐。
6. 短视频版本
在批准详细视频后,将每个短视频版本作为独立片段构建(formato: "9:16"),复用详细视频的场景:钩子 → 2 到 4 个数据场景 → 结尾。与步骤 3(每个片段一次语音调用)和步骤 4 相同。
7. 审核与交付
- 使用 ffmpeg 截取 4 到 8 帧并检查:确保字幕不遮挡数据、没有文本超出画面、没有场景显示为空白。
- 为每个片段编写
publicacion.md:标题(≤ 60 字符)、包含来源的描述、3 到 5 个话题标签、替代文本以及发布前需要验证的内容。 - 将 MP4 文件复制到
~/Downloads,并采用清晰的文件名(Video_<主题>.mp4、Short_<编号>_<主题>.mp4)。音频和 MP4 文件不纳入 git 管理(**/voz/*.wav、**/salida/)。
使用已有的动画 HTML
如果已存在包含 window.seek(t) 和固定时间场景的 HTML,可以手动编写 guion.json 文件(每个片段用 html: [a, b] 表示),然后运行 preparar.py + render.mjs。对于手动制作的短视频版本:motor/plantillas/motor-vertical.js。
格式与安全区域
- 16:9:1920×1080,字幕 34 px 位于底部,每行不超过 58 个字符。
- 9:16:1080×1920,字幕 54 px,距底部边缘 400 px,每行不超过 34 个字符;内容位于 y=400 和 y=1380 之间(上下各平台按钮区域)。
- 任何字幕不得以“que”、“las”、“por”等词结尾。
已知错误
- 无网络连接:Google 字体无法加载,渲染会回退为 Arial。
- ffmpeg 缺少 libass(Homebrew 版本):因此字幕在页面内绘制。
- 未知场景类型:视频输出为空白;请检查
tipo字段。