@optima-chat/comfy-cli 0.8.0 → 0.9.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.
@@ -35,7 +35,10 @@
35
35
  "Bash(git branch:*)",
36
36
  "Bash(gh run view:*)",
37
37
  "WebFetch(domain:code.claude.com)",
38
- "Bash(ssh:*)"
38
+ "Bash(ssh:*)",
39
+ "Bash(wc:*)",
40
+ "WebFetch(domain:modelstudio.console.alibabacloud.com)",
41
+ "WebFetch(domain:help.aliyun.com)"
39
42
  ],
40
43
  "deny": [],
41
44
  "ask": []
@@ -44,4 +44,54 @@ export interface ImageBackend {
44
44
  */
45
45
  getStatus(id: string): Promise<ImageResult>;
46
46
  }
47
+ /**
48
+ * 视频生成参数
49
+ */
50
+ export interface VideoParams {
51
+ inputImage: string;
52
+ prompt?: string;
53
+ negativePrompt?: string;
54
+ resolution?: '720P' | '1080P';
55
+ duration?: 5 | 10 | 15;
56
+ seed?: number;
57
+ wait?: boolean;
58
+ promptExtend?: boolean;
59
+ audio?: boolean;
60
+ audioUrl?: string;
61
+ shotType?: 'single' | 'multi';
62
+ watermark?: boolean;
63
+ }
64
+ /**
65
+ * 视频生成结果
66
+ */
67
+ export interface VideoResult {
68
+ id: string;
69
+ backend: 'dashscope' | 'comfyui';
70
+ status: 'pending' | 'processing' | 'completed' | 'failed';
71
+ output?: string;
72
+ outputUrl?: string;
73
+ duration?: number;
74
+ resolution?: string;
75
+ seed?: number;
76
+ durationMs?: number;
77
+ error?: string;
78
+ }
79
+ /**
80
+ * 视频后端接口
81
+ */
82
+ export interface VideoBackend {
83
+ readonly name: 'dashscope' | 'comfyui';
84
+ /**
85
+ * 检查后端是否可用
86
+ */
87
+ isAvailable(): boolean;
88
+ /**
89
+ * 生成视频
90
+ */
91
+ generate(params: VideoParams): Promise<VideoResult>;
92
+ /**
93
+ * 获取任务状态
94
+ */
95
+ getStatus(id: string): Promise<VideoResult>;
96
+ }
47
97
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/backends/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,KAAK,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;IAEjC;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEpD;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC7C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/backends/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { VideoBackend, VideoParams, VideoResult } from './types.js';
2
+ export declare class DashScopeVideoBackend implements VideoBackend {
3
+ readonly name: "dashscope";
4
+ private client;
5
+ constructor(apiKey: string);
6
+ isAvailable(): boolean;
7
+ generate(params: VideoParams): Promise<VideoResult>;
8
+ getStatus(id: string): Promise<VideoResult>;
9
+ }
10
+ //# sourceMappingURL=video-dashscope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-dashscope.d.ts","sourceRoot":"","sources":["../../src/backends/video-dashscope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAIzE,qBAAa,qBAAsB,YAAW,YAAY;IACxD,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAU;IACrC,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,EAAE,MAAM;IAI1B,WAAW,IAAI,OAAO;IAIhB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAqEnD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAsBlD"}
@@ -0,0 +1,94 @@
1
+ import { DashScopeClient } from '../services/dashscope-api.js';
2
+ import { getConfig } from '../services/config.js';
3
+ export class DashScopeVideoBackend {
4
+ name = 'dashscope';
5
+ client;
6
+ constructor(apiKey) {
7
+ this.client = new DashScopeClient(apiKey);
8
+ }
9
+ isAvailable() {
10
+ return true;
11
+ }
12
+ async generate(params) {
13
+ const startTime = Date.now();
14
+ const cfg = getConfig();
15
+ // 1. 处理输入图像(转为 base64 或直接使用 URL)
16
+ let imgUrl = params.inputImage;
17
+ if (!imgUrl.startsWith('http') && !imgUrl.startsWith('data:')) {
18
+ imgUrl = await this.client.imageToBase64(params.inputImage);
19
+ }
20
+ // 2. 构建请求参数,合并配置默认值
21
+ const submitParams = {
22
+ prompt: params.prompt,
23
+ negativePrompt: params.negativePrompt,
24
+ imgUrl,
25
+ audioUrl: params.audioUrl,
26
+ resolution: params.resolution || cfg.dashscope?.resolution || '1080P',
27
+ duration: params.duration || cfg.dashscope?.duration || 5,
28
+ promptExtend: params.promptExtend ?? cfg.dashscope?.promptExtend ?? true,
29
+ audio: params.audio ?? cfg.dashscope?.audio ?? true,
30
+ shotType: params.shotType || cfg.dashscope?.shotType || 'single',
31
+ watermark: params.watermark ?? false,
32
+ seed: params.seed,
33
+ };
34
+ // 3. 提交任务
35
+ const submitResult = await this.client.submit(submitParams);
36
+ const taskId = submitResult.output.task_id;
37
+ // 4. 如果不等待,直接返回
38
+ if (params.wait === false) {
39
+ return {
40
+ id: taskId,
41
+ backend: 'dashscope',
42
+ status: 'pending',
43
+ resolution: submitParams.resolution,
44
+ duration: submitParams.duration,
45
+ };
46
+ }
47
+ // 5. 轮询等待结果
48
+ const pollResult = await this.client.poll(taskId, {
49
+ interval: 15000,
50
+ timeout: 600000,
51
+ });
52
+ // 6. 下载视频到本地
53
+ const outputDir = cfg.outputDir || './comfy-output';
54
+ const filename = `dashscope_${taskId}.mp4`;
55
+ let localPath;
56
+ if (pollResult.output.video_url) {
57
+ localPath = await this.client.downloadVideo(pollResult.output.video_url, outputDir, filename);
58
+ }
59
+ const durationMs = Date.now() - startTime;
60
+ return {
61
+ id: taskId,
62
+ backend: 'dashscope',
63
+ status: 'completed',
64
+ output: localPath,
65
+ outputUrl: pollResult.output.video_url,
66
+ duration: pollResult.usage?.duration,
67
+ resolution: submitParams.resolution,
68
+ durationMs,
69
+ };
70
+ }
71
+ async getStatus(id) {
72
+ const result = await this.client.getResult(id);
73
+ const status = result.output.task_status;
74
+ let videoStatus = 'pending';
75
+ if (status === 'SUCCEEDED') {
76
+ videoStatus = 'completed';
77
+ }
78
+ else if (status === 'FAILED' || status === 'CANCELED' || status === 'UNKNOWN') {
79
+ videoStatus = 'failed';
80
+ }
81
+ else if (status === 'RUNNING') {
82
+ videoStatus = 'processing';
83
+ }
84
+ return {
85
+ id,
86
+ backend: 'dashscope',
87
+ status: videoStatus,
88
+ outputUrl: result.output.video_url,
89
+ duration: result.usage?.duration,
90
+ error: videoStatus === 'failed' ? status : undefined,
91
+ };
92
+ }
93
+ }
94
+ //# sourceMappingURL=video-dashscope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-dashscope.js","sourceRoot":"","sources":["../../src/backends/video-dashscope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { VideoBackend } from './types.js';
2
+ export type VideoBackendType = 'auto' | 'dashscope' | 'comfyui';
3
+ export { VideoBackend, VideoParams, VideoResult } from './types.js';
4
+ export { DashScopeVideoBackend } from './video-dashscope.js';
5
+ /**
6
+ * 获取 DashScope API Key(优先环境变量,其次配置文件)
7
+ */
8
+ export declare function getDashScopeApiKey(): string | undefined;
9
+ /**
10
+ * 获取视频生成后端
11
+ *
12
+ * - auto: 有 DashScope API Key 则用 DashScope,否则用 ComfyUI
13
+ * - dashscope: 强制使用 DashScope(需要 API Key)
14
+ * - comfyui: 强制使用 ComfyUI
15
+ *
16
+ * API Key 优先级: 环境变量 DASHSCOPE_API_KEY > 配置文件 dashscope.apiKey
17
+ */
18
+ export declare function getVideoBackend(type?: VideoBackendType): VideoBackend;
19
+ /**
20
+ * 获取当前会使用的视频后端名称
21
+ */
22
+ export declare function getCurrentVideoBackendName(type?: VideoBackendType): 'dashscope' | 'comfyui';
23
+ //# sourceMappingURL=video-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-index.d.ts","sourceRoot":"","sources":["../../src/backends/video-index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAEhE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAEvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG,YAAY,CAyBrE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG,WAAW,GAAG,SAAS,CAe3F"}
@@ -0,0 +1,57 @@
1
+ import { getConfig } from '../services/config.js';
2
+ import { DashScopeVideoBackend } from './video-dashscope.js';
3
+ export { DashScopeVideoBackend } from './video-dashscope.js';
4
+ /**
5
+ * 获取 DashScope API Key(优先环境变量,其次配置文件)
6
+ */
7
+ export function getDashScopeApiKey() {
8
+ return process.env.DASHSCOPE_API_KEY || getConfig().dashscope?.apiKey;
9
+ }
10
+ /**
11
+ * 获取视频生成后端
12
+ *
13
+ * - auto: 有 DashScope API Key 则用 DashScope,否则用 ComfyUI
14
+ * - dashscope: 强制使用 DashScope(需要 API Key)
15
+ * - comfyui: 强制使用 ComfyUI
16
+ *
17
+ * API Key 优先级: 环境变量 DASHSCOPE_API_KEY > 配置文件 dashscope.apiKey
18
+ */
19
+ export function getVideoBackend(type) {
20
+ const cfg = getConfig();
21
+ const backendType = type || cfg.preferVideoBackend || 'auto';
22
+ // 强制使用 DashScope
23
+ if (backendType === 'dashscope') {
24
+ const apiKey = getDashScopeApiKey();
25
+ if (!apiKey) {
26
+ throw new Error('DashScope API key not configured. Set DASHSCOPE_API_KEY env or run: comfy config set dashscope.apiKey <key>');
27
+ }
28
+ return new DashScopeVideoBackend(apiKey);
29
+ }
30
+ // 强制使用 ComfyUI(返回 null,由调用方处理)
31
+ if (backendType === 'comfyui') {
32
+ return null; // ComfyUI 视频后端由 video.ts 原有逻辑处理
33
+ }
34
+ // 自动选择:优先 DashScope
35
+ const apiKey = getDashScopeApiKey();
36
+ if (apiKey) {
37
+ return new DashScopeVideoBackend(apiKey);
38
+ }
39
+ return null; // 回退到 ComfyUI
40
+ }
41
+ /**
42
+ * 获取当前会使用的视频后端名称
43
+ */
44
+ export function getCurrentVideoBackendName(type) {
45
+ const cfg = getConfig();
46
+ const backendType = type || cfg.preferVideoBackend || 'auto';
47
+ if (backendType === 'dashscope') {
48
+ return 'dashscope';
49
+ }
50
+ if (backendType === 'comfyui') {
51
+ return 'comfyui';
52
+ }
53
+ // auto
54
+ const apiKey = getDashScopeApiKey();
55
+ return apiKey ? 'dashscope' : 'comfyui';
56
+ }
57
+ //# sourceMappingURL=video-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-index.js","sourceRoot":"","sources":["../../src/backends/video-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAM7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;AACxE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,IAAuB;IACrD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,IAAI,GAAG,CAAC,kBAAkB,IAAI,MAAM,CAAC;IAE7D,iBAAiB;IACjB,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,6GAA6G,CAAC,CAAC;QACjI,CAAC;QACD,OAAO,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,+BAA+B;IAC/B,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAW,CAAC,CAAC,gCAAgC;IACtD,CAAC;IAED,oBAAoB;IACpB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,IAAW,CAAC,CAAC,cAAc;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAuB;IAChE,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,IAAI,GAAG,CAAC,kBAAkB,IAAI,MAAM,CAAC;IAE7D,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;QAChC,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;IACP,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA2KpD"}
1
+ {"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA+FpD"}
@@ -7,19 +7,35 @@ import { success, info } from '../utils/logger.js';
7
7
  import { outputSuccess, outputError, isPrettyMode } from '../utils/output.js';
8
8
  import { addEnhancedHelp } from '../utils/helpText.js';
9
9
  import { monitorProgress } from '../services/websocket.js';
10
+ import { getVideoBackend, getCurrentVideoBackendName } from '../backends/video-index.js';
10
11
  export function registerVideoCommand(program) {
11
12
  const cmd = program
12
13
  .command('video')
13
- .description('生成视频(图生视频)- 使用 Wan2.1 模型将静态图像转换为动态视频')
14
+ .description('生成视频(图生视频)- 支持 DashScope (wan2.6) 和 ComfyUI (wan2.1) 后端')
14
15
  .argument('<image>', '输入图像路径')
15
- .option('-p, --prompt <text>', '运动描述提示词(如 "camera zoom in")', '')
16
+ .option('-p, --prompt <text>', '运动描述提示词', '')
16
17
  .option('-n, --negative <text>', '负向提示词', '')
17
- .option('-o, --output <dir>', '输出目录 (默认: ./output)', './output')
18
- .option('--width <number>', '视频宽度 (默认: 512)', '512')
19
- .option('--height <number>', '视频高度 (默认: 512)', '512')
18
+ .option('-b, --backend <type>', '后端选择: auto | dashscope | comfyui', 'auto')
19
+ // DashScope 选项
20
+ .option('-r, --resolution <res>', '分辨率: 720P | 1080P (DashScope)', '1080P')
21
+ .option('-d, --duration <seconds>', '视频时长: 5 | 10 | 15 秒 (DashScope)', '5')
22
+ .option('--prompt-extend', '启用智能改写 prompt (DashScope, 默认开启)')
23
+ .option('--no-prompt-extend', '禁用智能改写 prompt')
24
+ .option('--audio', '启用自动配音 (DashScope, 默认开启)')
25
+ .option('--no-audio', '禁用自动配音')
26
+ .option('--audio-url <url>', '自定义音频 URL (DashScope)')
27
+ .option('--shot-type <type>', '镜头类型: single | multi (DashScope)', 'single')
28
+ .option('--watermark', '添加 AI 生成水印 (DashScope)')
29
+ .option('--seed <number>', '随机种子')
30
+ // ComfyUI 选项
31
+ .option('-o, --output <dir>', '输出目录 (ComfyUI)', './output')
32
+ .option('--width <number>', '视频宽度 (ComfyUI)', '512')
33
+ .option('--height <number>', '视频高度 (ComfyUI)', '512')
20
34
  .option('--no-wait', '提交任务后立即返回,不等待生成完成')
21
35
  .action(async (image, options) => {
22
36
  const pretty = isPrettyMode(options);
37
+ const backendType = options.backend;
38
+ const actualBackend = getCurrentVideoBackendName(backendType);
23
39
  try {
24
40
  // 检查图像文件是否存在
25
41
  const imagePath = path.resolve(image);
@@ -27,98 +43,14 @@ export function registerVideoCommand(program) {
27
43
  outputError('IMAGE_NOT_FOUND', `图像文件不存在: ${imagePath}`, options);
28
44
  }
29
45
  if (pretty) {
30
- info(`正在生成视频: "${path.basename(image)}"`);
46
+ info(`正在生成视频: "${path.basename(image)}" (后端: ${actualBackend})`);
31
47
  }
32
- // 先上传图像
33
- const client = new ComfyAPIClient();
34
- let uploadResult;
35
- if (pretty) {
36
- const uploadSpinner = ora('正在上传图像...').start();
37
- try {
38
- const imageBuffer = fs.readFileSync(imagePath);
39
- uploadResult = await client.uploadImage(imageBuffer, path.basename(imagePath));
40
- uploadSpinner.succeed('图像上传完成');
41
- }
42
- catch (err) {
43
- uploadSpinner.fail('图像上传失败');
44
- throw err;
45
- }
46
- }
47
- else {
48
- const imageBuffer = fs.readFileSync(imagePath);
49
- uploadResult = await client.uploadImage(imageBuffer, path.basename(imagePath));
50
- }
51
- // 加载内置 workflow
52
- const workflowPath = getBuiltinWorkflowPath('wan_image_to_video.json');
53
- const workflow = loadWorkflow(workflowPath);
54
- // 准备参数
55
- const params = {
56
- input_image: uploadResult.name,
57
- prompt: options.prompt,
58
- negative_prompt: options.negative || '色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走',
59
- width: parseInt(options.width),
60
- height: parseInt(options.height),
61
- frames: 33, // 固定最佳值
62
- fps: 8, // 固定最佳值
63
- steps: 20, // 固定最佳值
64
- cfg_scale: 6.0, // 固定最佳值
65
- seed: Math.floor(Math.random() * 1000000), // 随机种子
66
- sampler: 'uni_pc',
67
- scheduler: 'simple',
68
- unet_model: 'Wan2.1/wan2.1_i2v_720p_14B_fp8_scaled.safetensors',
69
- clip_model: 'umt5_xxl_fp8_e4m3fn_scaled.safetensors',
70
- clip_vision_model: 'clip_vision_h.safetensors',
71
- vae_model: 'wan_2.1_vae.safetensors',
72
- shift: 8.0,
73
- filename_prefix: 'comfy-cli-video',
74
- };
75
- // 替换变量
76
- const processedWorkflow = replaceVariables(workflow, params);
77
- // 提交到 ComfyUI
78
- const result = await client.submitWorkflow(processedWorkflow);
79
- if (pretty) {
80
- success(`视频生成任务已提交`);
81
- info(`Prompt ID: ${result.prompt_id}`);
82
- info(`帧数: ${params.frames}, FPS: ${params.fps}, 时长: ${(params.frames / params.fps).toFixed(1)}秒`);
83
- // 默认等待完成,除非指定了 --no-wait
84
- if (options.wait !== false) {
85
- const spinner = ora('正在连接 WebSocket...').start();
86
- try {
87
- await monitorProgress(result.prompt_id, (current, total, message) => {
88
- if (total > 0) {
89
- const percent = Math.round((current / total) * 100);
90
- spinner.text = `生成中: ${percent}% (${current}/${total})`;
91
- spinner.render();
92
- }
93
- else {
94
- spinner.text = message;
95
- spinner.render();
96
- }
97
- }, () => {
98
- spinner.succeed('视频生成完成!');
99
- });
100
- info(`使用 'comfy download ${result.prompt_id}' 下载结果`);
101
- }
102
- catch (err) {
103
- spinner.fail(`进度监听失败: ${err?.message || err}`);
104
- info(`使用 'comfy download ${result.prompt_id}' 下载结果`);
105
- }
106
- }
107
- else {
108
- info(`使用 'comfy download ${result.prompt_id}' 下载结果`);
109
- }
48
+ // 根据后端选择不同的生成逻辑
49
+ if (actualBackend === 'dashscope') {
50
+ await generateWithDashScope(imagePath, options, pretty);
110
51
  }
111
52
  else {
112
- outputSuccess({
113
- prompt_id: result.prompt_id,
114
- image: path.basename(image),
115
- width: params.width,
116
- height: params.height,
117
- frames: params.frames,
118
- fps: params.fps,
119
- duration: parseFloat((params.frames / params.fps).toFixed(1)),
120
- status: options.wait !== false ? 'submitted_waiting' : 'submitted',
121
- });
53
+ await generateWithComfyUI(imagePath, options, pretty);
122
54
  }
123
55
  }
124
56
  catch (err) {
@@ -128,46 +60,200 @@ export function registerVideoCommand(program) {
128
60
  // Add enhanced help text
129
61
  addEnhancedHelp(cmd, {
130
62
  examples: [
131
- '# 基础用法:图像转视频',
132
- '$ comfy video landscape.png',
63
+ '# 自动选择后端(有 API Key 用 DashScope,否则用 ComfyUI)',
64
+ '$ comfy video cat.png --prompt "cat walking"',
133
65
  '',
134
- '# 添加运动提示词',
135
- '$ comfy video photo.jpg --prompt "camera zoom in"',
66
+ '# 使用 DashScope (wan2.6) - 云端 API',
67
+ '$ comfy video cat.png --backend dashscope --duration 10 --resolution 1080P',
136
68
  '',
137
- '# 指定视频尺寸',
138
- '$ comfy video image.png --width 720 --height 480',
69
+ '# 多镜头叙事模式',
70
+ '$ comfy video scene.png --backend dashscope --shot-type multi --duration 15',
139
71
  '',
140
- '# 不等待完成',
141
- '$ comfy video sunset.png --no-wait',
72
+ '# 禁用自动配音',
73
+ '$ comfy video cat.png --backend dashscope --no-audio',
74
+ '',
75
+ '# 使用 ComfyUI (wan2.1) - 本地服务',
76
+ '$ comfy video cat.png --backend comfyui --width 720 --height 480',
142
77
  '',
143
- '# Pretty 模式',
144
- '$ comfy video cat.png --prompt "cat walking" --pretty',
78
+ '# 不等待完成',
79
+ '$ comfy video cat.png --no-wait',
145
80
  ],
146
81
  outputJson: `{
147
82
  "success": true,
148
83
  "data": {
149
- "prompt_id": "abc-123-def",
150
- "image": "landscape.png",
151
- "width": 512,
152
- "height": 512,
153
- "frames": 33,
154
- "fps": 8,
155
- "duration": 4.1,
156
- "status": "submitted_waiting"
84
+ "id": "abc-123-def",
85
+ "backend": "dashscope",
86
+ "status": "completed",
87
+ "output": "./comfy-output/dashscope_abc123.mp4",
88
+ "duration": 5,
89
+ "resolution": "1080P"
157
90
  }
158
91
  }`,
159
92
  relatedCommands: [
160
- { command: 'download <prompt_id>', description: '下载生成的视频' },
93
+ { command: 'download <prompt_id>', description: '下载生成的视频 (ComfyUI)' },
161
94
  { command: 'generate <prompt>', description: '生成新图像' },
162
- { command: 'edit <image> <prompt>', description: '编辑现有图像' },
95
+ { command: 'config set dashscope.apiKey <key>', description: '设置 DashScope API Key' },
163
96
  ],
164
97
  notes: [
165
- '默认使用 Wan2.1 模型,生成 4.1 秒视频(33 @ 8 FPS)',
166
- '图像会先上传到 ComfyUI 服务器',
167
- '支持常见图像格式:PNG, JPG, JPEG',
168
- '建议图像尺寸为 512x512 以获得最佳效果',
169
- '视频生成时间较长,建议使用 --no-wait 立即返回',
98
+ 'DashScope 后端使用 wan2.6-i2v 模型,支持 720P/1080P,5/10/15 ',
99
+ 'ComfyUI 后端使用 wan2.1 模型,需要本地部署',
100
+ '设置 DASHSCOPE_API_KEY 环境变量或 comfy config set dashscope.apiKey 启用云端',
101
+ 'DashScope 视频 URL 24 小时后失效,会自动下载到本地',
170
102
  ],
171
103
  });
172
104
  }
105
+ /**
106
+ * 使用 DashScope 后端生成视频
107
+ */
108
+ async function generateWithDashScope(imagePath, options, pretty) {
109
+ const backend = getVideoBackend('dashscope');
110
+ const params = {
111
+ inputImage: imagePath,
112
+ prompt: options.prompt || undefined,
113
+ negativePrompt: options.negative || undefined,
114
+ resolution: options.resolution,
115
+ duration: parseInt(options.duration),
116
+ promptExtend: options.promptExtend,
117
+ audio: options.audio,
118
+ audioUrl: options.audioUrl,
119
+ shotType: options.shotType,
120
+ watermark: options.watermark || false,
121
+ seed: options.seed ? parseInt(options.seed) : undefined,
122
+ wait: options.wait !== false,
123
+ };
124
+ if (pretty) {
125
+ const spinner = ora('正在提交视频生成任务...').start();
126
+ try {
127
+ if (params.wait) {
128
+ spinner.text = '正在生成视频(预计 1-5 分钟)...';
129
+ }
130
+ const result = await backend.generate(params);
131
+ if (result.status === 'completed') {
132
+ spinner.succeed('视频生成完成!');
133
+ success(`输出文件: ${result.output}`);
134
+ info(`时长: ${result.duration}s, 分辨率: ${result.resolution}`);
135
+ info(`生成耗时: ${((result.durationMs || 0) / 1000).toFixed(1)}s`);
136
+ }
137
+ else {
138
+ spinner.succeed('任务已提交');
139
+ info(`任务 ID: ${result.id}`);
140
+ info(`状态: ${result.status}`);
141
+ }
142
+ }
143
+ catch (err) {
144
+ spinner.fail(`生成失败: ${err?.message || err}`);
145
+ throw err;
146
+ }
147
+ }
148
+ else {
149
+ const result = await backend.generate(params);
150
+ outputSuccess({
151
+ id: result.id,
152
+ backend: result.backend,
153
+ status: result.status,
154
+ output: result.output,
155
+ outputUrl: result.outputUrl,
156
+ duration: result.duration,
157
+ resolution: result.resolution,
158
+ durationMs: result.durationMs,
159
+ });
160
+ }
161
+ }
162
+ /**
163
+ * 使用 ComfyUI 后端生成视频(原有逻辑)
164
+ */
165
+ async function generateWithComfyUI(imagePath, options, pretty) {
166
+ // 先上传图像
167
+ const client = new ComfyAPIClient();
168
+ let uploadResult;
169
+ if (pretty) {
170
+ const uploadSpinner = ora('正在上传图像...').start();
171
+ try {
172
+ const imageBuffer = fs.readFileSync(imagePath);
173
+ uploadResult = await client.uploadImage(imageBuffer, path.basename(imagePath));
174
+ uploadSpinner.succeed('图像上传完成');
175
+ }
176
+ catch (err) {
177
+ uploadSpinner.fail('图像上传失败');
178
+ throw err;
179
+ }
180
+ }
181
+ else {
182
+ const imageBuffer = fs.readFileSync(imagePath);
183
+ uploadResult = await client.uploadImage(imageBuffer, path.basename(imagePath));
184
+ }
185
+ // 加载内置 workflow
186
+ const workflowPath = getBuiltinWorkflowPath('wan_image_to_video.json');
187
+ const workflow = loadWorkflow(workflowPath);
188
+ // 准备参数
189
+ const params = {
190
+ input_image: uploadResult.name,
191
+ prompt: options.prompt,
192
+ negative_prompt: options.negative || '色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走',
193
+ width: parseInt(options.width),
194
+ height: parseInt(options.height),
195
+ frames: 33,
196
+ fps: 8,
197
+ steps: 20,
198
+ cfg_scale: 6.0,
199
+ seed: options.seed ? parseInt(options.seed) : Math.floor(Math.random() * 1000000),
200
+ sampler: 'uni_pc',
201
+ scheduler: 'simple',
202
+ unet_model: 'Wan2.1/wan2.1_i2v_720p_14B_fp8_scaled.safetensors',
203
+ clip_model: 'umt5_xxl_fp8_e4m3fn_scaled.safetensors',
204
+ clip_vision_model: 'clip_vision_h.safetensors',
205
+ vae_model: 'wan_2.1_vae.safetensors',
206
+ shift: 8.0,
207
+ filename_prefix: 'comfy-cli-video',
208
+ };
209
+ // 替换变量
210
+ const processedWorkflow = replaceVariables(workflow, params);
211
+ // 提交到 ComfyUI
212
+ const result = await client.submitWorkflow(processedWorkflow);
213
+ if (pretty) {
214
+ success(`视频生成任务已提交`);
215
+ info(`Prompt ID: ${result.prompt_id}`);
216
+ info(`帧数: ${params.frames}, FPS: ${params.fps}, 时长: ${(params.frames / params.fps).toFixed(1)}秒`);
217
+ // 默认等待完成,除非指定了 --no-wait
218
+ if (options.wait !== false) {
219
+ const spinner = ora('正在连接 WebSocket...').start();
220
+ try {
221
+ await monitorProgress(result.prompt_id, (current, total, message) => {
222
+ if (total > 0) {
223
+ const percent = Math.round((current / total) * 100);
224
+ spinner.text = `生成中: ${percent}% (${current}/${total})`;
225
+ spinner.render();
226
+ }
227
+ else {
228
+ spinner.text = message;
229
+ spinner.render();
230
+ }
231
+ }, () => {
232
+ spinner.succeed('视频生成完成!');
233
+ });
234
+ info(`使用 'comfy download ${result.prompt_id}' 下载结果`);
235
+ }
236
+ catch (err) {
237
+ spinner.fail(`进度监听失败: ${err?.message || err}`);
238
+ info(`使用 'comfy download ${result.prompt_id}' 下载结果`);
239
+ }
240
+ }
241
+ else {
242
+ info(`使用 'comfy download ${result.prompt_id}' 下载结果`);
243
+ }
244
+ }
245
+ else {
246
+ outputSuccess({
247
+ id: result.prompt_id,
248
+ backend: 'comfyui',
249
+ image: path.basename(imagePath),
250
+ width: params.width,
251
+ height: params.height,
252
+ frames: params.frames,
253
+ fps: params.fps,
254
+ duration: parseFloat((params.frames / params.fps).toFixed(1)),
255
+ status: options.wait !== false ? 'submitted_waiting' : 'submitted',
256
+ });
257
+ }
258
+ }
173
259
  //# sourceMappingURL=video.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"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"}
@@ -4,13 +4,23 @@ export interface BFLConfig {
4
4
  safetyTolerance: number;
5
5
  outputFormat: 'jpeg' | 'png';
6
6
  }
7
+ export interface DashScopeConfig {
8
+ apiKey?: string;
9
+ resolution: '720P' | '1080P';
10
+ duration: 5 | 10 | 15;
11
+ promptExtend: boolean;
12
+ audio: boolean;
13
+ shotType: 'single' | 'multi';
14
+ }
7
15
  export interface ComfyConfig {
8
16
  server: string;
9
17
  timeout: number;
10
18
  autoConnect: boolean;
11
19
  outputDir: string;
12
20
  bfl: BFLConfig;
21
+ dashscope: DashScopeConfig;
13
22
  preferBackend: 'auto' | 'bfl' | 'comfyui';
23
+ preferVideoBackend: 'auto' | 'dashscope' | 'comfyui';
14
24
  }
15
25
  export declare const config: Conf<ComfyConfig>;
16
26
  export declare function getConfig(): ComfyConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,SAAS,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;CAC3C;AAcD,eAAO,MAAM,MAAM,mBAGjB,CAAC;AAEH,wBAAgB,SAAS,IAAI,WAAW,CAEvC;AAGD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAEvD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAE/C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAGD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAYrD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,SAAS,CAAC;IACf,SAAS,EAAE,eAAe,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAC1C,kBAAkB,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;CACtD;AAsBD,eAAO,MAAM,MAAM,mBAGjB,CAAC;AAEH,wBAAgB,SAAS,IAAI,WAAW,CAEvC;AAGD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAEvD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAE/C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAGD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAmBrD"}
@@ -8,7 +8,15 @@ const defaultConfig = {
8
8
  safetyTolerance: 2,
9
9
  outputFormat: 'png',
10
10
  },
11
+ dashscope: {
12
+ resolution: '1080P',
13
+ duration: 5,
14
+ promptExtend: true,
15
+ audio: true,
16
+ shotType: 'single',
17
+ },
11
18
  preferBackend: 'auto',
19
+ preferVideoBackend: 'auto',
12
20
  };
13
21
  export const config = new Conf({
14
22
  projectName: 'comfy-cli',
@@ -40,7 +48,14 @@ export function isValidConfigKey(key) {
40
48
  'bfl.apiKey',
41
49
  'bfl.safetyTolerance',
42
50
  'bfl.outputFormat',
51
+ 'dashscope.apiKey',
52
+ 'dashscope.resolution',
53
+ 'dashscope.duration',
54
+ 'dashscope.promptExtend',
55
+ 'dashscope.audio',
56
+ 'dashscope.shotType',
43
57
  'preferBackend',
58
+ 'preferVideoBackend',
44
59
  ];
45
60
  return validKeys.includes(key);
46
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAiBxB,MAAM,aAAa,GAAgB;IACjC,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,gBAAgB;IAC3B,GAAG,EAAE;QACH,eAAe,EAAE,CAAC;QAClB,YAAY,EAAE,KAAK;KACpB;IACD,aAAa,EAAE,MAAM;CACtB,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAc;IAC1C,WAAW,EAAE,WAAW;IACxB,QAAQ,EAAE,aAAa;CACxB,CAAC,CAAC;AAEH,MAAM,UAAU,SAAS;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,KAAU;IAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,CAAC,MAAM,CAAC,GAAwB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,YAAY;AACZ,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,SAAS,GAAG;QAChB,QAAQ;QACR,SAAS;QACT,aAAa;QACb,WAAW;QACX,YAAY;QACZ,qBAAqB;QACrB,kBAAkB;QAClB,eAAe;KAChB,CAAC;IACF,OAAO,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AA4BxB,MAAM,aAAa,GAAgB;IACjC,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,gBAAgB;IAC3B,GAAG,EAAE;QACH,eAAe,EAAE,CAAC;QAClB,YAAY,EAAE,KAAK;KACpB;IACD,SAAS,EAAE;QACT,UAAU,EAAE,OAAO;QACnB,QAAQ,EAAE,CAAC;QACX,YAAY,EAAE,IAAI;QAClB,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,QAAQ;KACnB;IACD,aAAa,EAAE,MAAM;IACrB,kBAAkB,EAAE,MAAM;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAc;IAC1C,WAAW,EAAE,WAAW;IACxB,QAAQ,EAAE,aAAa;CACxB,CAAC,CAAC;AAEH,MAAM,UAAU,SAAS;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,KAAU;IAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,CAAC,MAAM,CAAC,GAAwB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,YAAY;AACZ,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,SAAS,GAAG;QAChB,QAAQ;QACR,SAAS;QACT,aAAa;QACb,WAAW;QACX,YAAY;QACZ,qBAAqB;QACrB,kBAAkB;QAClB,kBAAkB;QAClB,sBAAsB;QACtB,oBAAoB;QACpB,wBAAwB;QACxB,iBAAiB;QACjB,oBAAoB;QACpB,eAAe;QACf,oBAAoB;KACrB,CAAC;IACF,OAAO,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,69 @@
1
+ export interface DashScopeSubmitParams {
2
+ prompt?: string;
3
+ negativePrompt?: string;
4
+ imgUrl: string;
5
+ audioUrl?: string;
6
+ resolution?: '720P' | '1080P';
7
+ duration?: 5 | 10 | 15;
8
+ promptExtend?: boolean;
9
+ audio?: boolean;
10
+ shotType?: 'single' | 'multi';
11
+ watermark?: boolean;
12
+ seed?: number;
13
+ }
14
+ export interface DashScopeSubmitResponse {
15
+ output: {
16
+ task_id: string;
17
+ task_status: string;
18
+ };
19
+ request_id: string;
20
+ }
21
+ export interface DashScopeTaskResult {
22
+ output: {
23
+ task_id: string;
24
+ task_status: 'PENDING' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'CANCELED' | 'UNKNOWN';
25
+ video_url?: string;
26
+ orig_prompt?: string;
27
+ actual_prompt?: string;
28
+ submit_time?: string;
29
+ end_time?: string;
30
+ };
31
+ usage?: {
32
+ duration?: number;
33
+ SR?: number;
34
+ video_count?: number;
35
+ };
36
+ request_id: string;
37
+ }
38
+ export interface PollOptions {
39
+ interval?: number;
40
+ timeout?: number;
41
+ onProgress?: (status: string) => void;
42
+ }
43
+ export declare class DashScopeClient {
44
+ private client;
45
+ private baseUrl;
46
+ constructor(apiKey: string);
47
+ /**
48
+ * 提交视频生成任务 (wan2.6-i2v)
49
+ */
50
+ submit(params: DashScopeSubmitParams): Promise<DashScopeSubmitResponse>;
51
+ /**
52
+ * 获取任务结果
53
+ */
54
+ getResult(taskId: string): Promise<DashScopeTaskResult>;
55
+ /**
56
+ * 轮询等待结果
57
+ */
58
+ poll(taskId: string, options?: PollOptions): Promise<DashScopeTaskResult>;
59
+ /**
60
+ * 将本地图像转换为 base64 data URL
61
+ */
62
+ imageToBase64(filePath: string): Promise<string>;
63
+ /**
64
+ * 下载视频到本地
65
+ */
66
+ downloadVideo(url: string, outputDir: string, filename?: string): Promise<string>;
67
+ private sleep;
68
+ }
69
+ //# sourceMappingURL=dashscope-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashscope-api.d.ts","sourceRoot":"","sources":["../../src/services/dashscope-api.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;QACrF,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAA2C;gBAE9C,MAAM,EAAE,MAAM;IAY1B;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAiC7E;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAW7D;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA6CnF;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAStD;;OAEG;IACG,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBvF,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,134 @@
1
+ import axios from 'axios';
2
+ import * as fs from 'fs/promises';
3
+ import * as path from 'path';
4
+ export class DashScopeClient {
5
+ client;
6
+ baseUrl = 'https://dashscope.aliyuncs.com/api/v1';
7
+ constructor(apiKey) {
8
+ this.client = axios.create({
9
+ baseURL: this.baseUrl,
10
+ headers: {
11
+ 'Authorization': `Bearer ${apiKey}`,
12
+ 'Content-Type': 'application/json',
13
+ 'X-DashScope-Async': 'enable',
14
+ },
15
+ timeout: 30000,
16
+ });
17
+ }
18
+ /**
19
+ * 提交视频生成任务 (wan2.6-i2v)
20
+ */
21
+ async submit(params) {
22
+ const requestBody = {
23
+ model: 'wan2.6-i2v',
24
+ input: {
25
+ prompt: params.prompt,
26
+ negative_prompt: params.negativePrompt,
27
+ img_url: params.imgUrl,
28
+ audio_url: params.audioUrl,
29
+ },
30
+ parameters: {
31
+ resolution: params.resolution || '1080P',
32
+ duration: params.duration || 5,
33
+ prompt_extend: params.promptExtend ?? true,
34
+ audio: params.audio ?? true,
35
+ shot_type: params.shotType || 'single',
36
+ watermark: params.watermark ?? false,
37
+ seed: params.seed,
38
+ },
39
+ };
40
+ // 移除 undefined 值
41
+ if (!requestBody.input.prompt)
42
+ delete requestBody.input.prompt;
43
+ if (!requestBody.input.negative_prompt)
44
+ delete requestBody.input.negative_prompt;
45
+ if (!requestBody.input.audio_url)
46
+ delete requestBody.input.audio_url;
47
+ if (requestBody.parameters.seed === undefined)
48
+ delete requestBody.parameters.seed;
49
+ const response = await this.client.post('/services/aigc/video-generation/video-synthesis', requestBody);
50
+ return response.data;
51
+ }
52
+ /**
53
+ * 获取任务结果
54
+ */
55
+ async getResult(taskId) {
56
+ // 查询任务不需要 X-DashScope-Async 头
57
+ const response = await axios.get(`${this.baseUrl}/tasks/${taskId}`, {
58
+ headers: {
59
+ 'Authorization': this.client.defaults.headers['Authorization'],
60
+ },
61
+ timeout: 30000,
62
+ });
63
+ return response.data;
64
+ }
65
+ /**
66
+ * 轮询等待结果
67
+ */
68
+ async poll(taskId, options = {}) {
69
+ const { interval = 15000, // DashScope 建议 15 秒轮询一次
70
+ timeout = 600000, // 10 分钟超时(视频生成较慢)
71
+ onProgress, } = options;
72
+ const startTime = Date.now();
73
+ while (true) {
74
+ // 检查超时
75
+ if (Date.now() - startTime > timeout) {
76
+ throw new Error('DashScope polling timeout exceeded');
77
+ }
78
+ // 获取状态
79
+ const result = await this.getResult(taskId);
80
+ const status = result.output.task_status;
81
+ // 通知进度
82
+ onProgress?.(status);
83
+ // 完成
84
+ if (status === 'SUCCEEDED') {
85
+ return result;
86
+ }
87
+ // 失败
88
+ if (status === 'FAILED') {
89
+ throw new Error('DashScope video generation failed');
90
+ }
91
+ if (status === 'CANCELED') {
92
+ throw new Error('DashScope task was canceled');
93
+ }
94
+ if (status === 'UNKNOWN') {
95
+ throw new Error('DashScope task status unknown');
96
+ }
97
+ // 等待后继续轮询
98
+ await this.sleep(interval);
99
+ }
100
+ }
101
+ /**
102
+ * 将本地图像转换为 base64 data URL
103
+ */
104
+ async imageToBase64(filePath) {
105
+ const absolutePath = path.resolve(filePath);
106
+ const buffer = await fs.readFile(absolutePath);
107
+ const base64 = buffer.toString('base64');
108
+ const ext = path.extname(filePath).toLowerCase();
109
+ const mimeType = ext === '.png' ? 'image/png' : 'image/jpeg';
110
+ return `data:${mimeType};base64,${base64}`;
111
+ }
112
+ /**
113
+ * 下载视频到本地
114
+ */
115
+ async downloadVideo(url, outputDir, filename) {
116
+ // 确保输出目录存在
117
+ await fs.mkdir(outputDir, { recursive: true });
118
+ // 下载视频
119
+ const response = await axios.get(url, {
120
+ responseType: 'arraybuffer',
121
+ timeout: 300000, // 5 分钟(视频文件较大)
122
+ });
123
+ // 确定文件名
124
+ const finalFilename = filename || `dashscope_${Date.now()}.mp4`;
125
+ const outputPath = path.join(outputDir, finalFilename);
126
+ // 写入文件
127
+ await fs.writeFile(outputPath, response.data);
128
+ return outputPath;
129
+ }
130
+ sleep(ms) {
131
+ return new Promise(resolve => setTimeout(resolve, ms));
132
+ }
133
+ }
134
+ //# sourceMappingURL=dashscope-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashscope-api.js","sourceRoot":"","sources":["../../src/services/dashscope-api.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optima-chat/comfy-cli",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "A CLI tool for ComfyUI designed for LLM interactions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",