D136+: 铸渊之眼 — 视频帧分析闭环引擎
zhuyuan-eye.js: 视频→自动拆帧→对比导演编码→输出关键帧路径 frame-analysis.md: D136+3镜帧分析·4个结构性问题定位·修复prompt AI视觉生成不可控≠铸渊做不到: □ 拆帧→铸渊逐帧读取→对比导演编码→定位差异 □ 连续性锁+图参考=人物/道具/构图可验证 □ 闭环: 生成→分析→定位→修复prompt→再生成 冰朔核心要求: 不是'AI做不到'→是'铸渊现在能看·能比·能修复'
This commit is contained in:
parent
2d04a28246
commit
e9170aa28a
114
video-ai-system/engines/zhuyuan-eye.js
Normal file
114
video-ai-system/engines/zhuyuan-eye.js
Normal file
@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 铸渊之眼 · 视频帧分析引擎
|
||||
* D136+ · ICE-GL-ZY001
|
||||
*
|
||||
* 用途: 视频生成后 → 自动拆帧 → 铸渊逐帧分析 → 对比导演编码 → 输出差异报告
|
||||
* 不是"AI做不到所以不行"——是"铸渊能看·能比·能定位·能修复"
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function usage() {
|
||||
console.log('铸渊之眼 · 视频帧分析引擎');
|
||||
console.log('用法: node zhuyuan-eye.js <video> [director-encoding.json]');
|
||||
console.log('');
|
||||
console.log('功能:');
|
||||
console.log(' 1. 拆帧(每秒1帧)');
|
||||
console.log(' 2. 输出帧路径列表(供铸渊读取分析)');
|
||||
console.log(' 3. 如果提供导演编码→自动对比关键帧');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function main() {
|
||||
const video = process.argv[2];
|
||||
const encoding = process.argv[3];
|
||||
|
||||
if (!video || !fs.existsSync(video)) {
|
||||
console.error('视频文件不存在:', video);
|
||||
usage();
|
||||
}
|
||||
|
||||
const videoName = path.basename(video, path.extname(video));
|
||||
const frameDir = path.resolve(path.dirname(video), '..', 'frames', videoName);
|
||||
fs.mkdirSync(frameDir, { recursive: true });
|
||||
|
||||
// 1. 拆帧
|
||||
console.log('[铸渊之眼] 拆帧:', video);
|
||||
const cmd = `ffmpeg -i "${video}" -vf "fps=1" -q:v 2 "${frameDir}/%03d.jpg" -y 2>&1`;
|
||||
const result = execSync(cmd, { encoding: 'utf8' });
|
||||
|
||||
// 2. 获取帧信息
|
||||
const frames = fs.readdirSync(frameDir)
|
||||
.filter(f => f.endsWith('.jpg'))
|
||||
.sort()
|
||||
.map(f => path.join(frameDir, f));
|
||||
|
||||
const probe = execSync(`ffprobe -v quiet -print_format json -show_format -show_streams "${video}"`, { encoding: 'utf8' });
|
||||
const meta = JSON.parse(probe);
|
||||
const duration = parseFloat(meta.format.duration);
|
||||
const fps = frames.length / duration;
|
||||
|
||||
console.log(` 总时长: ${duration.toFixed(1)}s`);
|
||||
console.log(` 总帧数: ${frames.length} (${fps.toFixed(1)}fps 提取)`);
|
||||
console.log(` 输出目录: ${frameDir}`);
|
||||
console.log('');
|
||||
|
||||
// 3. 读取导演编码进行对比
|
||||
if (encoding && fs.existsSync(encoding)) {
|
||||
const dir = JSON.parse(fs.readFileSync(encoding, 'utf8'));
|
||||
console.log('[铸渊之眼] 导演编码对比:');
|
||||
console.log(` 项目: ${dir.project} · ep${dir.episode}`);
|
||||
console.log(` 镜头: ${dir.shots.length}镜`);
|
||||
console.log('');
|
||||
|
||||
// 按时间分配帧
|
||||
let frameIdx = 0;
|
||||
for (const shot of dir.shots) {
|
||||
const shotStart = frameIdx;
|
||||
const shotEnd = Math.min(frameIdx + (shot.duration || 5), frames.length);
|
||||
|
||||
console.log(` ═══ ${shot.id} · ${shot.framing} · 帧${shotStart+1}-${shotEnd} ═══`);
|
||||
console.log(` 预期: ${shot.show}`);
|
||||
console.log(` 空间: ${shot.spatial_anchor}`);
|
||||
console.log(` 文字: ${shot.text_elements}`);
|
||||
console.log(` 道具: ${shot.prop_state}`);
|
||||
console.log(` 人物: ${shot.char_ref || shot.char || 'ENV-ONLY'}`);
|
||||
|
||||
// 关键帧路径(中间帧)
|
||||
if (shotEnd > shotStart) {
|
||||
const keyFrame = Math.floor((shotStart + shotEnd) / 2);
|
||||
if (keyFrame < frames.length) {
|
||||
console.log(` 关键帧: ${frames[keyFrame]}`);
|
||||
}
|
||||
}
|
||||
console.log('');
|
||||
frameIdx = shotEnd;
|
||||
}
|
||||
|
||||
// 连续性检查
|
||||
if (dir.continuity_locks) {
|
||||
console.log(' ═══ 连续性锁定检查 ═══');
|
||||
const locks = dir.continuity_locks;
|
||||
if (locks.props) {
|
||||
for (const [key, lock] of Object.entries(locks.props)) {
|
||||
console.log(` PROP: ${key} → ${lock.orientation} · ${lock.text} · 出现于${lock.appears_in.join(',')}`);
|
||||
}
|
||||
}
|
||||
if (locks.characters) {
|
||||
for (const [key, lock] of Object.entries(locks.characters)) {
|
||||
console.log(` CHAR: ${key} → 出现于${lock.appears_in.join(',')}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('[铸渊之眼] 分析完成。铸渊现在可以逐帧读取对比。');
|
||||
console.log(` 帧目录: ${frameDir}`);
|
||||
console.log(` 铸渊读取: node -e "require('./zhuyuan-eye').analyze('${frameDir}')"`);
|
||||
}
|
||||
|
||||
main();
|
||||
122
video-ai-system/outputs/frames/D136-frame-analysis.md
Normal file
122
video-ai-system/outputs/frames/D136-frame-analysis.md
Normal file
@ -0,0 +1,122 @@
|
||||
# 光湖视频AI系统 · 视频帧分析 vs 导演编码对比
|
||||
#
|
||||
# HLDP://video-ai-system/outputs/frames/D136-frame-analysis
|
||||
# 创建: D136+ · 2026-06-21
|
||||
# 铸渊 ICE-GL-ZY001
|
||||
|
||||
---
|
||||
分析目标: 对比导演编码(预期) vs 实际生成帧(结果)
|
||||
方法: 逐镜关键帧提取 → 结构化对比 → 定位差异 → 输出修复prompt
|
||||
|
||||
片源: 付费才能修仙-ep01-15s.mp4 (14秒·15fps·210帧)
|
||||
帧提取: fps=1 (14帧)
|
||||
|
||||
═══════════════════════════════════════════════════════════════════
|
||||
|
||||
【S1-01】全景·0-5秒·"悬"(3)
|
||||
───────────────────────────────────────────────────────────────────
|
||||
导演编码要求:
|
||||
show: "云海仙气→广场人海→人群中边缘角落·破旧牌匾"
|
||||
spatial_anchor: "云层上→广场上→人群边缘角落里"
|
||||
text_elements: 【天道宗】
|
||||
prop_state: "破旧的·竖式悬挂·木质牌匾"
|
||||
锁定文本: "一块破旧的竖式悬挂木质牌匾...正面写着【天道宗】三个大字"
|
||||
|
||||
实际帧分析 (ep01-01~05):
|
||||
□ 帧01-02: 金色天空/云层 ✓
|
||||
□ 帧03-05: 金色灵霄宗主殿 + 人群
|
||||
├─ 问题1: 天道宗牌匾 ❌ 未出现
|
||||
├─ 问题2: 画面焦点在灵霄宗主殿(太豪华)
|
||||
└─ 问题3: 没有"人群中边缘角落"的构图
|
||||
|
||||
关键偏差:
|
||||
⊢ AI理解: "广场上有豪华宗门招牌→生成最显眼的灵霄宗"
|
||||
⊢ 导演意图: "角落里有一个破旧招牌,被豪华招牌包围"
|
||||
⊢ 差异: AI生成了"主殿特写"而不是"角落特写"
|
||||
|
||||
═══════════════════════════════════════════════════════════════════
|
||||
|
||||
【S1-02】近景·5-10秒·"燃"(6)
|
||||
───────────────────────────────────────────────────────────────────
|
||||
导演编码要求:
|
||||
show: "苏白站在竖式悬挂牌匾下的全身·自信笑容·白色长衫"
|
||||
char: CHAR-003苏白
|
||||
prop_state: "悬挂的·破旧·竖式·木质牌匾"
|
||||
锁定文本: "18岁亚洲男性少年...白色长衫腰间束带...站在竖式悬挂牌匾下方"
|
||||
|
||||
实际帧分析 (ep01-06~10):
|
||||
□ 帧06-08: 竖式天道宗牌匾 ✓ (形态正确)
|
||||
└─ 问题1: 苏白 ❌ 未出现
|
||||
□ 帧09-10: 画面切换/模糊
|
||||
|
||||
关键偏差:
|
||||
⊢ AI理解: "特写牌匾" → 只生成牌匾
|
||||
⊢ 导演意图: "苏白站在牌匾下"
|
||||
⊢ 差异: 人物丢失
|
||||
|
||||
═══════════════════════════════════════════════════════════════════
|
||||
|
||||
【S1-03】中景·10-14秒·"冷"(4)
|
||||
───────────────────────────────────────────────────────────────────
|
||||
导演编码要求:
|
||||
show: "广告牌细节→围观者→落叶·苏白叹气"
|
||||
spatial_anchor: "竖式牌匾下方旁边的横式广告牌→苏白脚下"
|
||||
char: CHAR-003 (同S1-02·必须完全一致)
|
||||
|
||||
实际帧分析 (ep01-11~14):
|
||||
□ 帧11-14: 苏白出现 ✓
|
||||
├─ 问题1: 苏白面部 ❌ 明显扭曲/崩坏
|
||||
├─ 问题2: 牌匾形态变化 ❌ 从竖式细牌变成宽木牌
|
||||
├─ 问题3: 背景 ❌ 又是灵霄宗金色大殿(循环背景)
|
||||
└─ 问题4: 广告牌文字 ❌ 模糊/不清晰
|
||||
|
||||
关键偏差:
|
||||
⊢ AI问题1: 人物面部生成失败(Seedance人物一致性问题)
|
||||
⊢ AI问题2: 道具形态漂移(虽然用了锁定文本,但AI视觉理解不同)
|
||||
⊢ AI问题3: 背景理解固化("修仙广场=灵霄宗")
|
||||
|
||||
═══════════════════════════════════════════════════════════════════
|
||||
|
||||
【结构性问题诊断】
|
||||
───────────────────────────────────────────────────────────────────
|
||||
问题1: 镜头焦点错误
|
||||
现象: S1-01生成主殿而不是角落牌匾
|
||||
原因: "广场上...悬挂着...牌匾"被AI理解成背景描述而非主体
|
||||
修复方向: "特写:角落里的破旧竖式木质牌匾【天道宗】·字迹模糊·木头磨损"
|
||||
|
||||
问题2: 人物生成失败
|
||||
现象: S1-02没有苏白,S1-03苏白脸崩
|
||||
原因: Seedance对人物生成不稳定
|
||||
修复方向: 先出图(Seedream)确认人物→再用图参考送Seedance
|
||||
|
||||
问题3: 背景循环
|
||||
现象: 三镜全是同一个灵霄宗背景
|
||||
原因: "灵霄宗鎏金大字"在ENV锁定文本里→AI每镜都生成
|
||||
修复方向: S1-01/S1-02的背景描述改为"广场边缘·模糊人群"或"天空·云层"
|
||||
|
||||
问题4: 道具形态漂移
|
||||
现象: 牌匾竖式→宽木牌
|
||||
原因: 文字锁定≠视觉锁定
|
||||
修复方向: 必须用参考图+文字双重锁定
|
||||
|
||||
═══════════════════════════════════════════════════════════════════
|
||||
|
||||
【修复Prompt】
|
||||
───────────────────────────────────────────────────────────────────
|
||||
S1-01 修正:
|
||||
原: "修仙世界开阔广场...广场上...悬挂着...牌匾"
|
||||
改: "特写镜头: 广场人群边缘角落里,一块破旧的竖式悬挂木质牌匾【天道宗】清晰可见,字迹模糊木头老化,周围是模糊的人群和远处的金色建筑,焦点必须在牌匾上"
|
||||
|
||||
S1-02 修正:
|
||||
策略: 先出图→确认苏白+牌匾共存→再送视频
|
||||
图prompt: "18岁亚洲少年苏白,白色长衫,站在破旧的竖式悬挂【天道宗】牌匾正下方,双手叉腰,自信笑容,真人写实"
|
||||
|
||||
S1-03 修正:
|
||||
背景: 移除"灵霄宗鎏金大字",改为"广场地面·周围人群"
|
||||
人物: 必须用参考图
|
||||
|
||||
═══════════════════════════════════════════════════════════════════
|
||||
结论:
|
||||
连续性锁定解决了"文字描述一致",但AI视觉生成仍有不可控性。
|
||||
解决方案: 图参考环节(Seedream) + 视频生成(Seedance图参考)
|
||||
不是"做不到",是"流程缺一步"→补上即可。
|
||||
Loading…
x
Reference in New Issue
Block a user