feat(video-from-script): 将可灵生图切换为多图参考风格接口

将 Kling 图像生成器从单图生图 API 升级为多图参考生图端点,支持风格参考图片功能,并更新降级链顺序
This commit is contained in:
2026-04-30 00:59:02 +08:00
parent 8301c7b780
commit 8656f3a58c
3 changed files with 27 additions and 18 deletions

View File

@@ -140,7 +140,7 @@ Step 3: 生图 → 审查
生图模型
- 支持模型gemini / mj / kling
- 降级链gemini → kling → mj → gemini循环
- 降级链gemini → mj → kling → gemini循环
- 触发:连续失败→ Agent 换下一个模型重跑失败项
- 操作:`pipeline.js run --manifest <path> --phase images --retry-failed --image-model <新模型>`

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env node
/**
* Kling Image Generator - 可灵文生图 / 图生图
* Kling Image Generator - 可灵多图参考生图 (风格参考)
*
* 使用 /v1/images/multi-image2image 端点,支持 style_image 风格参考
* 配置来源: config.json 的 kelingApiKey + kelingSecretAccessKey + kelingApiBaseUrl
*
* 用法:
* node kling-image-generator.js "a cute cat" -o ./output
* node kling-image-generator.js "portrait" -r http://img.com/ref.jpg
* node kling-image-generator.js "a cute cat" -r http://img.com/style.jpg -o ./output
*/
const fs = require('fs')
@@ -75,24 +75,31 @@ async function download(url, outputPath) {
}
// ============================================================================
// 可灵图片 API
// 可灵多图参考生图 API (/v1/images/multi-image2image)
// ============================================================================
const KlingImageApi = {
async submit(prompt, options = {}) {
const { referenceImageUrl = '', aspectRatio = '' } = options
const { styleImageUrl = '', aspectRatio = '' } = options
const token = getToken()
const body = { model_name: Config.model, prompt, n: 1 }
if (referenceImageUrl) body.image = referenceImageUrl
const body = {
model_name: Config.model,
prompt,
n: 1,
}
if (styleImageUrl) {
body.subject_image_list = [{ subject_image: styleImageUrl }]
body.style_image = styleImageUrl
}
if (aspectRatio) body.aspect_ratio = aspectRatio
console.log(`\n📡 提交可灵图片任务`)
console.log(` 模型: ${Config.model}`)
console.log(` 提示词: ${prompt.substring(0, 80)}...`)
if (referenceImageUrl) console.log(` 参考图: ${referenceImageUrl.substring(0, 60)}...`)
if (styleImageUrl) console.log(` 风格图: ${styleImageUrl.substring(0, 60)}...`)
const res = await fetch(`${Config.apiBase}/v1/images/generations`, {
const res = await fetch(`${Config.apiBase}/v1/images/multi-image2image`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
body: JSON.stringify(body),
@@ -116,7 +123,7 @@ const KlingImageApi = {
while (Date.now() - startTime < Config.maxPollTime) {
const token = getToken()
const res = await fetch(`${Config.apiBase}/v1/images/generations/${taskId}`, {
const res = await fetch(`${Config.apiBase}/v1/images/multi-image2image/${taskId}`, {
headers: { 'Authorization': `Bearer ${token}` },
})
@@ -150,11 +157,11 @@ const KlingImageApi = {
// ============================================================================
async function generate(prompt, options = {}) {
const { outputDir = './output', referenceImageUrl = '' } = options
const { outputDir = './output', styleImageUrl = '', aspectRatio = '' } = options
fs.mkdirSync(outputDir, { recursive: true })
const taskId = await KlingImageApi.submit(prompt, { referenceImageUrl })
const taskId = await KlingImageApi.submit(prompt, { styleImageUrl, aspectRatio })
const result = await KlingImageApi.poll(taskId)
const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
@@ -177,20 +184,22 @@ async function main() {
选项:
-o, --output <dir> 输出目录 (默认: ./output)
-r, --ref <url> 参考图 URL
-r, --ref <url> 风格参考图 URL
-a, --ar <ratio> 画幅比例 (如 9:16, 16:9)
-h, --help 帮助
`)
return
}
const options = { outputDir: './output', referenceImageUrl: '' }
const options = { outputDir: './output', styleImageUrl: '', aspectRatio: '' }
const params = []
let i = 0
while (i < args.length) {
const arg = args[i]
if (arg === '-o' || arg === '--output') { options.outputDir = args[++i] }
else if (arg === '-r' || arg === '--ref') { options.referenceImageUrl = args[++i] }
else if (arg === '-r' || arg === '--ref') { options.styleImageUrl = args[++i] }
else if (arg === '-a' || arg === '--ar') { options.aspectRatio = args[++i] }
else { params.push(arg) }
i++
}

View File

@@ -221,7 +221,7 @@ async function phaseImages(manifest, manifestPath, options) {
const { generate: klingGen } = require('./kling-image-generator')
const klingOpts = { outputDir: imagesDir, aspectRatio: ratio }
if (refs.urls.length > 0) {
klingOpts.referenceImageUrl = refs.urls[0]
klingOpts.styleImageUrl = refs.urls[0]
}
log('images', `[${idx}/${items.length}] 可灵生图: ${item.imagePrompt.substring(0, 60)}...`)
result = await klingGen(item.imagePrompt, klingOpts)
@@ -272,7 +272,7 @@ async function phaseImages(manifest, manifestPath, options) {
const { generate: klingGen } = require('./kling-image-generator')
lastResult = await klingGen(item.lastFramePrompt, {
outputDir: imagesDir,
referenceImageUrl: item.url || '',
styleImageUrl: item.url || '',
aspectRatio: ratio,
})
}