Guanghu Domestic Migration a2fa7d57d8 chore: import sanitized domestic snapshot for REPO-005
Source snapshot: 23037fa3a2e9b0597162735755e92fc763bf4d94
2026-07-17 15:55:48 +08:00

181 lines
9.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 步骤⑧: 逐镜 HLDP 提示词生成 (doubao-seed-2-1-pro)
const https = require('https');
const fs = require('fs');
const path = require('path');
const ENV_PATH = path.join(__dirname, '..', '..', '.env');
const ARK_KEY = fs.readFileSync(ENV_PATH, 'utf-8').match(/ARK_API_KEY=(.+)/)[1].trim();
// 10镜合并方案
const SHOTS = [
{
id: 'M01', duration: 8,
scene: '漆黑画面,警报滴滴声持续。林昊主观视角缓缓睁眼,天花板灯泡忽明忽暗。昏暗灯光下,破旧船员宿舍:两张三层钢架床铺凌乱,空无一人。宿舍唯一的舱门——厚重水密钢门,布满铁锈,上方嵌有矩形铆钉框观察窗。',
refs: 'ENV-001-crew-quarters.png (作为场景底板)',
camera: 'POV 主观视角,缓慢呼吸感起伏',
style: '深海科幻恐怖3D写实冷蓝工业光忽明忽暗'
},
{
id: 'M02', duration: 8,
scene: '林昊抬起双手至脸前,布满老茧,指甲缝嵌满黑色机油污渍。神色迷茫。突然轰隆巨响!船舱猛烈震颤!林昊从下铺猛地坐起,死死抓住床头铁杆固定身体。特写铁杆上镌刻的"秦山号"标记。',
refs: 'CHAR-001-林昊, ENV-001-crew-quarters.png',
camera: '近景手部→中景全身→推近至铁杆标记特写',
style: '同上,镜头随撞击晃动'
},
{
id: 'M03', duration: 8,
scene: '舱外传来极速沉重的脚步声。林昊猛地转头盯向锈迹斑斑的舱门。透过矩形观察窗,一道形状诡异、速度不似人类的黑影飞速闪过。震动渐停,灰尘震落。林昊跳下床,因船体倾斜险些摔倒,扶住床沿。',
refs: 'CHAR-001-林昊, ENV-002-hatch-window.png',
camera: '中景→快速甩镜至舱门→短暂 POV 透过观察窗',
style: '同上,甩镜制造紧张感'
},
{
id: 'M04', duration: 10,
scene: '林昊稳住身形,捂头皱眉,踉跄走向舱门。走到门前,伸手擦拭矩形观察窗内侧玻璃——四层钢化玻璃,内侧擦净,外侧仍被厚重灰尘糊住。拧动舱门把手,伴随刺耳吱呀声,把手纹丝不动。他看向掌心沾满的铁锈。',
refs: 'CHAR-001-林昊, ENV-002-hatch-window.png',
camera: '中景跟拍走向门→近景擦窗→近景手部+把手',
style: '同上,倾斜构图强调船体倾斜'
},
{
id: 'M05', duration: 6,
scene: '林昊瞥见舱门缝下渗出黑色液压油,皱眉面露不耐。转身看见下铺旁悬桌上放着一个硕大黑色破旧工具包。快步走过去,一把拉开拉链。',
refs: 'CHAR-001-林昊, ENV-002-hatch-window.png, PROP-001-tool-bag.png',
camera: '近景液压油→转身中景→近景拉开拉链',
style: '同上'
},
{
id: 'M06', duration: 6,
scene: '工具包内物品便携式手电筒、备用电源、急救绷带、半米长管钳、军绿水壶以及一个破旧工牌。推至工牌特写塑料壳泛黄开裂编号000768姓名林昊岗位模糊不清。照片的人脸部位被利器故意划烂仅余年轻帅气的下颌轮廓。',
refs: 'PROP-001-tool-bag.png, PROP-002-id-badge.png, PROP-003-pipe-wrench.png, PROP-004-flashlight.png',
camera: '特写包内物品慢摇→推至工牌极致特写',
style: '同上'
},
{
id: 'M07', duration: 9,
scene: '林昊猛抬头看向舱门矩形观察窗——又是一道黑影一闪而逝,更近更快。警报声变急促。林昊面露惧色,压低声音自语,呼吸急促。迅速收起工具包背在身上,抄起半米管钳紧握手中,大步走到舱门前。',
refs: 'CHAR-001-林昊, ENV-002-hatch-window.png, PROP-001-tool-bag.png, PROP-003-pipe-wrench.png',
camera: '中景抬头→快速甩镜至窗→回林昊恐惧面部→中景武装动作',
style: '同上,紧张节奏加快'
},
{
id: 'M08', duration: 8,
scene: '管钳卡住门把手,林昊咬紧牙关猛地用力——把手纹丝不动,铁锈碎屑飘落。盯着门缝下渗出的液压油渍,目光一凛,举管钳高高扬起,冲门把手下方液压凸起狠狠砸下!撞击瞬间:金属变形,白色泄压蒸汽猛然喷出。呲——林昊嘴角微扬,再次用管钳撬动把手,伴随刺耳吱呀声,把手终于缓缓转动。',
refs: 'PROP-003-pipe-wrench.png, ENV-002-hatch-window.png',
camera: '近景把手+管钳→中景举管钳→撞击晃动→定格雷泄压蒸汽→近景把手转动',
style: '同上,动作戏节奏紧凑'
},
{
id: 'M09', duration: 7,
scene: '砰!!一声巨响——一道不似人形的黑影重重砸在舱门外矩形观察窗上。一只手:指甲全部脱落,指尖露出白骨,血肉模糊,顺着玻璃缓缓滑下,留下五道暗红色血痕。然后一张脸贴上玻璃——半人半孢子。右半边:四十岁男人脸,苍白,眼泪滑落,嘴唇无声翕动。左半边:皮肤透明隆起,颗粒蠕动,左眼黑色菌膜覆盖,嘴角撕裂至耳根呈蜂窝状孔洞,黑色孢子在每个孔洞中脉动。每次呼吸,黑色孢子雾从孔洞喷出,蒙上玻璃。',
refs: 'ENV-002-hatch-window.png, CHAR-002-半孢感染者',
camera: '中景→撞击晃动→慢推至窗外→极致特写半孢脸→推至孢子雾',
style: '同上,恐怖高潮,冷蓝光让血呈现近乎黑色'
},
{
id: 'M10', duration: 5,
scene: '林昊僵在原地,瞳孔剧烈收缩,手中紧握的管钳不停发抖。画面骤然全黑。急促警报声拉至最大音量,持续不断。',
refs: 'CHAR-001-林昊',
camera: '近景林昊面部恐惧→瞳孔特写→渐隐至全黑',
style: '同上,尾声渐暗'
}
];
function callDoubao(prompt, system) {
return new Promise((resolve, reject) => {
var payload = JSON.stringify({
model: 'doubao-seed-2-1-pro-260628',
messages: [
{ role: 'system', content: system },
{ role: 'user', content: prompt }
],
temperature: 0.3,
max_tokens: 512
});
var options = {
hostname: 'ark.cn-beijing.volces.com',
path: '/api/v3/chat/completions',
method: 'POST',
headers: {
'Authorization': 'Bearer ' + ARK_KEY,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload, 'utf-8')
}
};
var req = https.request(options, function(res) {
var body = '';
res.on('data', function(c) { body += c; });
res.on('end', function() {
try {
var d = JSON.parse(body);
if (d.error) { reject(d.error); return; }
resolve(d.choices[0].message.content.trim());
} catch(e) { reject(e); }
});
});
req.on('error', reject);
req.setTimeout(120000, function() { req.destroy(); reject(new Error('timeout')); });
req.write(payload);
req.end();
});
}
async function main() {
var projPath = path.join(__dirname, '..', 'projects', 'deep-sea-voyage');
var outputLines = [];
outputLines.push('# 深海迷航 · EP01 · PROMPTS-EP01');
outputLines.push('# 引擎: doubao-seed-2-1-pro-260628');
outputLines.push('# 10镜 · Seedance 2.0 · 720p');
outputLines.push('');
var totalCost = 0;
for (var i = 0; i < SHOTS.length; i++) {
var s = SHOTS[i];
console.log('--- ' + s.id + ' (' + s.duration + 's) ---');
var cost = (0.5 * s.duration).toFixed(1);
totalCost += parseFloat(cost);
outputLines.push('## ' + s.id + ' · ' + s.duration + 's');
outputLines.push('△ ' + s.scene);
outputLines.push('相机: ' + s.camera);
outputLines.push('参考图: ' + s.refs);
outputLines.push('');
// AI 生成英文 Seedance prompt
var sysPrompt = '你是一个专业的 AI 视频生成提示词工程师。将中文场景描述转化为 Seedance 2.0 英文视频生成提示词。不超过 200 词。包含景别、动作、灯光、风格。不要加引号。';
var userPrompt = '场景: ' + s.scene + '\n相机运动: ' + s.camera + '\n风格: ' + s.style;
console.log(' 调用AI生成英文提示词...');
try {
var seedancePrompt = await callDoubao(userPrompt, sysPrompt);
outputLines.push('Seedance prompt:');
outputLines.push(seedancePrompt);
outputLines.push('');
console.log(' ✅ ' + s.id + ' (' + seedancePrompt.length + ' chars)');
} catch(e) {
outputLines.push('Seedance prompt: [生成失败: ' + (e.message || e) + ']');
outputLines.push('');
console.log(' ❌ ' + s.id + ': ' + (e.message || e));
}
}
outputLines.push('---');
outputLines.push('## 成本预估');
outputLines.push('');
outputLines.push('| M# | 时长 | 单价 | 费用 |');
outputLines.push('|:--:|:--:|:--:|:--:|');
for (var j = 0; j < SHOTS.length; j++) {
var s2 = SHOTS[j];
var c = (0.5 * s2.duration).toFixed(1);
outputLines.push('| ' + s2.id + ' | ' + s2.duration + 's | ¥0.5/s | ¥' + c + ' |');
}
outputLines.push('| **合计** | **75s** | — | **¥' + totalCost.toFixed(1) + '** |');
var outPath = path.join(projPath, 'PROMPTS-EP01.hdlp');
fs.writeFileSync(outPath, outputLines.join('\n'), 'utf-8');
console.log('\n🎬 SAVED: ' + outPath);
console.log('总计 10镜 75s 预估 ¥' + totalCost.toFixed(1));
}
main().catch(function(e) { console.error('FATAL:', e.message || e); });