OpenMontage Avatar-Video 技能实战:HeyGen 视频自动字幕(captions)从启用、样式配置到 SRT 与本地字幕后处理
本文以 OpenMontage 仓库 avatar-video 技能中的字幕参考文档为主线,讲解 HeyGen /v2/video/generate 接口的 caption 字段如何启用自动字幕、CaptionConfig 样式对象如何控制字体/颜色/位置、SRT 字幕文件与视频翻译的协作方式,并结合仓库中的 subtitle_gen 工具与 Remotion 字幕组件源码,补全“云端生成字幕 + 本地后处理字幕”的完整工程链路。读完本文,你可以直接在 Avatar 视频请求中挂载符合可访问性与社媒规范的字幕,并知道在 HeyGen 字幕能力受限时的本地替代方案。
一、字幕能力在 avatar-video 技能中的位置
OpenMontage 将 HeyGen Avatar 视频能力沉淀为一组 Agent 技能文件,其中 .agents/skills/avatar-video/references/captions.md 是专门讲字幕的参考文档,它属于 avatar-video 技能 的 “Video Customization” 参考文件之一(另外两个是 backgrounds.md 与 text-overlays.md)。技能主文档的默认工作流为:
GET /v2/avatars列数字人,选定avatar_id;GET /v2/voices(如需)挑选音色;- 撰写脚本;
POST /v2/video/generate生成视频(字幕即在此步骤通过caption字段启用);GET /v2/videos/{video_id}轮询直到completed。
调用前提是所有请求都要携带 X-Api-Key: $HEYGEN_API_KEY 请求头(环境变量 HEYGEN_API_KEY)。技能文档同时建议:若 HeyGen MCP 工具(mcp__heygen__*)可用则优先使用,它们会自动处理鉴权与请求格式;视频生成本身(POST /v2/video/generate)与数字人/音色列表仍走直接 API 调用。
此外需要注意技能演进:旧的 heygen 技能 已被标记为 DEPRECATED,其职责拆分为 create-video(提示词生成)与 avatar-video(精确控制)两个聚焦技能;.agents/skills/heygen/references/captions.md 与本文所讲的 avatar-video 版本内容基本一致,新场景应以 avatar-video 下的参考文档为准。
二、启用自动字幕(caption: true)
字幕在生成视频时即可启用。video-generation.md 的请求字段表中,顶层字段 caption 被定义为布尔类型、非必填、含义为 “Enable auto-captions”,因此最小用法就是把 caption 设为 true:
const videoConfig = {
video_inputs: [
{
character: {
type: "avatar",
avatar_id: "josh_lite3_20230714",
avatar_style: "normal",
},
voice: {
type: "text",
input_text: "Hello! This video will have automatic captions.",
voice_id: "1bd001e7e50f421d891986aad5158bc8",
},
},
],
// Caption settings (availability varies by plan)
caption: true,
};
对应到 curl 的完整请求(摘自 video-generation.md,此处叠加 caption 字段):
curl -X POST "https://api.heygen.com/v2/video/generate" \
-H "X-Api-Key: $HEYGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_inputs": [
{
"character": {
"type": "avatar",
"avatar_id": "josh_lite3_20230714",
"avatar_style": "normal"
},
"voice": {
"type": "text",
"input_text": "Hello! This video will have automatic captions.",
"voice_id": "1bd001e7e50f421d891986aad5158bc8"
}
}
],
"dimension": { "width": 1920, "height": 1080 },
"caption": true
}'
几个与字幕直接相关的前提条件(均来自技能参考文档):
video_inputs为必填数组(1–50 个场景对象),每个对象必含character与voice;test: true可用测试模式生成带水印视频且不消耗额度,适合在正式启用字幕前先验证配置;- 字幕功能的可用性 随订阅套餐(plan)不同而变化,参考文档原文即标注 “Caption settings (availability varies by plan)”。
三、CaptionConfig 配置结构
除了布尔开关,字幕还支持对象形式的样式配置。参考文档给出的完整接口定义如下:
interface CaptionConfig {
// Enable/disable captions
enabled: boolean;
// Caption style
style?: {
font_family?: string;
font_size?: number;
font_color?: string;
background_color?: string;
position?: "top" | "bottom";
};
// Language for caption generation
language?: string;
}
字段说明整理为表:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
enabled |
boolean | 是 | 开启/关闭字幕(对象形式下使用) |
style.font_family |
string | 否 | 字体族,如 "Arial"、"Roboto" |
style.font_size |
number | 否 | 字号,参考值 28–42 |
style.font_color |
string | 否 | 字体颜色,CSS 色值 |
style.background_color |
string | 否 | 字幕背景色,支持 rgba() 半透明 |
style.position |
"top" | "bottom" |
否 | 字幕位置,默认 bottom |
language |
string | 否 | 字幕生成语言(见多语言一节) |
需要注意一个细微差别:顶层 caption 字段在 video-generation.md 的字段表与 VideoGenerateRequest 接口中声明为 caption?: boolean;而 captions.md 中演示了传入 CaptionConfig 对象({ enabled, style })的写法。从两套文档结构看,可以理解为布尔值是 API 请求的基线形态,对象形式承载样式扩展;实际支持程度以订阅套餐与 HeyGen 当时版本的接口能力为准(参考文档 “Limitations” 一节也说明部分高级字幕功能可能仅 Web 端可用)。
四、两种启用姿势:默认样式与自定义样式
默认样式(Basic Captions)——只开开关,用 HeyGen 默认排版:
const config = {
video_inputs: [...],
caption: true, // Enable with default styling
};
自定义样式(Styled Captions)——传入样式对象,白字 + 70% 不透明度黑底、底部居中,这是可访问性实践中最稳妥的组合:
const config = {
video_inputs: [...],
caption: {
enabled: true,
style: {
font_family: "Arial",
font_size: 32,
font_color: "#FFFFFF",
background_color: "rgba(0, 0, 0, 0.7)",
position: "bottom",
},
},
};
五、多语言字幕
字幕语言跟随语音(voice)语言生成:只要脚本 input_text 与所选 voice_id 是某种语言,自动字幕就会以该语言输出。参考文档给出西班牙语示例:
// Spanish video with Spanish captions
const spanishConfig = {
video_inputs: [
{
character: {
type: "avatar",
avatar_id: "josh_lite3_20230714",
avatar_style: "normal",
},
voice: {
type: "text",
input_text: "¡Hola! Este video tendrá subtítulos en español.",
voice_id: "spanish_voice_id",
},
},
],
caption: true,
};
实操提示:voice_id 必须与目标语言匹配(技能工作流第 2 步 GET /v2/voices 可按 locale 筛选),否则会出现“西语脚本 + 英语音色”这类语言不一致问题;CaptionConfig.language 字段则用于显式指定字幕生成语言,适合脚本语言与期望字幕语言不完全一致的场景。
六、与 SRT 字幕文件协作
6.1 标准 SRT 格式
字幕与 HeyGen 生态的通用交换格式是 SRT。标准结构为“序号 + 时间轴(HH:MM:SS,mmm --> HH:MM:SS,mmm)+ 文本”的重复块:
1
00:00:00,000 --> 00:00:03,000
Hello! This video will have
2
00:00:03,000 --> 00:00:06,000
automatic captions generated.
3
00:00:06,000 --> 00:00:09,000
They sync with the audio.
6.2 视频翻译场景下提供自定义 SRT
视频翻译(video translation)流程中,可以携带自备的 SRT 文件,并通过 srt_role 声明它扮演“输入字幕”还是“输出字幕”:
const translationConfig = {
input_video_id: "original_video_id",
output_languages: ["es-ES", "fr-FR"],
srt_key: "path/to/custom.srt", // Custom SRT file
srt_role: "input", // "input" or "output"
};
srt_role: "input"——以提供的 SRT 作为翻译源文本(例如原文是手写稿,希望字幕严格按稿翻译);srt_role: "output"——将翻译结果落为 SRT 供后续复用;srt_key指向已上传的 SRT 文件键(上传机制见同目录 assets.md 描述的素材上传流程)。
七、字幕位置:bottom 与 top
底部(默认)——绝大多数横屏/竖屏视频的标准位置:
caption: {
enabled: true,
style: {
position: "bottom"
}
}
顶部——当画面底部被 Logo、UI 或画中画占据时使用:
caption: {
enabled: true,
style: {
position: "top"
}
}
八、可访问性最佳实践
参考文档给出的 5 条实践,逐条对应了上面可配置的字段:
- 始终开启字幕——服务听障/重听观众,同时覆盖静音播放场景;
- 高对比配色——白字深底或反之(对应
font_color与background_color,示例中rgba(0,0,0,0.7)黑底是常见选择); - 可读字号——标准视频至少 24px,移动端更大(预设表中 28–42 的区间即按此思路取值);
- 不要遮挡关键内容——把字幕移开画面主体(
position的主要用途); - 时间轴对齐——字幕时序必须与音频严格同步,这也是自动字幕相对手写 SRT 的核心价值。
九、字幕预设(Presets)与辅助函数
参考文档提供了一套可直接复用的预设常量与工厂函数,适合作为团队级“字幕风格库”:
interface CaptionStyle {
font_family: string;
font_size: number;
font_color: string;
background_color: string;
position: "top" | "bottom";
}
const captionPresets: Record<string, CaptionStyle> = {
default: {
font_family: "Arial",
font_size: 32,
font_color: "#FFFFFF",
background_color: "rgba(0, 0, 0, 0.7)",
position: "bottom",
},
minimal: {
font_family: "Arial",
font_size: 28,
font_color: "#FFFFFF",
background_color: "transparent",
position: "bottom",
},
bold: {
font_family: "Arial",
font_size: 36,
font_color: "#FFFFFF",
background_color: "rgba(0, 0, 0, 0.9)",
position: "bottom",
},
branded: {
font_family: "Roboto",
font_size: 30,
font_color: "#00D1FF",
background_color: "rgba(26, 26, 46, 0.9)",
position: "bottom",
},
};
function createCaptionConfig(preset: keyof typeof captionPresets) {
return {
enabled: true,
style: captionPresets[preset],
};
}
四个预设的取舍:
| 预设 | 字号 | 背景 | 适用场景 |
|---|---|---|---|
default |
32 | 黑色 70% | 通用基线,稳妥高对比 |
minimal |
28 | 透明 | 画面干净、无复杂背景时 |
bold |
36 | 黑色 90% | 户外/嘈杂画面,强调可读性 |
branded |
30 | 深蓝 90% + 青色字 | 品牌片,统一视觉识别色 |
使用方式只需 const caption = createCaptionConfig("bold"),然后把结果赋给请求体的 caption 字段即可。
十、社媒平台差异化配置
TikTok / Instagram Reels
- 字幕放在中部或偏上区域;
- 避开底部约 20% 区域(会被平台 UI 元素遮挡);
- 移动端观看需要更大字号:
const socialCaptions = {
enabled: true,
style: {
font_size: 42,
position: "top", // Avoid bottom UI elements
},
};
YouTube
- 标准底部字幕即可;
- YouTube 本身支持上传封闭字幕(closed captions),SRT 可另作平台侧字幕源上传。
- 强烈建议加字幕(大量用户静音浏览信息流);
- 风格上偏向专业、克制的排版(如
default或branded预设)。
十一、能力限制(Limitations)
参考文档明确列出的四条限制,规划字幕方案时应纳入考量:
- 可用字幕样式受订阅层级限制;
- 部分高级字幕功能可能需要 Web 界面操作;
- 多说话人字幕检测的可用性有限;
- 字幕准确度取决于音频质量与发音清晰度。
十二、与视频翻译的集成
视频翻译流程会自动处理字幕生成——目标语言的字幕随翻译一并产出,不需要单独请求:
// Video translation includes caption generation
const translationConfig = {
input_video_id: "original_video_id",
output_languages: ["es-ES"],
// Captions generated in target language
};
翻译工作流的细节由仓库中的 video-translate 技能承载(见 .agents/skills/video-translate/SKILL.md),captions.md 的边界是“字幕如何产生”,翻译技能回答“翻译如何编排”。
十三、源码纵深:OpenMontage 的本地字幕后处理链路
以上都发生在 HeyGen 云端渲染之前。当云端字幕样式受套餐限制,或需要“词级高亮”这类更精细的表现时,OpenMontage 在仓库内提供了完整的本地替代/后处理链路,由两部分构成:
13.1 subtitle_gen:从词级时间戳到 SRT/VTT/JSON
tools/subtitle/subtitle_gen.py 实现 SubtitleGen 工具,将转写器(transcriber)输出的词级时间戳转换为 SRT、VTT 或字幕 JSON 三种格式,纯 Python 标准库实现、确定性执行(determinism = DETERMINISTIC)。其 input_schema 定义的关键参数:
| 参数 | 类型/取值 | 默认值 | 说明 |
|---|---|---|---|
segments |
array(必填) | — | 转写器输出的含 words 与时间戳的段落 |
format |
srt / vtt / json |
srt |
输出格式 |
output_path |
string | — | 字幕文件落盘路径 |
max_chars_per_line |
integer | 42 | 每行最大字符数 |
max_words_per_cue |
integer | 8 | 每条字幕(cue)最大词数 |
highlight_style |
none / word_by_word / karaoke |
none |
高亮模式,word_by_word 即逐词高亮 |
corrections |
object | — | ASR 常见错词纠正表,如 {"cloud": "Claude"},生成字幕前统一替换 |
这套参数与 captions.md 中 SRT 的“序号 + 时间轴 + 文本”结构直接对接:本地生成的 SRT 即可按第六节的方式作为 srt_role: "input" 的自定义字幕回灌 HeyGen 翻译流程,或在 Remotion 合成中独立使用。
13.2 CaptionOverlay:Remotion 词级高亮字幕组件
remotion-composer/src/components/CaptionOverlay.tsx 是面向 TikTok 风格逐词高亮的字幕覆盖层组件。其核心数据模型与 props(摘自源码开头定义):
// Word-level caption for TikTok-style highlight display
export interface WordCaption {
word: string;
startMs: number;
endMs: number;
// Force a page break after this word (e.g. sentence or scene boundaries).
// Useful for CJK captions where pages should align with clause boundaries.
pageBreakAfter?: boolean;
}
type CaptionOverlayProps = {
words: WordCaption[];
wordsPerPage?: number; // 每“页”显示词数
fontSize?: number;
color?: string;
highlightColor?: string; // 当前词高亮色
backgroundColor?: string;
fontFamily?: string;
wordSeparator?: string; // 空格分隔语言用 " ";CJK 语言应传 ""
};
从源码结构看,该组件的三个设计点对应了 captions.md 各节的工程诉求:
- 分页算法
buildPages:按wordsPerPage或pageBreakAfter切分“页”,每页取首词startMs与末词endMs作为页时间轴——这实现了“不要遮挡关键内容、时序严格对齐”的可访问性要求; - CJK 适配:
wordSeparator注释明确“空格分隔语言用默认空格;无词间空格的 CJK 语言应传空串”,WordCaption的inline-block + white-space: nowrap渲染防止词中断行,pageBreakAfter让分页对齐中文分句边界; - 动效:每页入场使用 Remotion
spring(damping 18 / stiffness 120)配合interpolate做 20px 上浮淡入,当前词通过startMs/endMs与当前帧时间比较切换highlightColor——即 HeyGen 云端字幕套餐受限时,本地可以做出“逐词点亮”的社媒字幕效果。
两条链路的分工因此清晰:HeyGen caption 负责生成阶段“零成本、与口型/音频同源”的自动字幕;subtitle_gen + CaptionOverlay 负责后期阶段“样式完全可控”的字幕重排与高亮。前者配置见本文第二至十节,后者代码可直接在 remotion-composer 工程中复用。
十四、相关文件索引
| 文件 | 作用 |
|---|---|
| .agents/skills/avatar-video/references/captions.md | 本文主线:HeyGen 自动字幕参考文档 |
| .agents/skills/avatar-video/SKILL.md | avatar-video 技能总览、鉴权与默认工作流 |
| .agents/skills/avatar-video/references/video-generation.md | /v2/video/generate 完整请求字段(含顶层 caption 布尔字段) |
| .agents/skills/avatar-video/references/assets.md | 素材(图片/音频/SRT 等)上传机制 |
| .agents/skills/heygen/SKILL.md | 已弃用的旧 heygen 技能,仅作历史对照 |
| tools/subtitle/subtitle_gen.py | 本地字幕生成工具(SRT/VTT/JSON) |
| remotion-composer/src/components/CaptionOverlay.tsx | 词级高亮字幕覆盖层组件 |
| .agents/skills/video-translate/SKILL.md | 视频翻译技能(字幕翻译的编排层) |
十五、小结
- 启用:
POST /v2/video/generate顶层加caption: true即可获得自动字幕,无需二次处理;样式受限时改用{ enabled, style }对象显式声明字体、字号、颜色与top/bottom位置。 - 多语言:字幕跟随 voice 语言生成;翻译流程中可用
srt_key+srt_role注入自定义 SRT,翻译则自动产出目标语言字幕。 - 规范:高对比、≥24px、避开 UI 遮挡区(Reels 底部 20%)、时序对齐,四条可访问性原则可直接落到预设与社媒配置中。
- 边界:样式与高级功能受套餐限制、部分功能仅限 Web 端、多说话人支持有限、准确度依赖音源质量——超出的部分由仓库内
subtitle_gen+CaptionOverlay本地链路兜底,二者共用 SRT 这一通用交换格式。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00