feat(video-from-script): 升级可灵视频生成使用官方 API 并添加失败重试机制
- 使用 AK/SK → JWT (HMAC-SHA256) 鉴权替代旧版 API Key - 支持多种凭证来源:~/.config/kling/.credentials 或 config.json - 更新 API 端点至官方规范 (v1/videos/image2video) - 添加 `--retry-failed` 参数支持失败 item 状态重置和重试 - 更新 manifest 文档添加状态机和失败处理说明 - 调整模型名称和参数格式以匹配新 API
This commit is contained in:
@@ -531,6 +531,46 @@ async function runPipeline(manifestPath, options) {
|
||||
manifest.pipeline = { phases: {} }
|
||||
}
|
||||
|
||||
// --retry-failed: 重置失败 item 状态,允许重新处理
|
||||
if (options.retryFailed) {
|
||||
let resetCount = 0
|
||||
for (const item of manifest.items) {
|
||||
if (item.status === 'failed' || item.status === 'partial') {
|
||||
// 根据 item 是否有 url 判断该重置到哪个阶段
|
||||
if (item.url && item.videoPrompt && !item.video) {
|
||||
// 图片已生成、有视频提示词、但没视频 → 重置为可生视频
|
||||
item.status = 'done'
|
||||
item.error = ''
|
||||
resetCount++
|
||||
} else if (!item.url && item.imagePrompt) {
|
||||
// 没有图片但有提示词 → 重置为可生图
|
||||
item.status = 'pending'
|
||||
item.error = ''
|
||||
resetCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
// 重置对应阶段状态
|
||||
if (phases.includes('videos')) {
|
||||
const hasVideoItems = manifest.items.some(it => it.status === 'done' && it.url && it.videoPrompt && !it.video)
|
||||
if (hasVideoItems) manifest.pipeline.phases.videos = 'pending'
|
||||
}
|
||||
if (phases.includes('images')) {
|
||||
const hasImageItems = manifest.items.some(it => !it.status || it.status === 'pending')
|
||||
if (hasImageItems) manifest.pipeline.phases.images = 'pending'
|
||||
}
|
||||
if (phases.includes('upload')) {
|
||||
manifest.pipeline.phases.upload = 'pending'
|
||||
}
|
||||
if (phases.includes('tts')) {
|
||||
manifest.pipeline.phases.tts = 'pending'
|
||||
}
|
||||
if (resetCount > 0) {
|
||||
log('pipeline', `重置 ${resetCount} 个失败 item (--retry-failed)`)
|
||||
saveManifest(manifestPath, manifest)
|
||||
}
|
||||
}
|
||||
|
||||
log('pipeline', `阶段: ${phases.join(' → ')}`)
|
||||
|
||||
const phaseHandlers = {
|
||||
@@ -1007,6 +1047,7 @@ function parseArgs(argv) {
|
||||
else if (argv[i] === '--account' && argv[i + 1]) args.account = argv[++i]
|
||||
else if (argv[i] === '--phase' && argv[i + 1]) args.phases = argv[++i].split(',')
|
||||
else if (argv[i] === '--resume') args.resume = true
|
||||
else if (argv[i] === '--retry-failed') args.retryFailed = true
|
||||
else if (argv[i] === '--mode' && argv[i + 1]) args.mode = argv[++i]
|
||||
else if (argv[i] === '--items' && argv[i + 1]) args.items = argv[++i]
|
||||
else if (argv[i] === '--items-file' && argv[i + 1]) args.itemsFile = argv[++i]
|
||||
@@ -1045,7 +1086,7 @@ async function main() {
|
||||
}
|
||||
|
||||
if (command === 'run') {
|
||||
if (!args.manifest) { console.error('用法: pipeline.js run --manifest <path> [--account id] [--phase p1,p2] [--resume]'); process.exit(1) }
|
||||
if (!args.manifest) { console.error('用法: pipeline.js run --manifest <path> [--account id] [--phase p1,p2] [--resume] [--retry-failed]'); process.exit(1) }
|
||||
await runPipeline(args.manifest, args)
|
||||
return
|
||||
}
|
||||
@@ -1066,7 +1107,7 @@ async function main() {
|
||||
console.log(' pipeline.js validate-account --account <id>')
|
||||
console.log(' pipeline.js init --account <id> --mode <single|framePair> --items <JSON> [--items-file <path>]')
|
||||
console.log(' pipeline.js validate --manifest <path>')
|
||||
console.log(' pipeline.js run --manifest <path> [--account id] [--phase p1,p2] [--resume]')
|
||||
console.log(' pipeline.js run --manifest <path> [--account id] [--phase p1,p2] [--resume] [--retry-failed]')
|
||||
console.log(' pipeline.js status --manifest <path>')
|
||||
console.log('')
|
||||
console.log('Manifest 路径约定: output/{account}_{date}_{NNN}/manifest.json(同天自增序号)')
|
||||
|
||||
Reference in New Issue
Block a user