D136+: Kling可灵API适配器 + S1-03版权过滤修复
kling-api-adapter.js: 接入可灵视频生成API endpoint: api.klingapi.com/v1/videos/text2video model: kling-v2.6-pro (/bin/zsh.049/s ≈ 1.8元/5秒) ️价格对比: 可灵 1.8元 vs Seedance 5元+ (省1/3) 导演编码修复: S1-03去广告文本→版权过滤拦截解决
This commit is contained in:
parent
b3da7e2f6e
commit
083030b453
107
video-ai-system/engines/kling-api-adapter.js
Normal file
107
video-ai-system/engines/kling-api-adapter.js
Normal file
@ -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 };
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,7 +57,7 @@
|
||||
"framing": "中景",
|
||||
"char": "CHAR-003",
|
||||
"env": "ENV-002",
|
||||
"action": "天道宗竖式悬挂牌匾下方旁边,放着一块横式广告牌,上面写着:【天道宗】【未来第一宗】【名额:一位】【包吃包住】【每月基础银子:三十两】【入宗即可学习仙法】。苏白大声:「走过路过不要错过!」听到呼喊声,周围的人围了过来,对着苏白和广告牌指指点点。围观的人讽刺完散去,一阵风吹起了苏白脚下的落叶。苏白叹了一口气。",
|
||||
"action": "天道宗竖式牌匾下方旁边,放着一块木板手写告示牌。苏白大声吆喝招人。听到喊声,周围的人围过来指指点点。围观的人讽刺完散去,一阵风吹起苏白脚下落叶。苏白叹了一口气。",
|
||||
"emotion": { "intensity": 4, "type": "冷" },
|
||||
"rhythm": "转折",
|
||||
"show": "广告牌细节→围观者表情→落叶飘散·苏白叹气",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user