@optima-chat/gen-cli 1.2.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.claude/skills/digital-human/SKILL.md +195 -0
  2. package/.claude/skills/digital-human/references/avatar-catalog.md +47 -0
  3. package/.claude/skills/digital-human/references/edit.md +198 -0
  4. package/.claude/skills/digital-human/references/generate.md +246 -0
  5. package/.claude/skills/digital-human/references/manage.md +126 -0
  6. package/.claude/skills/digital-human/references/train.md +291 -0
  7. package/.claude/skills/gen/SKILL.md +33 -26
  8. package/.claude/skills/video-edit/SKILL.md +99 -17
  9. package/.claude/skills/video-gen/SKILL.md +34 -108
  10. package/.claude/skills/video-translate/SKILL.md +254 -11
  11. package/dist/commands/asr.d.ts.map +1 -1
  12. package/dist/commands/asr.js +6 -3
  13. package/dist/commands/asr.js.map +1 -1
  14. package/dist/commands/avatar.d.ts +12 -2
  15. package/dist/commands/avatar.d.ts.map +1 -1
  16. package/dist/commands/avatar.js +27 -9
  17. package/dist/commands/avatar.js.map +1 -1
  18. package/dist/commands/doctor.d.ts +14 -4
  19. package/dist/commands/doctor.d.ts.map +1 -1
  20. package/dist/commands/doctor.js +59 -38
  21. package/dist/commands/doctor.js.map +1 -1
  22. package/dist/commands/image.d.ts.map +1 -1
  23. package/dist/commands/image.js +13 -6
  24. package/dist/commands/image.js.map +1 -1
  25. package/dist/commands/tryon.d.ts.map +1 -1
  26. package/dist/commands/tryon.js +6 -3
  27. package/dist/commands/tryon.js.map +1 -1
  28. package/dist/commands/tts.d.ts.map +1 -1
  29. package/dist/commands/tts.js +6 -3
  30. package/dist/commands/tts.js.map +1 -1
  31. package/dist/commands/video-translate.d.ts.map +1 -1
  32. package/dist/commands/video-translate.js +10 -6
  33. package/dist/commands/video-translate.js.map +1 -1
  34. package/dist/commands/video.d.ts +19 -0
  35. package/dist/commands/video.d.ts.map +1 -1
  36. package/dist/commands/video.js +292 -12
  37. package/dist/commands/video.js.map +1 -1
  38. package/dist/utils/output.d.ts +9 -2
  39. package/dist/utils/output.d.ts.map +1 -1
  40. package/dist/utils/output.js +9 -2
  41. package/dist/utils/output.js.map +1 -1
  42. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: video-translate
3
3
  description: "把单段口播视频翻译成 English / Thai (Thailand) / Malay (Malaysia) / Vietnamese (Vietnam) 之一,出片自带译音(自动克隆原说话人)+ 烧录目标语花体字幕 + 默认 BGM ducking。触发场景:用户说翻译这个视频/做泰语版/英文版/越南语版/马来语版/视频本地化/换语言/dub。"
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  owner_repo: Optima-Chat/optima-gen
6
6
  ---
7
7
 
@@ -21,7 +21,7 @@ owner_repo: Optima-Chat/optima-gen
21
21
  ## 前提
22
22
 
23
23
  - 源视频 URL 公网可访问(或先让用户上传到 Optima → 拿 URL)
24
- - 容器有:`gen` CLI(`@optima-chat/optima-gen` ≥ latest)、`video-translate` CLI(`@optima-chat/video-translate-tools` ≥ 1.0.2)、`ffmpeg`、`curl`、`jq`
24
+ - 容器有:`gen` CLI(`@optima-chat/optima-gen` ≥ latest)、`video-translate` CLI(`@optima-chat/video-translate-tools` ≥ 1.0.5)、`ffmpeg`、`curl`、`jq`
25
25
  - gen video-translate 的 `--mode fast` / `--dynamic-duration` flag 在 latest 版本已存在;若 CLI 报 unknown flag → `npm i -g @optima-chat/optima-gen@latest` 升级
26
26
 
27
27
  ## 输入
@@ -33,13 +33,33 @@ owner_repo: Optima-Chat/optima-gen
33
33
  | `TAG` | ✅ | 对应的两字母 tag(`en` / `th` / `ms` / `vi`) |
34
34
  | `BGM` | ⬜ | 自定义 BGM 文件路径(覆盖默认)。不传则用 npm 包内置 `bgm/default.mp3`(22s clean instrumental,自动 loop)|
35
35
  | `NO_BGM` | ⬜ | 设非空值则跳过 BGM(出片只有人声 + 原视频 BGM 残留)|
36
+ | `VOICE` | ⬜ | HeyGen stock voice_id(从下面 ## Voice Catalog 选)。**不传 = 克隆源说话人音色**(legacy 默认行为)|
36
37
  | `NAME` | ⬜ | 工作区名,默认从 URL 末段推 |
37
38
 
38
39
  ## 3 步主流程(+ Step 0 预检 + Step 4 可选清理)
39
40
 
40
- ### Step 0:声明 + 工作区 + 源视频音量预检
41
+ ### Step 0:声明 + 工作区 + URL 预处理 + 源视频音量预检
41
42
 
42
43
  ```bash
44
+ ## ⚠ URL 必须是公网 https URL,不能是本地路径 /home/aiuser/...
45
+ ## gen video-translate 只接受 https URL(HeyGen 那边要拉的)
46
+ ## 如果是本地路径,先用 chat 系统的 file API 签 URL
47
+ if [[ ! "$URL" =~ ^https?:// ]]; then
48
+ echo "INFO: 本地路径 '$URL',需要上传拿 https URL"
49
+ TOKEN=$(jq -r '.access_token' ~/.optima/token.json)
50
+ ## shell.optima.onl 的 file signing endpoint(具体路径以系统实际为准,
51
+ ## 这里给出常见模式;如果不行,根据 stderr 报错调整)
52
+ SIGNED=$(curl -sS -X POST "https://shell.optima.onl/api/files/sign" \
53
+ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
54
+ -d "{\"path\":\"$URL\"}" 2>&1 | jq -r '.data.url // .url // empty' 2>/dev/null)
55
+ if [ -z "$SIGNED" ]; then
56
+ echo "ERR: 拿不到 signed URL,把 '$URL' 上传到 chat 系统拿 https URL 再来"
57
+ exit 1
58
+ fi
59
+ URL="$SIGNED"
60
+ echo "URL → $URL"
61
+ fi
62
+
43
63
  ## URL 末段可能含 query string(HeyGen / S3 预签名 url 含 token)— 先去掉再 basename
44
64
  NAME="${NAME:-$(echo "$URL" | cut -d'?' -f1 | xargs basename | sed 's/\.[^.]*$//' | sed 's/[^A-Za-z0-9_-]/_/g')}"
45
65
  WORK="./videos/${NAME}.work"
@@ -52,6 +72,42 @@ ffmpeg -i "$URL" -af volumedetect -f null - 2>&1 | grep mean_volume
52
72
 
53
73
  如果 `mean_volume < -25dB`,提示用户:"源视频音量太低(< −25dB),翻译服务大概率会报无人声。建议先用 `ffmpeg -i in.mp4 -af 'volume=20dB,acompressor=threshold=-20dB:ratio=4' -c:v copy out.mp4` 放大后再翻译。"
54
74
 
75
+ ### Step 0.5:让用户挑音色 — 纯文本对话(不要用 AskUserQuestion)
76
+
77
+ **重要:不要用 AskUserQuestion 工具**(只支持 4 选项 + label-based 反查不可靠,试过失败)。**用纯文本输出 5 个选项,等用户文字回复**:
78
+
79
+ agent 输出(逐字照搬,把 $LANG 换成实际目标语):
80
+
81
+ ```
82
+ 翻译到 $LANG,4 个语种共用一个音色。请回复编号(1-5)或名字:
83
+
84
+ 1. Connie - 沉稳专业旁白(F) — preview: https://resource.heygen.ai/text_to_speech/locale=en-USmodel=eleven_multilingual_v2id=9FnNGNtwCeU9fyf6mFfDp8.mp3
85
+ 2. Sophie - 温柔友好(F) — preview: https://resource.heygen.ai/text_to_speech/locale=model=eleven_multilingual_v2id=kte4EzDuRTnsnHkATe6tDK.mp3
86
+ 3. Bruce - 中年浑厚(M) — preview: https://resource.heygen.ai/text_to_speech/locale=model=eleven_multilingual_v2id=2SdnapPUN7wvtCbkPSgdHV.mp3
87
+ 4. Luca - 年轻活力(M) — preview: https://resource.heygen.ai/text_to_speech/locale=model=eleven_multilingual_v2id=FVKYscu8J8EVReBuZdPXnJ.mp3
88
+ 5. 保留原声(克隆源说话人音色)
89
+
90
+ 回复方式:数字 1-5,或者 "Connie"/"Sophie"/"Bruce"/"Luca"/"原声",或者 "随便"(我帮你随机挑)。
91
+ ```
92
+
93
+ #### 用户回复 → VOICE 变量(严格按下表)
94
+
95
+ | 用户回复 | VOICE 变量值 |
96
+ |---|---|
97
+ | `1` / `Connie` / `用 Connie` / 任何含 "Connie" | **`VOICE=d774d69075f24d1fb52a0dad145ba809`** |
98
+ | `2` / `Sophie` / `用 Sophie` | **`VOICE=vakjM0uzzAxU4UiT0433`** |
99
+ | `3` / `Bruce` / `用 Bruce` | **`VOICE=1LtsDD7yfTuX92TzjmJk`** |
100
+ | `4` / `Luca` / `用 Luca` | **`VOICE=6HiVdeiuBdZbtcnukrQn`** |
101
+ | `5` / `原声` / `克隆` / `用我自己的` / `keep original` | **`VOICE=`**(留空,不传 `--voice`) |
102
+ | `随便` / `random` | 从 1-4 voice_id 里**随机挑一个**设 VOICE,**不要默认 5** |
103
+
104
+ #### 严禁(踩过两次了)
105
+
106
+ - ❌ **用 AskUserQuestion 工具**(4 选项限制 + label 反查不可靠,会让用户选了 voice 你跑 clone)
107
+ - ❌ **用户选了 1-4,你设 VOICE=空走 clone** — 跟选择不一致就是 bug
108
+ - ❌ **不列全 5 个选项**(比如只列"用 voice / 原声"二选一,等同不让选)
109
+ - ❌ **不告诉用户怎么回复**(必须明确说"回复数字或名字")
110
+
55
111
  ### Step 1:HeyGen 翻译(用现成 CLI)
56
112
 
57
113
  ```bash
@@ -62,6 +118,7 @@ gen video-translate \
62
118
  --lang "$LANG" \
63
119
  --mode fast \
64
120
  --dynamic-duration \
121
+ ${VOICE:+--voice "$VOICE"} \
65
122
  -o "$RAW_DIR" \
66
123
  > "$WORK/gen.json"
67
124
  ```
@@ -70,14 +127,14 @@ gen video-translate \
70
127
 
71
128
  幂等:`$WORK/gen.json` 存在则跳。
72
129
 
73
- 提取 v3 输出字段(jq null check —— gen 后端契约改名时早 fail):
130
+ **⚠ 提取字段必须用 `.data.` 前缀**:gen-cli `outputSuccess` 把所有字段包装在 `{success: true, data: {...}}` 结构里。**不带 `.data.` 永远读不到字段,SKILL 会卡死**:
74
131
 
75
132
  ```bash
76
- ## v3 API 返回 audio_url + caption_url + video_url 分开;我们只要 audio + caption
77
- AUDIO_URL=$(jq -r '.audio_url // empty' "$WORK/gen.json")
78
- CAP_URL=$(jq -r '.caption_url // empty' "$WORK/gen.json")
133
+ ## gen-cli 输出格式: {"success": true, "data": {"task_id": "...", "audio_url": "...", "caption_url": "..."}}
134
+ AUDIO_URL=$(jq -r '.data.audio_url // empty' "$WORK/gen.json")
135
+ CAP_URL=$(jq -r '.data.caption_url // empty' "$WORK/gen.json")
79
136
  [ -n "$AUDIO_URL" ] && [ -n "$CAP_URL" ] || {
80
- echo "ERR: gen.json 缺 .audio_url 或 .caption_url 字段(需 gen v3 adapter)。看原始 response:"
137
+ echo "ERR: gen.json 缺 .data.audio_url 或 .data.caption_url 字段。原始 response:"
81
138
  cat "$WORK/gen.json"
82
139
  exit 1
83
140
  }
@@ -132,6 +189,14 @@ video-translate mux \
132
189
  - `--raw` = HeyGen v3 译音(audio_url 下载的 wav)
133
190
  - 字幕烧 + BGM ducking 走 mux 内置
134
191
 
192
+ **BGM + 花体字幕样式 = 默认产出的一部分,不是可选项。** 不要问用户"要不要加",不要在结尾说"如需 BGM/字幕样式可补充"。`video-translate mux` 默认就用 `bgm/default.mp3` + Path-B 描边样式;`render-ass --lang $TAG` 默认按语言选字体(Bangers / Sarabun / Noto Sans)。不要绕过 `mux` 自己手写 ffmpeg(会丢 BGM + 字幕样式 + 音轨规范化)。
193
+
194
+ 如果 `mux` 真的失败,先把完整 stderr 给用户看(不要默默用 `ffmpeg -i ... -c copy` 兜底出"裸版"),让用户决定下一步。
195
+
196
+ ## 出片汇报口径
197
+
198
+ 只描述事实("xxx_th.mp4 翻译完成,泰语花体字幕 + BGM ducking 已烧录")。**禁止**任何形式的"如需 X 可以告诉我"尾巴 — BGM 和字幕样式不是可选 add-on,这种话术暗示没做。
199
+
135
200
  ### Step 4(可选):清理
136
201
 
137
202
  ```bash
@@ -139,6 +204,170 @@ video-translate mux \
139
204
  rm -rf "$WORK"
140
205
  ```
141
206
 
207
+ ---
208
+
209
+ ## 批量模式(多语种,一段视频翻多语)
210
+
211
+ **触发条件**:用户一次请求 ≥2 种目标语言("翻译成英/泰/越/马 4 国语")。
212
+
213
+ **不要按单语流程循环跑 N 次**——会有两个致命问题:
214
+ 1. wall time = N × 单次 (~12min/lang × 4 = 48min)
215
+ 2. chat bash 队列被 N 条阻塞命令塞满,后续命令(mux/SFX)全卡"准备中"
216
+
217
+ 改用 **单条 bash 内 N 路 subshell 并发**:chat 队列只占 1 slot,HeyGen 服务端并行处理,wall time ≈ 单次最慢 (~12min)。
218
+
219
+ ### Step B0:URL 预处理 + workspace + 音量预检 + 源视频下载(只跑一次)
220
+
221
+ ```bash
222
+ ## ⚠ URL 预处理:同单语 Step 0,本地路径必须先上传拿 https URL
223
+ if [[ ! "$URL" =~ ^https?:// ]]; then
224
+ TOKEN=$(jq -r '.access_token' ~/.optima/token.json)
225
+ SIGNED=$(curl -sS -X POST "https://shell.optima.onl/api/files/sign" \
226
+ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
227
+ -d "{\"path\":\"$URL\"}" 2>&1 | jq -r '.data.url // .url // empty' 2>/dev/null)
228
+ if [ -z "$SIGNED" ]; then
229
+ echo "ERR: 拿不到 signed URL for '$URL'"; exit 1
230
+ fi
231
+ URL="$SIGNED"
232
+ fi
233
+
234
+ NAME="${NAME:-$(echo "$URL" | cut -d'?' -f1 | xargs basename | sed 's/\.[^.]*$//' | sed 's/[^A-Za-z0-9_-]/_/g')}"
235
+ mkdir -p "./videos/${NAME}.batch"
236
+
237
+ ## 音量预检(同单语 Step 0)
238
+ ffmpeg -i "$URL" -af volumedetect -f null - 2>&1 | grep mean_volume
239
+
240
+ ## 源视频下载一次,所有 mux 共用(避免 N 次重复下载)
241
+ ORIG_VIDEO="./videos/${NAME}.batch/orig.mp4"
242
+ [ -f "$ORIG_VIDEO" ] || curl -sSL "$URL" -o "$ORIG_VIDEO"
243
+ ```
244
+
245
+ ### Step B0.5:voice 选一次,所有语种共用
246
+
247
+ 同单语 Step 0.5。`VOICE` 变量设一次后下方循环里所有 subshell 都继承,**所有语种用同一个 voice 出片**(用户只需挑一次)。
248
+
249
+ ### Step B1:并发派出所有 HeyGen 翻译(后台跑,~5 秒返回)
250
+
251
+ ```bash
252
+ ## 用户实际要的语种,从下面 4 个里选(不要的注释掉)
253
+ LANG_LIST=(
254
+ "English:en"
255
+ "Thai (Thailand):th"
256
+ "Malay (Malaysia):ms"
257
+ "Vietnamese (Vietnam):vi"
258
+ )
259
+
260
+ for entry in "${LANG_LIST[@]}"; do
261
+ LANG="${entry%:*}"
262
+ TAG="${entry##*:}"
263
+ WORK="./videos/${NAME}_${TAG}.work"
264
+ mkdir -p "$WORK/raw"
265
+
266
+ ## 后台启动 gen video-translate,各自写 gen.json,bash 立即继续
267
+ nohup gen video-translate \
268
+ --video-url "$URL" --lang "$LANG" \
269
+ --mode fast --dynamic-duration \
270
+ ${VOICE:+--voice "$VOICE"} \
271
+ -o "$WORK/raw" > "$WORK/gen.json" 2>&1 &
272
+
273
+ echo "$TAG: launched (PID $!) -> $WORK/gen.json"
274
+ done
275
+ echo "=== all submitted, returning immediately ==="
276
+ ```
277
+
278
+ 这一步 5 秒返回。**关键**:用 `nohup ... &` 后台启动,bash exit 后进程继续(尽量 survive 短暂 idle / 容器升级)。每个进程会在 HeyGen 翻译完成后把 audio_url/caption_url 写入对应的 gen.json。
279
+
280
+ ### Step B2-B5:逐语种等结果 → 出片(每个一条独立 bash)
281
+
282
+ **重点:每个语种用单独的 bash 命令处理,不要再用 `&` 并发**。这样:
283
+ - chat 看到每个语种独立完成、独立报告
284
+ - 第 1 个 bash 等 HeyGen(~12 min),后续每个 bash 几乎瞬间完成(因为 4 个翻译是并行跑的,后续几个早已 done)
285
+ - 失败隔离:1 个失败不影响其他
286
+
287
+ 通用 per-lang 模板(把 `$TAG` 换成 en / th / ms / vi 各跑一遍):
288
+
289
+ ```bash
290
+ TAG=en ## ← 换语种就改这个
291
+ WORK="./videos/${NAME}_${TAG}.work"
292
+ FINAL="./videos/${NAME}_${TAG}.mp4"
293
+
294
+ ## 等 gen.json 写完(或失败)
295
+ ## ⚠ gen-cli 用 outputSuccess 包装在 {success, data: {...}} 里,字段在 .data.* 下
296
+ DEADLINE=$(( $(date +%s) + 1800 )) ## 30min 上限,跟 HeyGen poll timeout 对齐
297
+ while true; do
298
+ ## Case 1: 成功 → .data.audio_url 非 null
299
+ if jq -e '.data.audio_url' "$WORK/gen.json" >/dev/null 2>&1; then
300
+ break
301
+ fi
302
+ ## Case 2: 业务失败 → .data.error_message(outputSuccess with status=failed)
303
+ if jq -e '.data.error_message' "$WORK/gen.json" >/dev/null 2>&1; then
304
+ echo "[$TAG] FAIL: $(jq -r '.data.error_message' "$WORK/gen.json")"
305
+ exit 1
306
+ fi
307
+ ## Case 3: CLI 异常 → .error.code/.error.message(outputError 抛出)
308
+ if jq -e '.error' "$WORK/gen.json" >/dev/null 2>&1; then
309
+ echo "[$TAG] FAIL: $(jq -r '.error.code + \": \" + .error.message' "$WORK/gen.json")"
310
+ exit 1
311
+ fi
312
+ ## Case 4: 30min 超时(HeyGen 一般 5-15min,30min 还没就是真挂了)
313
+ if [ "$(date +%s)" -gt "$DEADLINE" ]; then
314
+ echo "[$TAG] TIMEOUT 30min,gen.json 内容:"; cat "$WORK/gen.json"; exit 1
315
+ fi
316
+ sleep 15
317
+ done
318
+
319
+ ## 拿到 audio_url + caption_url(必须带 .data. 前缀)
320
+ AUDIO_URL=$(jq -r '.data.audio_url' "$WORK/gen.json")
321
+ CAP_URL=$(jq -r '.data.caption_url' "$WORK/gen.json")
322
+
323
+ ## 下载 + render-ass
324
+ curl -sSL --retry 1 "$AUDIO_URL" -o "$WORK/translated_audio.wav"
325
+ curl -sSL --retry 1 "$CAP_URL" -o "$WORK/caption.srt"
326
+ video-translate render-ass \
327
+ --srt "$WORK/caption.srt" --lang "$TAG" \
328
+ --translations "$WORK/translations.json" \
329
+ --out "$WORK/subs.ass"
330
+
331
+ ## mux 出片
332
+ video-translate mux \
333
+ --raw "$WORK/translated_audio.wav" \
334
+ --orig-video "$ORIG_VIDEO" \
335
+ --ass "$WORK/subs.ass" \
336
+ ${BGM:+--bgm "$BGM"} ${NO_BGM:+--no-bgm} \
337
+ --work "$WORK" \
338
+ --out "$FINAL"
339
+
340
+ echo "[$TAG] DONE -> $FINAL"
341
+ ```
342
+
343
+ **Agent 执行节奏**:
344
+ 1. 跑 Step B1(1 条 bash,5 秒返回,**立刻告知用户"4 个翻译派出去了"**)
345
+ 2. 跑 per-lang 模板 `TAG=en`(1 条 bash,~12 min,出片后**立刻告知用户"English 出片 ✓"**)
346
+ 3. 跑 per-lang 模板 `TAG=th`(1 条 bash,~30 秒,出片后**立刻告知用户"Thai 出片 ✓"**)
347
+ 4. 跑 per-lang 模板 `TAG=ms`(~30 秒)
348
+ 5. 跑 per-lang 模板 `TAG=vi`(~30 秒)
349
+
350
+ **总 wall time 不变(~13 min)**,但用户每 30 秒看到一个出片,不是 12 min 黑盒后突然 4 个一起出。
351
+
352
+ 输出:`./videos/${NAME}_en.mp4` / `_th.mp4` / `_ms.mp4` / `_vi.mp4`
353
+
354
+ ### 单语 vs 渐进批量对比
355
+
356
+ | | 单语循环(❌ 不要) | 渐进批量(✓) |
357
+ |---|---|---|
358
+ | 源视频下载 | N 次重下 | 1 次共用 |
359
+ | HeyGen 调用 | 串行 N × 12min | 并发 max(12min) |
360
+ | chat 队列占 | N 条阻塞 bash | 1 条 submit + N 条快速 poll |
361
+ | 失败隔离 | 一个挂全停 | per-lang subshell + bash 独立 |
362
+ | 用户感知 | 黑盒 48 min | 第 1 个 ~12 min 出,后续每 ~30 秒 1 个 |
363
+ | **wall time(N=4)** | **~48 min** | **~13 min(73%↓)** |
364
+
365
+ ### 失败处理
366
+
367
+ - 单 lang 失败:per-lang bash `exit 1`,agent 报告该语种失败但**继续跑下一个语种的 bash**
368
+ - 用户对失败的单 lang re-run → 删 `$WORK/gen.json` 重跑 Step B1 单语 + per-lang 模板即可
369
+ - HeyGen credit 不足报错 → 当 lang 个失败处理,不阻塞其他 lang
370
+
142
371
  ## 错误处理
143
372
 
144
373
  | 失败 | 处理 |
@@ -148,15 +377,14 @@ rm -rf "$WORK"
148
377
  | HeyGen `status: failed` "No speaker is detected" | 同源视频音量过低处理 |
149
378
  | HeyGen 其他失败 | 透出 task_id,提示用 `gen task get <id>` 查最新;干净退出 |
150
379
  | HeyGen >30min 超时 | 同上,可能任务还在 running |
151
- | `gen.json` 缺 `.output` / `.caption_url` | gen 后端契约可能改字段名。打 `cat $WORK/gen.json` 看实际字段 |
380
+ | `gen.json` 缺 `.audio_url` / `.caption_url` | gen 后端契约可能改字段名。打 `cat $WORK/gen.json` 看实际字段 |
152
381
  | `curl <caption_url>` 失败 | URL 7 天 expire。retry 1 次后仍失败 → 重跑 step 1 |
153
382
  | `video-translate render-ass` SRT 解析失败 | 显示 SRT 头 20 行,不重试 |
154
383
  | `video-translate mux` 字体 ☐ | 检查 `fc-match Bangers / Sarabun / "Noto Sans"` 是否精确返回 |
155
384
 
156
385
  ## 不做
157
386
 
158
- - ❌ 音色覆盖(voice override)— v1 默认 HeyGen 自动克隆;v2 再考虑"用户问起时 LLM 给候选 + preview URL"流程
159
- - ❌ 性别自动检测 — 同上 defer v2
387
+ - ❌ 性别自动检测(让用户自己选,见 Step 0.5)
160
388
  - ❌ 硬字幕(burnt-in)抹除 — 源视频有的话出片会双语
161
389
  - ❌ 自动加粗关键词 — SRT 直入无粉色,用户手编 translations.json
162
390
  - ❌ 双说话人差异化音色 — HeyGen 自动 diarize 但用同一克隆音色
@@ -166,3 +394,18 @@ rm -rf "$WORK"
166
394
 
167
395
  - 设计 SPEC:https://github.com/Optima-Chat/video-translate/blob/main/SPEC.md (v3.1)
168
396
  - 实测踩坑(gotchas):同上 §Gotchas
397
+
398
+ ---
399
+
400
+ ## Voice Catalog
401
+
402
+ 下面 4 个 voice 全部是 HeyGen catalog 里走 **ElevenLabs `eleven_multilingual_v2`** 模型的多语 voice,**任选一个,所有支持语言(en/th/ms/vi)都能说**。实测 Connie 跨 4 语全部 Whisper 95%+ 语种识别置信度,音色保留 + 自动适配目标语言性别敬语(如泰语 ค่ะ/ครับ)。
403
+
404
+ | # | voice_id | 名字 | 性别 | 风格定位 | preview(英文样本) |
405
+ |---|---|---|---|---|---|
406
+ | 1 | `d774d69075f24d1fb52a0dad145ba809` | Connie - Professional | F | 沉稳专业旁白 | https://resource.heygen.ai/text_to_speech/locale=en-USmodel=eleven_multilingual_v2id=9FnNGNtwCeU9fyf6mFfDp8.mp3 |
407
+ | 2 | `vakjM0uzzAxU4UiT0433` | Sophie | F | 温柔友好 | https://resource.heygen.ai/text_to_speech/locale=model=eleven_multilingual_v2id=kte4EzDuRTnsnHkATe6tDK.mp3 |
408
+ | 3 | `1LtsDD7yfTuX92TzjmJk` | Bruce | M | 中年浑厚 | https://resource.heygen.ai/text_to_speech/locale=model=eleven_multilingual_v2id=2SdnapPUN7wvtCbkPSgdHV.mp3 |
409
+ | 4 | `6HiVdeiuBdZbtcnukrQn` | Luca | M | 年轻活力 | https://resource.heygen.ai/text_to_speech/locale=model=eleven_multilingual_v2id=FVKYscu8J8EVReBuZdPXnJ.mp3 |
410
+
411
+ > 维护说明:换 voice 时,从 `GET /v2/voices` 里筛 `preview_audio` 含 `multilingual` 的 EL 系列。其它非 EL 系列的"English"标签 voice **大概率**不能跨语言,要实测验证。
@@ -1 +1 @@
1
- {"version":3,"file":"asr.d.ts","sourceRoot":"","sources":["../../src/commands/asr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,QAiIlD"}
1
+ {"version":3,"file":"asr.d.ts","sourceRoot":"","sources":["../../src/commands/asr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,QAoIlD"}
@@ -79,12 +79,15 @@ export function registerAsrCommand(program) {
79
79
  });
80
80
  }
81
81
  else {
82
- outputSuccess({
82
+ // task status != completed → 失败。outputError 让顶层 success:false 并 exit 1,
83
+ // 否则 Agent 把 failure 当 success(参见 image.ts 同样修复)。
84
+ const errCode = result.error_code ?? 'GENERATION_FAILED';
85
+ const errMsg = result.error_message ?? `任务状态: ${result.status}`;
86
+ outputError(errCode, errMsg, options, {
83
87
  task_id: result.task_id,
84
88
  status: result.status,
85
- error_code: result.error_code ?? null,
86
89
  retryable: result.retryable ?? false,
87
- error_message: result.error_message,
90
+ error_class: result.error_class ?? null,
88
91
  });
89
92
  }
90
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"asr.js","sourceRoot":"","sources":["../../src/commands/asr.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAElB,iBAAiB,EACjB,YAAY,GACb,MAAM,+BAA+B,CAAC;AAEvC,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,GAAG,GAAG,OAAO;SAChB,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,yCAAyC,CAAC;SACtD,QAAQ,CAAC,QAAQ,EAAE,sCAAsC,CAAC;SAC1D,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,CAAC;SACxD,MAAM,CAAC,gBAAgB,EAAE,YAAY,EAAE,wBAAwB,CAAC;SAChE,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAO,EAAE,EAAE;QACtC,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QAErC,IAAI,CAAC;YACH,WAAW;YACX,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,WAAW,CAAC,gBAAgB,EAAE,YAAY,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC/D,OAAO;YACT,CAAC;YAED,YAAY;YACZ,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAE3C,eAAe;YACf,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;YAEhD,MAAM,MAAM,GAAiB;gBAC3B,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACjC,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC;YAEF,MAAM,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE7B,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;gBAEzC,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE;wBACvD,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE;4BACrB,OAAO,CAAC,IAAI,GAAG,UAAU,MAAM,MAAM,CAAC;wBACxC,CAAC;qBACF,CAAC,CAAC;oBAEH,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;oBAE1C,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;wBAClC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;wBAC3B,IAAI,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;4BAC7B,OAAO,CAAC,SAAS,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;wBAC9C,CAAC;6BAAM,CAAC;4BACN,IAAI,CAAC,+BAA+B,MAAM,CAAC,OAAO,QAAQ,CAAC,CAAC;wBAC9D,CAAC;wBACD,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBACjD,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;wBACvC,IAAI,MAAM,CAAC,aAAa;4BAAE,IAAI,CAAC,OAAO,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;wBAC9D,IAAI,CAAC,oBAAoB,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;oBACrD,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,OAAO,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;oBAC7C,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBACzD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAE1C,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;oBAClC,aAAa,CAAC;wBACZ,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE;wBACpC,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM;wBACpC,KAAK,EAAE,OAAO,CAAC,KAAK;wBACpB,UAAU;qBACX,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,aAAa,CAAC;wBACZ,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI;wBACrC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,KAAK;wBACpC,aAAa,EAAE,MAAM,CAAC,aAAa;qBACpC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,kBAAkB,EAAE,CAAC;gBACtC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,YAAY,EAAE,WAAW,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,eAAe,CAAC,GAAG,EAAE;QACnB,QAAQ,EAAE;YACR,iBAAiB;YACjB,yBAAyB;YACzB,EAAE;YACF,iBAAiB;YACjB,uCAAuC;YACvC,EAAE;YACF,UAAU;YACV,oCAAoC;SACrC;QACD,UAAU,EAAE;;;;;;;;;;EAUd;QACE,eAAe,EAAE;YACf,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE;YAC/C,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE;SACpD;QACD,KAAK,EAAE;YACL,yCAAyC;YACzC,mDAAmD;YACnD,qCAAqC;YACrC,aAAa;SACd;KACF,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"asr.js","sourceRoot":"","sources":["../../src/commands/asr.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,17 @@
1
1
  import { Command } from 'commander';
2
2
  /**
3
- * `gen avatar train <video-file> --external-id <id>` train a HeyGen digital_twin avatar
4
- * from a local video file. CLI handles asset upload + submit + poll, then prints look_id.
3
+ * `gen avatar`数字人分身完整 namespace.
4
+ *
5
+ * 低层 (本文件):
6
+ * gen avatar train <video-file> --external-id <id> 训练 avatar look
7
+ *
8
+ * 高层 (来自 doctor.ts,作为 alias 也注册在 gen doctor 下):
9
+ * gen avatar onboard <audio> <video> 一次性训 voice + avatar
10
+ * gen avatar video --avatar <id> --voice <id> 用 trained avatar 合成视频
11
+ * gen avatar profile <external-id> 查 profile (voice_id / look_id / 状态)
12
+ *
13
+ * gen doctor * 是历史命名 (Phase 2 POC 起源于医生场景),保留作为兼容性别名,
14
+ * 行为完全一致。新用户 / 文档推荐用 gen avatar *。
5
15
  *
6
16
  * Phase 2 doctor-avatar feature. See spec §13 + §13.4 (clean-bg requirement).
7
17
  */
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../src/commands/avatar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QA6JrD"}
1
+ {"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../src/commands/avatar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QAqKrD"}
@@ -5,14 +5,28 @@ import { success, info, warning } from '../utils/logger.js';
5
5
  import { outputSuccess, outputError, isPrettyMode } from '../utils/output.js';
6
6
  import { addEnhancedHelp } from '../utils/helpText.js';
7
7
  import { GenerationApiClient, GenerationApiError } from '../services/generation-api.js';
8
+ import { registerDoctorSubcommands } from './doctor.js';
8
9
  /**
9
- * `gen avatar train <video-file> --external-id <id>` train a HeyGen digital_twin avatar
10
- * from a local video file. CLI handles asset upload + submit + poll, then prints look_id.
10
+ * `gen avatar`数字人分身完整 namespace.
11
+ *
12
+ * 低层 (本文件):
13
+ * gen avatar train <video-file> --external-id <id> 训练 avatar look
14
+ *
15
+ * 高层 (来自 doctor.ts,作为 alias 也注册在 gen doctor 下):
16
+ * gen avatar onboard <audio> <video> 一次性训 voice + avatar
17
+ * gen avatar video --avatar <id> --voice <id> 用 trained avatar 合成视频
18
+ * gen avatar profile <external-id> 查 profile (voice_id / look_id / 状态)
19
+ *
20
+ * gen doctor * 是历史命名 (Phase 2 POC 起源于医生场景),保留作为兼容性别名,
21
+ * 行为完全一致。新用户 / 文档推荐用 gen avatar *。
11
22
  *
12
23
  * Phase 2 doctor-avatar feature. See spec §13 + §13.4 (clean-bg requirement).
13
24
  */
14
25
  export function registerAvatarCommand(program) {
15
- const avatar = program.command('avatar').description('医生 avatar(数字人)训练相关命令(Phase 2)');
26
+ const avatar = program.command('avatar').description('数字人分身相关命令 (train / onboard / video / profile)');
27
+ // 高层 facade (与 gen doctor * 等价)
28
+ registerDoctorSubcommands(avatar);
29
+ // 低层 train (仅在 gen avatar 下注册,不在 gen doctor 下出现)
16
30
  const trainCmd = avatar
17
31
  .command('train')
18
32
  .description('用本地视频训练 HeyGen digital_twin avatar,产出 avatar look_id')
@@ -93,19 +107,23 @@ export function registerAvatarCommand(program) {
93
107
  }
94
108
  }
95
109
  else {
110
+ // task status != completed → 失败。让顶层 success:false 并 exit 1,否则
111
+ // Agent 会把 failure 当 success(参见 image.ts 同样修复)。
112
+ const errCode = result.error_code ?? 'GENERATION_FAILED';
113
+ const errMsg = result.error_message ?? `任务状态: ${result.status}`;
96
114
  if (pretty) {
97
- trainSpinner.info(`任务状态: ${result.status}`);
98
- if (result.error_message)
99
- info(`错误: ${result.error_message}`);
115
+ trainSpinner.fail(errMsg);
116
+ if (result.error_code)
117
+ info(`错误码: ${result.error_code}${result.retryable ? '(可重试)' : ''}`);
100
118
  info(`使用 'gen task get ${result.task_id}' 查看最新状态`);
119
+ process.exit(1);
101
120
  }
102
121
  else {
103
- outputSuccess({
122
+ outputError(errCode, errMsg, options, {
104
123
  task_id: result.task_id,
105
124
  status: result.status,
106
- error_code: result.error_code ?? null,
107
125
  retryable: result.retryable ?? false,
108
- error_message: result.error_message,
126
+ error_class: result.error_class ?? null,
109
127
  });
110
128
  }
111
129
  }
@@ -1 +1 @@
1
- {"version":3,"file":"avatar.js","sourceRoot":"","sources":["../../src/commands/avatar.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"avatar.js","sourceRoot":"","sources":["../../src/commands/avatar.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,19 @@
1
1
  import { Command } from 'commander';
2
2
  /**
3
- * `gen doctor` namespace — Phase 2 doctor-avatar high-level commands:
4
- * gen doctor onboard <audio> <video> --external-id <id>
5
- * gen doctor video --avatar <id> --voice <id> --text <...>
6
- * gen doctor profile <external-id>
3
+ * `gen doctor` namespace — historical naming (Phase 2 POC originated for medical
4
+ * scenarios). Functionally identical to `gen avatar *` and kept as a
5
+ * backward-compatible alias.
6
+ *
7
+ * Subcommands (registered via registerDoctorSubcommands, also reused under
8
+ * `gen avatar` in avatar.ts):
9
+ * onboard <audio> <video> --external-id <id>
10
+ * video --avatar <id> --voice <id> --text <...>
11
+ * profile <external-id>
12
+ *
13
+ * All user-facing help text refers to `gen avatar *` (recommended name),
14
+ * not `gen doctor *`. `--help` under either namespace guides users toward
15
+ * the unified command set.
7
16
  */
8
17
  export declare function registerDoctorCommand(program: Command): void;
18
+ export declare function registerDoctorSubcommands(parent: Command): void;
9
19
  //# sourceMappingURL=doctor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QAMrD"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QAMrD;AAKD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,QAIxD"}