// 步骤⑦ storyboard: doubao 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(); const SCRIPT_PATH = path.join(__dirname, '..', 'projects', 'deep-sea-voyage', 'EP01-SCRIPT-LOCK.hdlp'); const script = fs.readFileSync(SCRIPT_PATH, 'utf-8'); const prompt = `请将以下短剧剧本第1集拆解为结构化分镜,严格输出JSON格式。 要求: - 按镜头拆分,每个镜头对应一个动作/反应/信息增量 - 每镜包含:shot_number(S01-SXX), description(中文50字内), camera(特写/近景/中景/全景/POV), duration(秒), type(establishing/action/reaction/closeup/transition), characters(角色列表), scenes(场景列表), props(道具列表) 输出示例: {"episode":1,"shots":[{"shot_number":"S01","description":"画面漆黑,警报声滴滴","camera":"POV","duration":3,"type":"establishing","characters":[],"scenes":["船员宿舍"],"props":[],"dialogue":"滴滴滴滴..."}]} 剧本: ${script}`; const payload = JSON.stringify({ model: 'doubao-seed-2-1-pro-260628', messages: [{ role: 'system', content: '你是一个顶级影视分镜师,专精科幻恐怖短剧。' }, { role: 'user', content: prompt }], temperature: 0.2, max_tokens: 4096 }); const 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') } }; console.log('豆包 PRO 拆解剧本...'); var t0 = Date.now(); var req = https.request(options, function(res) { var body = ''; res.on('data', function(chunk) { body += chunk; }); res.on('end', function() { var elapsed = ((Date.now() - t0) / 1000).toFixed(1); console.log('elapsed: ' + elapsed + 's'); try { var data = JSON.parse(body); if (data.error) { console.error('ERROR:', JSON.stringify(data.error)); process.exit(1); } var content = data.choices[0].message.content; console.log('tokens:', JSON.stringify(data.usage)); var json = content; var m = json.match(/```(?:json)?\s*([\s\S]*?)```/); if (m) json = m[1].trim(); var outPath = path.join(__dirname, '..', 'projects', 'deep-sea-voyage', 'STORYBOARD-AI-PRO.json'); fs.writeFileSync(outPath, json, 'utf-8'); console.log('SAVED:', outPath); console.log('---\n' + json); } catch(e) { console.error(e.message); } }); }); req.on('error', function(e) { console.error(e.message); }); req.setTimeout(300000, function() { req.destroy(); console.error('TIMEOUT 300s'); }); req.write(payload); req.end();