铁律: - ④重写为白名单/黑名单机制 (今日4次违规) - ⑤新增 BREAKDOWN回验协议 - ⑥新增 管线不容跳步 核心经验: - 图片+视频混合管线路线验证 - ENV底板法 (i2i→i2v) - 提示词工程: 工业术语+禁人称词+负面约束 - CHAR真人检测绕过 (blur公式) - FFmpeg xfade拼接方法 - Seedance 2.0 参数 (9:16, 4-15s) 新增文件: - eererdan/experience/EED-EXPER-001~010 - protocols/BREAKDOWN-VERIFY.hdlp - deep-sea-voyage/STORYBOARD-EP01.hdlp (Pro版26→10镜) - deep-sea-voyage/PROMPTS-EP01.hdlp - deep-sea-voyage/DIRECTOR-ENCODING-EP01.hdlp - tools/jimeng3-gen.js, run_storyboard.js, run_prompts.js, run_adapt.js, run_gen.js, crop_watermark.py - lib/seedream.py (支持 Seedream 3/4/5) - outputs/ENV-*-v5, PROP-* (6张定稿资产) - outputs/videos/M01-v2.mp4, M02.mp4 下次继续: M03~M10 (9:16竖屏)
51 lines
2.9 KiB
JavaScript
51 lines
2.9 KiB
JavaScript
// M01 v3: ENV only, no CHAR blur
|
|
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 OUT = path.join(__dirname, '..', 'projects', 'deep-sea-voyage', 'outputs');
|
|
|
|
var envB64 = 'data:image/png;base64,' + fs.readFileSync(path.join(OUT, 'ENV-001-crew-quarters.png')).toString('base64');
|
|
|
|
var prompt = 'Medium shot of a cramped deep-sea crew dorm exactly as in reference. LIN HAO lies unconscious on the lower-left bunk bed, eyes closed, half-covered by a thin grey blanket, wearing dark blue worn coverall. The bare ceiling bulb flickers erratically with cold blue industrial light. The room is tilted, metal walls stained with rust and oil. Faint persistent alarm beeps. Camera slowly pushes in from medium to close-up, subtle breathing bob. NO other people. 8 seconds.';
|
|
|
|
var body = JSON.stringify({
|
|
model: 'doubao-seedance-2-0-260128',
|
|
content: [
|
|
{ type: 'text', text: prompt },
|
|
{ type: 'image_url', role: 'reference_image', image_url: { url: envB64 } }
|
|
],
|
|
duration: 8, resolution: '720p', ratio: '9:16', watermark: false
|
|
});
|
|
|
|
console.log('M01 v3: ENV only, no CHAR blur...');
|
|
var req = https.request({ hostname: 'ark.cn-beijing.volces.com', path: '/api/v3/contents/generations/tasks', method: 'POST', headers: { 'Authorization': 'Bearer ' + ARK_KEY, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body, 'utf-8') } }, function(res) {
|
|
var d = ''; res.on('data', c => d += c); res.on('end', () => {
|
|
var r = JSON.parse(d);
|
|
if (r.error) { console.error('❌', JSON.stringify(r.error)); return; }
|
|
console.log(' 任务: ' + r.id);
|
|
var start = Date.now();
|
|
function poll() {
|
|
if ((Date.now()-start)/1000 > 600) { console.error('timeout'); return; }
|
|
https.get({ hostname: 'ark.cn-beijing.volces.com', path: '/api/v3/contents/generations/tasks/' + r.id, headers: { 'Authorization': 'Bearer ' + ARK_KEY } }, function(res2) {
|
|
var b = ''; res2.on('data', c => b += c); res2.on('end', () => {
|
|
var r2 = JSON.parse(b);
|
|
if (r2.status === 'succeeded') {
|
|
var fp = path.join(OUT, 'videos', 'M01-v3.mp4');
|
|
var vurl = r2.content.video_url;
|
|
var dl = u => https.get(u, res3 => {
|
|
var f = fs.createWriteStream(fp);
|
|
var dp = r3 => { r3.pipe(f); f.on('finish', () => { f.close(); var s = (fs.statSync(fp).size/1024).toFixed(1); console.log('✅ M01-v3.mp4 ' + s + ' KB'); }); };
|
|
if (res3.statusCode >= 300 && res3.headers.location) https.get(res3.headers.location, dp); else dp(res3);
|
|
}); dl(vurl);
|
|
} else if (r2.status === 'failed') { console.error('❌ failed'); }
|
|
else { process.stdout.write('.'); setTimeout(poll, 30000); }
|
|
});
|
|
});
|
|
}
|
|
poll();
|
|
});
|
|
});
|
|
req.write(body); req.end();
|