diff --git a/video-ai-system/engines/kling-api-adapter.js b/video-ai-system/engines/kling-api-adapter.js new file mode 100644 index 0000000..5eb9dc2 --- /dev/null +++ b/video-ai-system/engines/kling-api-adapter.js @@ -0,0 +1,107 @@ +/** + * 光湖视频AI系统 · Kling 可灵 API 适配器 + * D136+ · 铸渊 ICE-GL-ZY001 · 2026-06-21 + * + * 接入可灵AI视频生成API。价格: kling-v2.6-pro $0.049/s (约1.8元/5秒) + * 非Seedance——用于低成本验证提示词和流程 + */ + +const fs = require('fs'); +const path = require('path'); +const https = require('https'); + +// API配置 +const API_KEY = 'Ze8Bas4_xw1JsPLmfULgMyykvZelFSwv57Hycc6SJm0'; +const BASE_URL = 'api.klingapi.com'; +const POLL_INTERVAL = 3000; // 可灵更快,3秒轮询 +const MAX_POLL = 60; // 最多3分钟 + +// 输出路径 +const OUT_DIR = (() => { + const jzao = '/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/视频/zai-fu-fei-xiu-xian/ep01'; + return fs.existsSync(jzao) ? jzao : path.resolve(__dirname, '../outputs/shots'); +})(); + +function apiRequest(method, path_, body = null) { + return new Promise((resolve, reject) => { + const options = { + hostname: BASE_URL, + path: path_, + method, + headers: { + 'Authorization': `Bearer ${API_KEY}`, + 'Content-Type': 'application/json', + }, + }; + const req = https.request(options, (res) => { + let data = ''; + res.on('data', chunk => data += chunk); + res.on('end', () => { + try { resolve(JSON.parse(data)); } + catch (e) { resolve({ raw: data }); } + }); + }); + req.on('error', reject); + if (body) req.write(JSON.stringify(body)); + req.end(); + }); +} + +function downloadFile(url, dest) { + return new Promise((resolve, reject) => { + const file = fs.createWriteStream(dest); + const proto = url.startsWith('https') ? https : require('http'); + proto.get(url, (res) => { + if (res.statusCode >= 300 && res.statusCode < 400) { + return downloadFile(res.headers.location, dest).then(resolve).catch(reject); + } + res.pipe(file); + file.on('finish', () => { file.close(); resolve(dest); }); + }).on('error', reject); + }); +} + +async function generateKlingVideo({ prompt, duration = 5, outputPath, model = 'kling-v2.6-pro' }) { + console.log('[Kling] 提交文生视频...'); + + // 提交 + const submit = await apiRequest('POST', '/v1/videos/text2video', { + model, + prompt, + duration: Math.min(duration, 10), + aspect_ratio: '16:9', + mode: 'standard', + }); + + if (!submit.task_id) { + throw new Error(`提交失败: ${JSON.stringify(submit)}`); + } + console.log(`[Kling] 任务: ${submit.task_id}`); + + // 轮询 + for (let i = 1; i <= MAX_POLL; i++) { + await new Promise(r => setTimeout(r, POLL_INTERVAL)); + const status = await apiRequest('GET', `/v1/videos/${submit.task_id}`); + + if (status.status === 'completed') { + const videoUrl = status.video_url || status.output?.video_url; + if (!videoUrl) throw new Error('任务完成但无视频URL'); + + const out = outputPath || path.join(OUT_DIR, `kling-${submit.task_id}.mp4`); + fs.mkdirSync(path.dirname(out), { recursive: true }); + console.log(`[Kling] 下载: ${videoUrl.substring(0,60)}...`); + await downloadFile(videoUrl, out); + console.log(`[Kling] ✅ ${path.basename(out)}`); + return { videoPath: out, taskId: submit.task_id }; + } + + if (status.status === 'failed') { + throw new Error(`生成失败: ${status.error || JSON.stringify(status)}`); + } + + if (i % 10 === 0) console.log(`[Kling] 生成中... (${i}/${MAX_POLL})`); + } + throw new Error('超时'); +} + +module.exports = { generateKlingVideo }; diff --git a/video-ai-system/outputs/video-registry.json b/video-ai-system/outputs/video-registry.json index 5f6db8e..9e8ebb1 100644 --- a/video-ai-system/outputs/video-registry.json +++ b/video-ai-system/outputs/video-registry.json @@ -1,30 +1,30 @@ { "_meta": { - "updated": "2026-06-21T08:49:17.336Z", + "updated": "2026-06-21T10:05:42.868Z", "by": "铸渊 ICE-GL-ZY001", - "totalShots": 3 + "totalShots": 4 }, "shots": { "付费才能修仙-ep01-S1-01": { "shotId": "付费才能修仙-ep01-S1-01", - "taskId": "cgt-20260621163837-2wwgs", + "taskId": "cgt-20260621174538-zcmlv", "projectKey": "付费修仙/ep01", - "filePath": "/Users/bingshuolingdianyuanhe/guanghulab/video-ai-system/outputs/shots/付费才能修仙-ep01-S1-01.mp4", + "filePath": "/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/视频/zai-fu-fei-xiu-xian/ep01/付费才能修仙-ep01-S1-01.mp4", "duration": 5, "resolution": "720p", - "promptPreview": "修仙世界·3D动画渲染·电影级光影·动态漫风格。修仙世界开阔广场,云海环绕远处山峰,白天阳光明媚金色光芒仙气弥漫。广场上人山人海宗门招牌林立,在人群边缘的一个角", - "generatedAt": "2026-06-21T08:41:17.575Z", + "promptPreview": "[Epep01 Summary] Su Bai has system, never despairs. Worst booth in cultivation s", + "generatedAt": "2026-06-21T09:47:47.968Z", "dNumber": "D135" }, "付费才能修仙-ep01-S1-02": { "shotId": "付费才能修仙-ep01-S1-02", - "taskId": "cgt-20260621164117-phfvb", + "taskId": "cgt-20260621174748-jqdcz", "projectKey": "付费修仙/ep01", - "filePath": "/Users/bingshuolingdianyuanhe/guanghulab/video-ai-system/outputs/shots/付费才能修仙-ep01-S1-02.mp4", + "filePath": "/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/视频/zai-fu-fei-xiu-xian/ep01/付费才能修仙-ep01-S1-02.mp4", "duration": 5, "resolution": "720p", - "promptPreview": "修仙世界·3D动画渲染·电影级光影·动态漫风格。修仙世界开阔广场,云海环绕远处山峰,白天阳光明媚金色光芒仙气弥漫。广场上人山人海宗门招牌林立,在人群边缘的一个角", - "generatedAt": "2026-06-21T08:44:49.278Z", + "promptPreview": "[Epep01 Summary] Su Bai has system, never despairs. Worst booth in cultivation s", + "generatedAt": "2026-06-21T09:50:58.950Z", "dNumber": "D135" }, "付费才能修仙-ep01-S1-03": { @@ -37,6 +37,17 @@ "promptPreview": "修仙世界·3D动画渲染·电影级光影·动态漫风格。修仙世界开阔广场,云海环绕远处山峰,白天阳光明媚金色光芒仙气弥漫。广场上人山人海宗门招牌林立,在人群边缘的一个角", "generatedAt": "2026-06-21T08:49:17.336Z", "dNumber": "D135" + }, + "cgt-20260621180038-8t8bm": { + "shotId": "cgt-20260621180038-8t8bm", + "taskId": "cgt-20260621180038-8t8bm", + "projectKey": "付费修仙/ep01", + "filePath": "/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/视频/zai-fu-fei-xiu-xian/ep01/付费才能修仙-ep01-S1-03.mp4", + "duration": 5, + "resolution": "720p", + "promptPreview": "[Ep01 Summary] Su Bai has system, never despairs. Worst booth in cultivation squ", + "generatedAt": "2026-06-21T10:05:42.868Z", + "dNumber": "D135" } } } \ No newline at end of file diff --git a/video-ai-system/outputs/付费修仙-ep01-director-encoding.json b/video-ai-system/outputs/付费修仙-ep01-director-encoding.json index 44f5396..ec542f3 100644 --- a/video-ai-system/outputs/付费修仙-ep01-director-encoding.json +++ b/video-ai-system/outputs/付费修仙-ep01-director-encoding.json @@ -57,7 +57,7 @@ "framing": "中景", "char": "CHAR-003", "env": "ENV-002", - "action": "天道宗竖式悬挂牌匾下方旁边,放着一块横式广告牌,上面写着:【天道宗】【未来第一宗】【名额:一位】【包吃包住】【每月基础银子:三十两】【入宗即可学习仙法】。苏白大声:「走过路过不要错过!」听到呼喊声,周围的人围了过来,对着苏白和广告牌指指点点。围观的人讽刺完散去,一阵风吹起了苏白脚下的落叶。苏白叹了一口气。", + "action": "天道宗竖式牌匾下方旁边,放着一块木板手写告示牌。苏白大声吆喝招人。听到喊声,周围的人围过来指指点点。围观的人讽刺完散去,一阵风吹起苏白脚下落叶。苏白叹了一口气。", "emotion": { "intensity": 4, "type": "冷" }, "rhythm": "转折", "show": "广告牌细节→围观者表情→落叶飘散·苏白叹气",