@optima-chat/gen-cli 1.0.9 → 1.2.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.
- package/.claude/skills/gen/SKILL.md +345 -0
- package/.claude/skills/multigrid-poster/SKILL.md +194 -0
- package/.claude/skills/multigrid-poster/layouts/2x2.json +34 -0
- package/.claude/skills/multigrid-poster/layouts/3x3.json +43 -0
- package/.claude/skills/multigrid-poster/scripts/compose.py +116 -0
- package/.claude/skills/multigrid-poster/scripts/placeholder.png +0 -0
- package/.claude/skills/multigrid-poster/shared/fonts/MaShanZheng-Regular.ttf +0 -0
- package/.claude/skills/video-edit/SKILL.md +189 -0
- package/.claude/skills/video-gen/SKILL.md +718 -0
- package/.claude/skills/video-gen/templates/INDEX.md +78 -0
- package/.claude/skills/video-gen/templates/before-after-beauty.md +183 -0
- package/.claude/skills/video-gen/templates/drama-fmcg.md +183 -0
- package/.claude/skills/video-gen/templates/kol-reaction-food.md +193 -0
- package/.claude/skills/video-gen/templates/multi-point-apparel.md +185 -0
- package/.claude/skills/video-gen/templates/pain-solution-home.md +184 -0
- package/.claude/skills/video-gen/templates/pdp-360-showcase.md +189 -0
- package/.claude/skills/video-gen/templates/pdp-feature-highlight.md +182 -0
- package/.claude/skills/video-gen/templates/scene-digital.md +183 -0
- package/dist/commands/avatar.d.ts +9 -0
- package/dist/commands/avatar.d.ts.map +1 -0
- package/dist/commands/avatar.js +155 -0
- package/dist/commands/avatar.js.map +1 -0
- package/dist/commands/doctor.d.ts +9 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +293 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/video.d.ts.map +1 -1
- package/dist/commands/video.js +21 -25
- package/dist/commands/video.js.map +1 -1
- package/dist/commands/voice.d.ts +9 -0
- package/dist/commands/voice.d.ts.map +1 -0
- package/dist/commands/voice.js +123 -0
- package/dist/commands/voice.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/services/generation-api.d.ts +69 -4
- package/dist/services/generation-api.d.ts.map +1 -1
- package/dist/services/generation-api.js +114 -8
- package/dist/services/generation-api.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { success, info, warning } from '../utils/logger.js';
|
|
5
|
+
import { outputSuccess, outputError, isPrettyMode } from '../utils/output.js';
|
|
6
|
+
import { addEnhancedHelp } from '../utils/helpText.js';
|
|
7
|
+
import { GenerationApiClient, GenerationApiError, resolveOutputPath, downloadResult, } from '../services/generation-api.js';
|
|
8
|
+
import { getConfigValue } from '../services/config.js';
|
|
9
|
+
/**
|
|
10
|
+
* `gen doctor` namespace — Phase 2 doctor-avatar high-level commands:
|
|
11
|
+
* gen doctor onboard <audio> <video> --external-id <id>
|
|
12
|
+
* gen doctor video --avatar <id> --voice <id> --text <...>
|
|
13
|
+
* gen doctor profile <external-id>
|
|
14
|
+
*/
|
|
15
|
+
export function registerDoctorCommand(program) {
|
|
16
|
+
const doctor = program.command('doctor').description('医生数字分身相关命令(Phase 2)');
|
|
17
|
+
registerOnboard(doctor);
|
|
18
|
+
registerVideo(doctor);
|
|
19
|
+
registerProfile(doctor);
|
|
20
|
+
}
|
|
21
|
+
function registerOnboard(doctor) {
|
|
22
|
+
const cmd = doctor
|
|
23
|
+
.command('onboard')
|
|
24
|
+
.description('一次性训练医生 voice + avatar(并发 2 个底层 task)')
|
|
25
|
+
.argument('<audio-file>', '音频文件路径(.wav / .mp3 等)')
|
|
26
|
+
.argument('<video-file>', '视频文件路径(.mp4 / .mov 等)')
|
|
27
|
+
.requiredOption('--external-id <id>', '业务方医生标识')
|
|
28
|
+
.option('--clean-bg', '声明视频背景已干净(白墙/医院/棚拍/绿幕)', false)
|
|
29
|
+
.option('--accept-baked-bg', '明确接受脏背景被 baked 进 avatar look(spec §13.4 — 仅用于探针/非上线)', false)
|
|
30
|
+
.action(async (audioFile, videoFile, options) => {
|
|
31
|
+
const pretty = isPrettyMode(options);
|
|
32
|
+
try {
|
|
33
|
+
if (!options.cleanBg && !options.acceptBakedBg) {
|
|
34
|
+
outputError('BG_DECISION_REQUIRED', '请二选一(spec §13.4):\n --clean-bg 视频背景已干净\n --accept-baked-bg 接受脏背景成为 avatar 永久背景', options);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (options.cleanBg && options.acceptBakedBg) {
|
|
38
|
+
outputError('BG_DECISION_CONFLICT', '--clean-bg 和 --accept-baked-bg 二选一', options);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const audioPath = path.resolve(audioFile);
|
|
42
|
+
const videoPath = path.resolve(videoFile);
|
|
43
|
+
if (!fs.existsSync(audioPath)) {
|
|
44
|
+
outputError('AUDIO_NOT_FOUND', `音频文件不存在: ${audioPath}`, options);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (!fs.existsSync(videoPath)) {
|
|
48
|
+
outputError('VIDEO_NOT_FOUND', `视频文件不存在: ${videoPath}`, options);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (pretty && options.acceptBakedBg) {
|
|
52
|
+
warning('已显式接受脏背景被 baked,生成视频时无法替换 avatar 内置背景');
|
|
53
|
+
}
|
|
54
|
+
const client = new GenerationApiClient();
|
|
55
|
+
// Step 1+2: upload both assets concurrently
|
|
56
|
+
const upSpinner = pretty ? ora('并发上传音频 + 视频到 HeyGen 资产存储...').start() : null;
|
|
57
|
+
const [audioAsset, videoAsset] = await Promise.all([
|
|
58
|
+
client.uploadHeyGenAsset(audioPath),
|
|
59
|
+
client.uploadHeyGenAsset(videoPath),
|
|
60
|
+
]);
|
|
61
|
+
if (pretty)
|
|
62
|
+
upSpinner.succeed(`两个资产已上传(audio=${audioAsset.asset_id}, video=${videoAsset.asset_id})`);
|
|
63
|
+
// Step 3: submit onboard facade
|
|
64
|
+
const onboardSpinner = pretty ? ora('提交 doctor onboard(并发触发 voice + avatar 训练)...').start() : null;
|
|
65
|
+
const onboard = await client.submitDoctorOnboard({
|
|
66
|
+
audio_asset_id: audioAsset.asset_id,
|
|
67
|
+
video_asset_id: videoAsset.asset_id,
|
|
68
|
+
external_id: options.externalId,
|
|
69
|
+
training_video_clean_bg: options.cleanBg,
|
|
70
|
+
});
|
|
71
|
+
if (pretty)
|
|
72
|
+
onboardSpinner.succeed(`onboard 提交成功(voice_task=${onboard.voice_task_id}, avatar_task=${onboard.avatar_task_id})`);
|
|
73
|
+
if (pretty) {
|
|
74
|
+
info('两个底层 task 异步训练中,使用以下命令各自查状态:');
|
|
75
|
+
info(` gen task get ${onboard.voice_task_id}`);
|
|
76
|
+
info(` gen task get ${onboard.avatar_task_id}`);
|
|
77
|
+
info(`完成后用: gen doctor profile ${options.externalId} 查看 voice_id + look_id`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
outputSuccess({
|
|
81
|
+
external_id: onboard.external_id,
|
|
82
|
+
voice_task_id: onboard.voice_task_id,
|
|
83
|
+
avatar_task_id: onboard.avatar_task_id,
|
|
84
|
+
status: 'pending',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
if (err instanceof GenerationApiError) {
|
|
90
|
+
outputError(err.code, err.message, options);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
outputError('ONBOARD_FAILED', `onboard 失败: ${err}`, options);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
addEnhancedHelp(cmd, {
|
|
98
|
+
examples: [
|
|
99
|
+
'# 一次性训练医生 voice + avatar',
|
|
100
|
+
'$ gen doctor onboard ./audio.wav ./video.mp4 --external-id doc-123 --clean-bg',
|
|
101
|
+
],
|
|
102
|
+
outputJson: `{
|
|
103
|
+
"success": true,
|
|
104
|
+
"data": {
|
|
105
|
+
"external_id": "doc-123",
|
|
106
|
+
"voice_task_id": "task-uuid-1",
|
|
107
|
+
"avatar_task_id": "task-uuid-2",
|
|
108
|
+
"status": "pending"
|
|
109
|
+
}
|
|
110
|
+
}`,
|
|
111
|
+
relatedCommands: [
|
|
112
|
+
{ command: 'task get <id>', description: '查 voice/avatar 任务状态' },
|
|
113
|
+
{ command: 'doctor profile <external-id>', description: '查 profile(含 voice_id + look_id)' },
|
|
114
|
+
{ command: 'doctor video --avatar --voice --text', description: '用训练好的 ID 合成视频' },
|
|
115
|
+
],
|
|
116
|
+
notes: [
|
|
117
|
+
'Onboard 内部并发触发 voice-clone + avatar-train 两个独立 task(失败 isolation)',
|
|
118
|
+
'想细控就分别用 gen voice clone + gen avatar train',
|
|
119
|
+
],
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function registerVideo(doctor) {
|
|
123
|
+
const cmd = doctor
|
|
124
|
+
.command('video')
|
|
125
|
+
.description('用训练好的 doctor avatar + voice 合成视频(自动 retry-on-still-processing + DELETE cleanup)')
|
|
126
|
+
.requiredOption('--avatar <id>', 'avatar look_id(从 gen avatar train 或 gen doctor profile 拿到)')
|
|
127
|
+
.requiredOption('--voice <id>', 'voice_id(从 gen voice clone 或 gen doctor profile 拿到)')
|
|
128
|
+
.requiredOption('--text <text>', '医生说话文本(≤ 50 字, spec §13.3)')
|
|
129
|
+
.option('--title <title>', '视频标题')
|
|
130
|
+
.option('-o, --output <path>', '输出文件 / 目录')
|
|
131
|
+
.action(async (options) => {
|
|
132
|
+
const pretty = isPrettyMode(options);
|
|
133
|
+
try {
|
|
134
|
+
if (options.text.length > 50) {
|
|
135
|
+
outputError('TEXT_TOO_LONG', 'text 不能超过 50 字符(spec §13.3:trained avatar 长 prompt 挂死,client 端拆段)', options);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const client = new GenerationApiClient();
|
|
139
|
+
const defaultDir = getConfigValue('outputDir') || './gen-output';
|
|
140
|
+
const spinner = pretty ? ora('提交 doctor-video 生成任务...').start() : null;
|
|
141
|
+
const result = await client.submitAndPoll('doctor-video', {
|
|
142
|
+
avatar_id: options.avatar,
|
|
143
|
+
voice_id: options.voice,
|
|
144
|
+
text: options.text,
|
|
145
|
+
title: options.title,
|
|
146
|
+
}, {
|
|
147
|
+
timeout: 1800000, // 30 min
|
|
148
|
+
onProgress: (status) => {
|
|
149
|
+
if (pretty)
|
|
150
|
+
spinner.text = `doctor-video 生成中 (${status})...`;
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
if (result.status === 'completed' && result.result_url) {
|
|
154
|
+
const defaultFilename = `doctor_${result.task_id.slice(0, 8)}.mp4`;
|
|
155
|
+
const { dir, filename } = resolveOutputPath(options.output, defaultDir, defaultFilename);
|
|
156
|
+
const outputPath = await downloadResult(result.result_url, dir, filename);
|
|
157
|
+
if (pretty) {
|
|
158
|
+
spinner.succeed('doctor video 生成完成!');
|
|
159
|
+
success(`输出文件: ${outputPath}`);
|
|
160
|
+
info(`task_id: ${result.task_id}`);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
outputSuccess({
|
|
164
|
+
task_id: result.task_id,
|
|
165
|
+
status: result.status,
|
|
166
|
+
output: outputPath,
|
|
167
|
+
result_url: result.result_url,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
if (pretty) {
|
|
173
|
+
spinner.info(`任务状态: ${result.status}`);
|
|
174
|
+
if (result.error_message)
|
|
175
|
+
info(`错误: ${result.error_message}`);
|
|
176
|
+
info(`使用 'gen task get ${result.task_id}' 查看最新状态`);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
outputSuccess({
|
|
180
|
+
task_id: result.task_id,
|
|
181
|
+
status: result.status,
|
|
182
|
+
error_code: result.error_code ?? null,
|
|
183
|
+
retryable: result.retryable ?? false,
|
|
184
|
+
error_message: result.error_message,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
if (err instanceof GenerationApiError) {
|
|
191
|
+
outputError(err.code, err.message, options);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
outputError('DOCTOR_VIDEO_FAILED', `生成失败: ${err}`, options);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
addEnhancedHelp(cmd, {
|
|
199
|
+
examples: [
|
|
200
|
+
'# 用训练好的 doctor avatar + voice 合成 ≤ 50 字短视频',
|
|
201
|
+
'$ gen doctor video --avatar look_xxx --voice voice_xxx --text "你好,我是张医生。"',
|
|
202
|
+
],
|
|
203
|
+
outputJson: `{
|
|
204
|
+
"success": true,
|
|
205
|
+
"data": {
|
|
206
|
+
"task_id": "task-uuid",
|
|
207
|
+
"status": "completed",
|
|
208
|
+
"output": "./gen-output/doctor_abc123.mp4",
|
|
209
|
+
"result_url": "https://heygen/..."
|
|
210
|
+
}
|
|
211
|
+
}`,
|
|
212
|
+
relatedCommands: [
|
|
213
|
+
{ command: 'doctor profile <external-id>', description: '查 avatar look_id + voice_id' },
|
|
214
|
+
{ command: 'video --provider heygen', description: '用任意 HeyGen avatar/voice 合成(无 retry/cleanup wrapper)' },
|
|
215
|
+
],
|
|
216
|
+
notes: [
|
|
217
|
+
'**text 上限 50 字**(spec §13.3:trained avatar 长 prompt 挂死)',
|
|
218
|
+
'内部封装:retry-on-"still-processing"(初始 1min,30min 上限)+ DELETE cleanup 卡死任务',
|
|
219
|
+
'生成时长几十秒到几分钟',
|
|
220
|
+
],
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
function registerProfile(doctor) {
|
|
224
|
+
const cmd = doctor
|
|
225
|
+
.command('profile')
|
|
226
|
+
.description('查询医生 profile(voice_id + look_id + 状态)')
|
|
227
|
+
.argument('<external-id>', '业务方医生标识')
|
|
228
|
+
.action(async (externalId, options) => {
|
|
229
|
+
const pretty = isPrettyMode(options);
|
|
230
|
+
try {
|
|
231
|
+
const client = new GenerationApiClient();
|
|
232
|
+
const profile = await client.getDoctorAvatarProfile(externalId);
|
|
233
|
+
if (!profile) {
|
|
234
|
+
if (pretty) {
|
|
235
|
+
warning(`profile 不存在: external_id=${externalId}`);
|
|
236
|
+
info('先训练:gen voice clone / gen avatar train / gen doctor onboard');
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
outputError('NOT_FOUND', `profile not found: ${externalId}`, options);
|
|
240
|
+
}
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (pretty) {
|
|
244
|
+
success(`Doctor Avatar Profile: ${profile.external_id}`);
|
|
245
|
+
info(`voice_id: ${profile.heygen_voice_id ?? '(not trained)'}`);
|
|
246
|
+
info(`voice_status: ${profile.voice_status}${profile.voice_error ? ` (${profile.voice_error})` : ''}`);
|
|
247
|
+
info(`avatar_group_id: ${profile.heygen_avatar_group_id ?? '(not trained)'}`);
|
|
248
|
+
info(`avatar look_ids: ${JSON.stringify(profile.heygen_avatar_look_ids)}`);
|
|
249
|
+
info(`avatar_status: ${profile.avatar_status}${profile.avatar_error ? ` (${profile.avatar_error})` : ''}`);
|
|
250
|
+
info(`preview_image: ${profile.preview_image_url ?? '(none)'}`);
|
|
251
|
+
info(`clean_bg: ${profile.training_video_clean_bg}`);
|
|
252
|
+
info(`consent_status: ${profile.consent_status ?? '(unknown)'}`);
|
|
253
|
+
info(`created_at: ${profile.created_at}`);
|
|
254
|
+
info(`updated_at: ${profile.updated_at}`);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
outputSuccess(profile);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
if (err instanceof GenerationApiError) {
|
|
262
|
+
outputError(err.code, err.message, options);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
outputError('PROFILE_QUERY_FAILED', `查询 profile 失败: ${err}`, options);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
addEnhancedHelp(cmd, {
|
|
270
|
+
examples: ['# 查看医生训练状态 + ID', '$ gen doctor profile doc-123'],
|
|
271
|
+
outputJson: `{
|
|
272
|
+
"success": true,
|
|
273
|
+
"data": {
|
|
274
|
+
"external_id": "doc-123",
|
|
275
|
+
"heygen_voice_id": "f7a8ea9f...",
|
|
276
|
+
"voice_status": "complete",
|
|
277
|
+
"heygen_avatar_group_id": "174fa88e...",
|
|
278
|
+
"heygen_avatar_look_ids": ["04182555..."],
|
|
279
|
+
"avatar_status": "completed",
|
|
280
|
+
"preview_image_url": "https://heygen/preview.jpg",
|
|
281
|
+
"training_video_clean_bg": true,
|
|
282
|
+
"consent_status": "skipped",
|
|
283
|
+
"created_at": "2026-05-08T12:00:00Z",
|
|
284
|
+
"updated_at": "2026-05-08T12:10:00Z"
|
|
285
|
+
}
|
|
286
|
+
}`,
|
|
287
|
+
relatedCommands: [
|
|
288
|
+
{ command: 'doctor video --avatar --voice --text', description: '用 profile 里的 ID 合成视频' },
|
|
289
|
+
],
|
|
290
|
+
notes: ['voice_status / avatar_status 独立(允许只训其中一个)'],
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAkB5C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAkB5C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAgQpD"}
|
package/dist/commands/video.js
CHANGED
|
@@ -11,11 +11,11 @@ export function registerVideoCommand(program) {
|
|
|
11
11
|
const cmd = program
|
|
12
12
|
.command('video')
|
|
13
13
|
.description('生成视频(文生视频 / 图生视频)')
|
|
14
|
-
.argument('[image]', '
|
|
14
|
+
.argument('[image]', '输入图像路径(默认 dashscope 图生视频必需;纯文生视频暂不可用)')
|
|
15
15
|
.option('-p, --prompt <text>', '视频描述提示词', '')
|
|
16
16
|
.option('-n, --negative <text>', '负向提示词(DashScope)', '')
|
|
17
17
|
.option('-r, --resolution <res>', '分辨率: 720P | 1080P(DashScope)', '1080P')
|
|
18
|
-
.option('-d, --duration <seconds>', '视频时长:
|
|
18
|
+
.option('-d, --duration <seconds>', '视频时长: 5|10 秒(dashscope / piapi 同样上限)', '5')
|
|
19
19
|
.option('--prompt-extend', '启用智能改写 prompt(DashScope,默认开启)')
|
|
20
20
|
.option('--no-prompt-extend', '禁用智能改写 prompt')
|
|
21
21
|
.option('--audio', '启用自动配音(DashScope,默认开启)')
|
|
@@ -24,7 +24,9 @@ export function registerVideoCommand(program) {
|
|
|
24
24
|
.option('--shot-type <type>', '镜头类型: single | multi(DashScope)', 'single')
|
|
25
25
|
.option('--watermark', '添加 AI 生成水印(DashScope)')
|
|
26
26
|
.option('--seed <number>', '随机种子')
|
|
27
|
-
|
|
27
|
+
// No default — let the backend pick the default provider so this CLI
|
|
28
|
+
// stays version-agnostic. Pass --provider explicitly only to override.
|
|
29
|
+
.addOption(new Option('--provider <name>', '视频生成供应商(不传则由后端选默认)').choices(['kie', 'dashscope', 'piapi', 'heygen']))
|
|
28
30
|
.option('--avatar <id>', 'HeyGen avatar ID')
|
|
29
31
|
.option('--voice <id>', 'HeyGen voice ID')
|
|
30
32
|
.option('--text <text>', 'HeyGen 数字人说话文本')
|
|
@@ -35,15 +37,15 @@ export function registerVideoCommand(program) {
|
|
|
35
37
|
.option('--bg-image <url>', 'HeyGen 背景图 URL')
|
|
36
38
|
.option('--caption', '启用字幕(HeyGen)')
|
|
37
39
|
.option('--title <title>', '视频标题(HeyGen)')
|
|
38
|
-
.option('--aspect-ratio <ratio>', '
|
|
39
|
-
.option('--size <size>', 'GrsAI 视频尺寸')
|
|
40
|
+
.option('--aspect-ratio <ratio>', '宽高比: 16:9 | 9:16 | 1:1 等(PiAPI / DashScope)')
|
|
40
41
|
.option('-o, --output <dir>', '输出目录', '')
|
|
41
42
|
.action(async (image, options) => {
|
|
42
43
|
const pretty = isPrettyMode(options);
|
|
43
44
|
try {
|
|
44
45
|
const duration = parseInt(options.duration);
|
|
45
46
|
const resolution = options.resolution;
|
|
46
|
-
|
|
47
|
+
// provider is undefined when --provider not passed — let backend decide.
|
|
48
|
+
const provider = options.provider;
|
|
47
49
|
// HeyGen 数字人视频:独立参数路径
|
|
48
50
|
if (provider === 'heygen') {
|
|
49
51
|
if (!options.avatar) {
|
|
@@ -141,7 +143,7 @@ export function registerVideoCommand(program) {
|
|
|
141
143
|
}
|
|
142
144
|
// CLI 层快速校验
|
|
143
145
|
if (provider === 'dashscope' && !imageBase64) {
|
|
144
|
-
outputError('MISSING_IMAGE', '
|
|
146
|
+
outputError('MISSING_IMAGE', '该供应商视频生成需要输入图像', options);
|
|
145
147
|
return;
|
|
146
148
|
}
|
|
147
149
|
if (!options.prompt && !imageBase64) {
|
|
@@ -161,9 +163,9 @@ export function registerVideoCommand(program) {
|
|
|
161
163
|
shot_type: options.shotType,
|
|
162
164
|
watermark: options.watermark || false,
|
|
163
165
|
seed: options.seed ? parseInt(options.seed) : undefined,
|
|
164
|
-
provider
|
|
166
|
+
// Only include provider when explicitly set, so backend default wins.
|
|
167
|
+
...(provider ? { provider } : {}),
|
|
165
168
|
aspectRatio: options.aspectRatio,
|
|
166
|
-
size: options.size,
|
|
167
169
|
};
|
|
168
170
|
const client = new GenerationApiClient();
|
|
169
171
|
const defaultDir = getConfigValue('outputDir') || './gen-output';
|
|
@@ -223,25 +225,19 @@ export function registerVideoCommand(program) {
|
|
|
223
225
|
});
|
|
224
226
|
addEnhancedHelp(cmd, {
|
|
225
227
|
examples: [
|
|
226
|
-
'#
|
|
227
|
-
'$ gen video --prompt "a cat walking on the beach"',
|
|
228
|
-
'',
|
|
229
|
-
'# 图生视频(GrsAI Sora2)',
|
|
228
|
+
'# 图生视频(默认 dashscope,需要输入图像)',
|
|
230
229
|
'$ gen video cat.png --prompt "cat walking"',
|
|
231
230
|
'',
|
|
232
|
-
'#
|
|
233
|
-
'$ gen video --
|
|
234
|
-
'',
|
|
235
|
-
'# 使用 DashScope Wan2.6(需要输入图像)',
|
|
236
|
-
'$ gen video cat.png --prompt "cat walking" --provider dashscope',
|
|
231
|
+
'# 高清长视频',
|
|
232
|
+
'$ gen video cat.png --duration 10 --resolution 1080P',
|
|
237
233
|
'',
|
|
238
|
-
'#
|
|
239
|
-
'$ gen video cat.png --
|
|
234
|
+
'# 指定宽高比',
|
|
235
|
+
'$ gen video cat.png --prompt "panning shot" --aspect-ratio 16:9',
|
|
240
236
|
'',
|
|
241
|
-
'# HeyGen
|
|
237
|
+
'# 数字人口播(HeyGen)',
|
|
242
238
|
'$ gen video --provider heygen --avatar <avatar_id> --voice <voice_id> --text "Hello world"',
|
|
243
239
|
'',
|
|
244
|
-
'#
|
|
240
|
+
'# 数字人带情感和背景色',
|
|
245
241
|
'$ gen video --provider heygen --avatar <id> --voice <id> --text "Hi" --voice-emotion Friendly --bg-color "#1a1a2e"',
|
|
246
242
|
],
|
|
247
243
|
outputJson: `{
|
|
@@ -257,9 +253,9 @@ export function registerVideoCommand(program) {
|
|
|
257
253
|
{ command: 'image <prompt>', description: '生成图像' },
|
|
258
254
|
],
|
|
259
255
|
notes: [
|
|
260
|
-
'
|
|
261
|
-
'
|
|
262
|
-
'
|
|
256
|
+
'默认 dashscope(仅图生视频,需要输入图像;自动配音默认开启)',
|
|
257
|
+
'`--provider piapi` 文生 / 图生都支持,但当前账户余额不足暂时不可用,恢复后可切回',
|
|
258
|
+
'`--provider heygen` 生成数字人口播视频(需要 avatar_id + voice_id + text)',
|
|
263
259
|
'需要 Optima 账号(~/.optima/token.json 或 OPTIMA_TOKEN)',
|
|
264
260
|
'视频生成需要 1-5 分钟',
|
|
265
261
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,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,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAElB,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,iBAAiB,GAClB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,GAAG,GAAG,OAAO;SAChB,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,mBAAmB,CAAC;SAChC,QAAQ,CAAC,SAAS,EAAE
|
|
1
|
+
{"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* `gen voice clone <audio-file> --external-id <id>` — train a HeyGen instant voice clone
|
|
4
|
+
* from a local audio file. CLI handles the asset upload + submit + poll, then prints voice_id.
|
|
5
|
+
*
|
|
6
|
+
* Phase 2 doctor-avatar feature. See spec §13 in optima-doctor-avatar repo.
|
|
7
|
+
*/
|
|
8
|
+
export declare function registerVoiceCommand(program: Command): void;
|
|
9
|
+
//# sourceMappingURL=voice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../src/commands/voice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA+GpD"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { success, info } from '../utils/logger.js';
|
|
5
|
+
import { outputSuccess, outputError, isPrettyMode } from '../utils/output.js';
|
|
6
|
+
import { addEnhancedHelp } from '../utils/helpText.js';
|
|
7
|
+
import { GenerationApiClient, GenerationApiError } from '../services/generation-api.js';
|
|
8
|
+
/**
|
|
9
|
+
* `gen voice clone <audio-file> --external-id <id>` — train a HeyGen instant voice clone
|
|
10
|
+
* from a local audio file. CLI handles the asset upload + submit + poll, then prints voice_id.
|
|
11
|
+
*
|
|
12
|
+
* Phase 2 doctor-avatar feature. See spec §13 in optima-doctor-avatar repo.
|
|
13
|
+
*/
|
|
14
|
+
export function registerVoiceCommand(program) {
|
|
15
|
+
const voice = program.command('voice').description('医生 voice clone 相关命令(Phase 2)');
|
|
16
|
+
const cloneCmd = voice
|
|
17
|
+
.command('clone')
|
|
18
|
+
.description('用本地音频文件训练 HeyGen voice clone,产出 voice_id')
|
|
19
|
+
.argument('<audio-file>', '音频文件路径(.wav / .mp3 等,30-90s 推荐)')
|
|
20
|
+
.requiredOption('--external-id <id>', '业务方医生标识(写入 doctor_avatar_profiles)')
|
|
21
|
+
.option('--name <name>', 'HeyGen 侧 voice name(默认 doctor-voice)')
|
|
22
|
+
.action(async (audioFile, options) => {
|
|
23
|
+
const pretty = isPrettyMode(options);
|
|
24
|
+
try {
|
|
25
|
+
const audioPath = path.resolve(audioFile);
|
|
26
|
+
if (!fs.existsSync(audioPath)) {
|
|
27
|
+
outputError('AUDIO_NOT_FOUND', `音频文件不存在: ${audioPath}`, options);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const client = new GenerationApiClient();
|
|
31
|
+
// Step 1: upload audio asset
|
|
32
|
+
const upSpinner = pretty ? ora('上传音频到 HeyGen 资产存储...').start() : null;
|
|
33
|
+
const asset = await client.uploadHeyGenAsset(audioPath);
|
|
34
|
+
if (pretty)
|
|
35
|
+
upSpinner.succeed(`音频已上传 (asset_id=${asset.asset_id}, ${(asset.size_bytes / 1024).toFixed(1)} KB)`);
|
|
36
|
+
// Step 2: submit voice-clone task
|
|
37
|
+
const trainSpinner = pretty ? ora('提交 voice clone 训练任务...').start() : null;
|
|
38
|
+
const result = await client.submitAndPoll('voice-clone', {
|
|
39
|
+
audio_asset_id: asset.asset_id,
|
|
40
|
+
external_id: options.externalId,
|
|
41
|
+
voice_name: options.name,
|
|
42
|
+
}, {
|
|
43
|
+
timeout: 900000, // 15 min — voice clone usually 30s-2min but allow buffer
|
|
44
|
+
onProgress: (status) => {
|
|
45
|
+
if (pretty)
|
|
46
|
+
trainSpinner.text = `voice clone 训练中 (${status})...`;
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
if (result.status === 'completed') {
|
|
50
|
+
const voiceId = result.result_meta?.voice_id;
|
|
51
|
+
if (pretty) {
|
|
52
|
+
trainSpinner.succeed('voice clone 完成!');
|
|
53
|
+
success(`voice_id: ${voiceId}`);
|
|
54
|
+
info(`task_id: ${result.task_id}`);
|
|
55
|
+
info(`external_id: ${options.externalId}`);
|
|
56
|
+
info(`使用: gen doctor profile ${options.externalId} 查看完整 profile`);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
outputSuccess({
|
|
60
|
+
task_id: result.task_id,
|
|
61
|
+
status: result.status,
|
|
62
|
+
voice_id: voiceId,
|
|
63
|
+
external_id: options.externalId,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
if (pretty) {
|
|
69
|
+
trainSpinner.info(`任务状态: ${result.status}`);
|
|
70
|
+
if (result.error_message)
|
|
71
|
+
info(`错误: ${result.error_message}`);
|
|
72
|
+
info(`使用 'gen task get ${result.task_id}' 查看最新状态`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
outputSuccess({
|
|
76
|
+
task_id: result.task_id,
|
|
77
|
+
status: result.status,
|
|
78
|
+
error_code: result.error_code ?? null,
|
|
79
|
+
retryable: result.retryable ?? false,
|
|
80
|
+
error_message: result.error_message,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
if (err instanceof GenerationApiError) {
|
|
87
|
+
outputError(err.code, err.message, options);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
outputError('VOICE_CLONE_FAILED', `voice clone 失败: ${err}`, options);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
addEnhancedHelp(cloneCmd, {
|
|
95
|
+
examples: [
|
|
96
|
+
'# 训练医生 voice clone',
|
|
97
|
+
'$ gen voice clone ./doctor-audio.wav --external-id doc-123',
|
|
98
|
+
'',
|
|
99
|
+
'# 自定义 voice name',
|
|
100
|
+
'$ gen voice clone ./audio.wav --external-id doc-123 --name "Dr. Wang voice"',
|
|
101
|
+
],
|
|
102
|
+
outputJson: `{
|
|
103
|
+
"success": true,
|
|
104
|
+
"data": {
|
|
105
|
+
"task_id": "task-uuid",
|
|
106
|
+
"status": "completed",
|
|
107
|
+
"voice_id": "f7a8ea9f...",
|
|
108
|
+
"external_id": "doc-123"
|
|
109
|
+
}
|
|
110
|
+
}`,
|
|
111
|
+
relatedCommands: [
|
|
112
|
+
{ command: 'avatar train <video-file> --external-id <id>', description: '训练 avatar' },
|
|
113
|
+
{ command: 'doctor onboard <audio> <video> --external-id <id>', description: '一次同时训 voice + avatar' },
|
|
114
|
+
{ command: 'doctor profile <external-id>', description: '查看医生 profile' },
|
|
115
|
+
],
|
|
116
|
+
notes: [
|
|
117
|
+
'推荐音频时长 30-90 秒,清晰人声(单声道,降噪后)',
|
|
118
|
+
'训练时长通常 30 秒到 2 分钟',
|
|
119
|
+
'完成后 voice_id 会持久化到 doctor_avatar_profiles 表,用 external_id 查询',
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=voice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.js","sourceRoot":"","sources":["../../src/commands/voice.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,9 @@ import { registerAsrCommand } from './commands/asr.js';
|
|
|
12
12
|
import { registerTryonCommand } from './commands/tryon.js';
|
|
13
13
|
import { registerTaskCommand } from './commands/task.js';
|
|
14
14
|
import { registerConfigCommand } from './commands/config.js';
|
|
15
|
+
import { registerVoiceCommand } from './commands/voice.js';
|
|
16
|
+
import { registerAvatarCommand } from './commands/avatar.js';
|
|
17
|
+
import { registerDoctorCommand } from './commands/doctor.js';
|
|
15
18
|
const __filename = fileURLToPath(import.meta.url);
|
|
16
19
|
const __dirname = dirname(__filename);
|
|
17
20
|
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
|
|
@@ -52,6 +55,10 @@ registerVideoTranslateCommand(program);
|
|
|
52
55
|
registerTtsCommand(program);
|
|
53
56
|
registerAsrCommand(program);
|
|
54
57
|
registerTryonCommand(program);
|
|
58
|
+
// Phase 2 doctor-avatar
|
|
59
|
+
registerVoiceCommand(program);
|
|
60
|
+
registerAvatarCommand(program);
|
|
61
|
+
registerDoctorCommand(program);
|
|
55
62
|
// 任务管理
|
|
56
63
|
registerTaskCommand(program);
|
|
57
64
|
// 配置
|