diff --git a/video-ai-system/CURRENT.hdlp b/video-ai-system/CURRENT.hdlp index 2635037..1b29f5b 100644 --- a/video-ai-system/CURRENT.hdlp +++ b/video-ai-system/CURRENT.hdlp @@ -3,7 +3,7 @@ > HLDP://video-ai-system/CURRENT > 类型: 子系统官方置信入口 · 每次进入视频AI系统先读 > 创建: D140 · 2026-06-22 · Codex收口 -> 更新: D143 · 2026-06-23 · preview-002复盘·制片厂化重启 +> 更新: D144 · 2026-06-24 · 8模块验收·生产阻塞项确认 > 铸渊 ICE-GL-ZY001 · 冰朔 TCS-0002∞ > 国作登字-2026-A-00037559 @@ -133,6 +133,7 @@ JZAO外置盘: 产物存放地,不是状态主控。 | 苏白TTS配音 | ✅ 工程测试通过 | `video-ai-system/outputs/tests/TEST-TTS-001-SUBAI-RUN-001-REPORT.hdlp` | | 模型/成本路线 | ✅ 已建立 | `video-ai-system/knowledge/D144-MODEL-COST-ROUTE.hdlp` | | 腾讯AI开发交接 | ✅ 已建立 | `video-ai-system/plans/D144-TENCENT-AI-DEV-HANDOFF.hdlp` | +| 腾讯AI 8模块代码 | 🟡 部分通过 | `video-ai-system/experience/D144-8-MODULE-VERIFICATION.hdlp` · 框架入仓,但主角资产、多参考图、口型同步、EP01 CLI仍非生产可用 | | 广告牌资产 | ✅ 草案 | `video-ai-system/assets/props/PROP-FREE-AD-BOARD/manifest.hdlp` | | 广告牌文字贴图 | ✅ PNG已生成 | `video-ai-system/assets/props/PROP-FREE-AD-BOARD/texture/free-ad-board-texture.png` | | 百宗会场景资产 | ✅ 草案 | `video-ai-system/assets/envs/ENV-002-Baizonghui/manifest.hdlp` | @@ -149,10 +150,10 @@ JZAO外置盘: 产物存放地,不是状态主控。 当前正式任务: ``` -D143-VIDEO-AI-RESET: -从 preview-002 失败复盘和《渔乡守真心》样片对标开始,重新建立影视制作流程知识库、素材库、模型准入、对白口型测试、竖屏剪辑模板和经验闭环。 -不直接生成 preview-003。 -第一个突破测试是 2-3 秒“苏白说一句话”,第二个突破测试是“天道宗牌匾跨镜一致”。 +D144-VIDEO-AI-PRODUCTION-BLOCKERS: +腾讯AI 8模块已入仓并完成第一轮验收,但不能按“全部开发完成”验收。 +当前优先级仍是字幕商业标准工具链、真实口型同步、剧本原文锁定、主角资产包真实生成、多参考/合成一致性路线。 +任何模块不能把占位输出、复制输出、未验证API能力标记成生产成功。 ``` --- diff --git a/video-ai-system/engines/char-hero-design-packer/char-hero-design-packer.py b/video-ai-system/engines/char-hero-design-packer/char-hero-design-packer.py index fe40c12..65e623f 100644 --- a/video-ai-system/engines/char-hero-design-packer/char-hero-design-packer.py +++ b/video-ai-system/engines/char-hero-design-packer/char-hero-design-packer.py @@ -19,14 +19,23 @@ import os import sys import json import argparse +import shutil from pathlib import Path # 添加项目根目录到路径 PROJECT_ROOT = Path(__file__).parent.parent.parent sys.path.insert(0, str(PROJECT_ROOT / "engines")) -from image_api_adapter import generate_image, save_image -from hldp_prompt import expand_prompt +try: + from image_api_adapter import generate_image +except Exception as exc: + print(f"⚠️ Python图片生成适配器未接通: {exc}") + generate_image = None + +try: + from hldp_prompt import expand_prompt +except Exception: + expand_prompt = None class CharHeroDesignPacker: @@ -115,6 +124,14 @@ class CharHeroDesignPacker: print(f" 参考图: {candidate}") print(f" 提示词: {prompt[:100]}...") + if generate_image is None: + print(" ⚠️ 当前仓库只有 JS 图片适配器 image-api-adapter.js,未提供 Python generate_image。") + print(" ⚠️ 暂不能生成新主角资产;仅将候选图复制到 candidates/ 供人工/后续工具处理。") + fallback_path = self.candidates_dir / output_name + shutil.copy2(candidate, fallback_path) + print(f" 🟡 已复制候选图: {fallback_path}") + return None + try: result_path = generate_image( prompt=prompt, @@ -203,24 +220,24 @@ class CharHeroDesignPacker: prompts = { "front_half_body": f""" - {base_desc.get('visual_description', '中国古代修仙少年,16岁,白色长发,蓝色眼睛')} + {base_desc.get('visual_description', '中国古代修仙少年,16岁,主角辨识度强')} 正面半身像,胸部以上,面部清晰,眼神坚定, - 3D动画风格,皮克斯风格,统一渲染风格, + 3D国风漫剧风格,统一渲染风格, 高清,8K,最佳质量 """.strip(), "side_face": f""" {base_desc.get('visual_description', '中国古代修仙少年')} 侧脸45度,能看到面部轮廓和发型, - 3D动画风格,皮克斯风格,统一渲染风格, + 3D国风漫剧风格,统一渲染风格, 高清,8K,最佳质量 """.strip(), "full_body_costume": f""" {base_desc.get('visual_description', '中国古代修仙少年')} 全身像,站立姿势,完整展示服装细节, - 白色内衬,蓝色外袍,黑色腰带,棕色靴子, - 3D动画风格,皮克斯风格,统一渲染风格, + 服装细节必须来自角色资产清单,不得自由改色, + 3D国风漫剧风格,统一渲染风格, 高清,8K,最佳质量 """.strip(), @@ -229,7 +246,7 @@ class CharHeroDesignPacker: 表情表,网格布局,包含: 平静,微笑,大笑,生气,惊讶,悲伤, 每个表情单独一格,统一光照和背景, - 3D动画风格,皮克斯风格, + 3D国风漫剧风格, 高清,8K,最佳质量 """.strip(), } @@ -263,7 +280,7 @@ class CharHeroDesignPacker: if path: results["expression_sheet"] = path - # 更新 manifest + # 更新 manifest。只有四项资产都真实生成时才可进入 APPROVED。 self._update_manifest(results) print(f"\n✅ 资产包生成完成!") @@ -276,10 +293,20 @@ class CharHeroDesignPacker: """更新 manifest.hdlp""" print(f"\n📝 更新 manifest.hdlp...") + required_assets = {"front_half_body", "side_face", "full_body_costume", "expression_sheet"} + is_complete = required_assets.issubset(results.keys()) + approval_status = "APPROVED" if is_complete else "DRAFT_GENERATED" + type_label = "已批准" if is_complete else "待质检" + lock_note = ( + "⊢ 资产已批准,可用于成片镜头。" + if is_complete + else "⊢ 资产包尚未完整生成/质检,禁止作为成片锁定资产。" + ) + manifest_content = f"""# 资产清单 · {self.character_id} > HLDP://video-ai-system/assets/characters/{self.character_id}/manifest -> 类型: 角色资产 · 已批准 +> 类型: 角色资产 · {type_label} > 建立: D143 · 2026-06-23 > 更新: D144 · 2026-06-24 > 项目: 付费才能修仙 · EP01 @@ -289,7 +316,7 @@ class CharHeroDesignPacker: ## 状态 ``` -approval_status: APPROVED +approval_status: {approval_status} asset_type: character canonical_id: {self.character_id} canonical_name: 苏白 @@ -311,19 +338,19 @@ expression_sheet: {results.get("expression_sheet", "NOT_GENERATED")} ## 视觉锁 ``` -face_shape: 少年脸,柔和轮廓,白色长发 -hair_style: 白色长发,束发,有发带 -costume: 白色内衬 + 蓝色外袍 + 黑色腰带 + 棕色靴子 +face_shape: TODO_FROM_APPROVED_ASSET +hair_style: TODO_FROM_APPROVED_ASSET +costume: TODO_FROM_APPROVED_ASSET age_band: 16岁 -render_style: 3D动画,皮克斯风格,明亮色彩 -color_palette: 白,蓝,黑,棕 +render_style: 3D国风漫剧 +color_palette: TODO_FROM_APPROVED_ASSET ``` --- ## 锁定 -⊢ 资产已批准,可用于成片镜头。 +{lock_note} ⊢ 禁止使用 candidates/ 或 rejected/ 中的图片作为最终资产。 """ diff --git a/video-ai-system/engines/character-distinctiveness-qc/character-distinctiveness-qc.py b/video-ai-system/engines/character-distinctiveness-qc/character-distinctiveness-qc.py index 16724c4..f0cfd2e 100644 --- a/video-ai-system/engines/character-distinctiveness-qc/character-distinctiveness-qc.py +++ b/video-ai-system/engines/character-distinctiveness-qc/character-distinctiveness-qc.py @@ -270,6 +270,14 @@ class CharacterDistinctivenessQC: return results + def save_report(self, result, output_path): + """保存单张或批量评估报告""" + output_path = Path(output_path) + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, "w", encoding="utf-8") as f: + json.dump(result, f, ensure_ascii=False, indent=2) + print(f"\n 报告已保存: {output_path}") + def _generate_batch_report(self, results): """生成批量评估报告""" print(f"\n📊 批量评估报告") @@ -301,6 +309,7 @@ def main(): parser.add_argument("--character", type=str, default="CHAR-003-SuBai", help="角色ID (默认: CHAR-003-SuBai)") parser.add_argument("--batch", type=str, help="批量评估目录") + parser.add_argument("--output", type=str, help="输出 JSON 报告路径") args = parser.parse_args() @@ -314,9 +323,13 @@ def main(): result = qc.evaluate_image(args.image) print(f"\n📋 评估详情:") print(json.dumps(result, ensure_ascii=False, indent=2)) + if args.output: + qc.save_report(result, args.output) elif args.batch: results = qc.evaluate_batch(args.batch) + if args.output: + qc.save_report(results, args.output) if __name__ == "__main__": diff --git a/video-ai-system/engines/lipsync-adapter.py b/video-ai-system/engines/lipsync-adapter.py index 8d3f608..e8c3e0b 100644 --- a/video-ai-system/engines/lipsync-adapter.py +++ b/video-ai-system/engines/lipsync-adapter.py @@ -33,8 +33,9 @@ sys.path.insert(0, str(PROJECT_ROOT / "engines")) class LipSyncAdapter: """口型适配器""" - def __init__(self, wav2lip_path=None): + def __init__(self, wav2lip_path=None, allow_fallback=False): self.wav2lip_path = wav2lip_path or PROJECT_ROOT / "tools" / "Wav2Lip" + self.allow_fallback = allow_fallback self.available = self._check_wav2lip() def _check_wav2lip(self): @@ -53,7 +54,7 @@ class LipSyncAdapter: print(f"✅ Wav2Lip 已安装: {self.wav2lip_path}") return True - def sync_lips(self, video_path, audio_path, output_path=None): + def sync_lips(self, video_path, audio_path, output_path=None, allow_fallback=None): """ 口型同步 @@ -98,9 +99,20 @@ class LipSyncAdapter: result = self._run_wav2lip(video_path, audio_path, output_path) return result - # 方法2: 回退 (不处理,只复制视频) - print(f" ⚠️ Wav2Lip 不可用,回退到不处理模式") - print(f" 💡 提示: 安装 Wav2Lip 以获得口型同步能力") + fallback_enabled = self.allow_fallback if allow_fallback is None else allow_fallback + if not fallback_enabled: + print(f" ❌ Wav2Lip 不可用,口型同步未执行") + print(f" 💡 如需调试占位输出,可显式传入 --allow-fallback-copy") + return { + "success": False, + "error": "Wav2Lip 不可用,未执行真实口型同步", + "method": "not-run", + "requires": "Install Wav2Lip and checkpoint wav2lip_gan.pth" + } + + # 调试回退: 不处理,只复制视频。必须显式开启,避免生产线假阳性。 + print(f" ⚠️ Wav2Lip 不可用,按 --allow-fallback-copy 复制原视频") + print(f" 💡 注意: 该输出不是口型同步成品") import shutil shutil.copy2(video_path, output_path) @@ -109,7 +121,7 @@ class LipSyncAdapter: "success": True, "output_path": str(output_path), "method": "fallback(copy)", - "warning": "Wav2Lip 不可用,口型未同步。请安装 Wav2Lip。" + "warning": "Wav2Lip 不可用,口型未同步。该文件只能用于调试占位。" } def _run_wav2lip(self, video_path, audio_path, output_path): @@ -247,6 +259,8 @@ def main(): parser.add_argument("--batch", type=str, help="批量处理配置文件 (JSON)") parser.add_argument("--wav2lip-path", type=str, help="Wav2Lip 安装路径") parser.add_argument("--check-sync", action="store_true", help="检查口型同步质量") + parser.add_argument("--allow-fallback-copy", action="store_true", + help="仅调试用: Wav2Lip 不可用时复制原视频并标记为 fallback") args = parser.parse_args() @@ -276,7 +290,7 @@ def main(): output_dir = config.get("output_dir", "./outputs/lipsync/") - adapter = LipSyncAdapter(args.wav2lip_path) + adapter = LipSyncAdapter(args.wav2lip_path, allow_fallback=args.allow_fallback_copy) results = adapter.batch_sync(video_audio_pairs, output_dir) sys.exit(0) @@ -285,7 +299,7 @@ def main(): parser.print_help() sys.exit(1) - adapter = LipSyncAdapter(args.wav2lip_path) + adapter = LipSyncAdapter(args.wav2lip_path, allow_fallback=args.allow_fallback_copy) result = adapter.sync_lips(args.video, args.audio, args.output) if result["success"]: diff --git a/video-ai-system/engines/multi-reference-video-adapter.py b/video-ai-system/engines/multi-reference-video-adapter.py index 37acf0e..48e2a26 100644 --- a/video-ai-system/engines/multi-reference-video-adapter.py +++ b/video-ai-system/engines/multi-reference-video-adapter.py @@ -30,34 +30,43 @@ from datetime import datetime PROJECT_ROOT = Path(__file__).parent.parent sys.path.insert(0, str(PROJECT_ROOT / "engines")) -# 从环境变量加载 API 配置 def load_api_config(): - """从 video-ai-system/.env 加载配置""" + """从仓库 .env、本机密钥文件和环境变量加载配置""" config = {} - env_file = PROJECT_ROOT / ".env" - if env_file.exists(): - with open(env_file, "r") as f: + env_files = [ + PROJECT_ROOT / ".env", + Path.home() / "guanghulab-local-secrets" / "video-ai-system.env", + ] + for env_file in env_files: + if not env_file.exists(): + continue + with open(env_file, "r", encoding="utf-8") as f: for line in f: line = line.strip() if line and not line.startswith("#"): key, _, val = line.partition("=") - config[key.strip()] = val.strip() + config[key.strip()] = val.strip().strip('"').strip("'") + for key in ["JIMENG_API_KEY", "JIMENG_BASE_URL", "JIMENG_MODEL"]: + if os.environ.get(key): + config[key] = os.environ[key] return config class MultiReferenceVideoAdapter: """多参考图视频适配器""" - def __init__(self): + def __init__(self, live_capability_check=False, allow_single_reference_fallback=False): self.config = load_api_config() self.api_key = self.config.get("JIMENG_API_KEY", "") self.base_url = self.config.get("JIMENG_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3") self.model = self.config.get("JIMENG_MODEL", "doubao-seedance-2-0-260128") + self.live_capability_check = live_capability_check + self.allow_single_reference_fallback = allow_single_reference_fallback # API 能力探测结果缓存 self._api_capabilities = None - def check_api_capabilities(self): + def check_api_capabilities(self, live=None): """ 检查 API 是否支持多参考图 返回: { @@ -70,6 +79,7 @@ class MultiReferenceVideoAdapter: if self._api_capabilities: return self._api_capabilities + live = self.live_capability_check if live is None else live print("🔍 检查 Seedance API 多参考图支持...") # 根据 Volcengine 官方文档 (https://www.volcengine.com/docs/82379/1520757) @@ -83,8 +93,17 @@ class MultiReferenceVideoAdapter: # { type: "image_url", image_url: { url: "data:image/png;base64,..." } }, # 第二张参考图 # ] - # 实际测试: 尝试提交一个包含2张参考图的请求,看是否报错 - test_result = self._test_multi_reference() + if not live: + test_result = { + "multi_reference_supported": False, + "max_references": 1, + "supported_types": ["image_url"], + "status": "unverified", + "details": "未执行付费/联网实测;需要 --live-check 才会提交真实 API 探测任务", + "requires_live_check": True + } + else: + test_result = self._test_multi_reference() self._api_capabilities = test_result return test_result @@ -94,6 +113,15 @@ class MultiReferenceVideoAdapter: 实际测试 API 是否支持多参考图 方法: 提交一个测试请求,包含2张参考图,观察响应 """ + if not self.api_key: + return { + "multi_reference_supported": False, + "max_references": 1, + "supported_types": ["image_url"], + "details": "未找到 JIMENG_API_KEY,无法执行 live check", + "status": "missing_api_key" + } + # 构造一个最小测试请求 test_prompt = "test multi-reference support" @@ -216,7 +244,16 @@ class MultiReferenceVideoAdapter: print(f" 2. 后期合成牌匾/场景 (平面追踪 + 贴图)") print(f" 3. 或使用可灵生成角色,Seedance 生成场景,后期合成") - # 回退: 只用第一张参考图 + if not self.allow_single_reference_fallback: + return { + "success": False, + "method": "not-run", + "error": "多参考图能力未确认或不支持,未自动回退单参考图以避免误导一致性测试", + "capabilities": capabilities, + "next_step": "使用 --live-check 验证多参考图,或显式传入 --allow-single-reference-fallback 做调试占位" + } + + # 回退: 只用第一张参考图。必须显式开启,避免误导牌匾/场景一致性判断。 warning = "API不支持多参考图,已回退到单参考图模式。牌匾/场景一致性需要后期合成。" print(f"\n 🔄 回退: 使用第一张参考图生成...") @@ -336,6 +373,10 @@ class MultiReferenceVideoAdapter: def main(): parser = argparse.ArgumentParser(description="MULTI-REFERENCE-VIDEO-ADAPTER") parser.add_argument("--check-api", action="store_true", help="检查API多参考图支持") + parser.add_argument("--live-check", action="store_true", + help="执行真实 API 探测请求,可能产生费用") + parser.add_argument("--allow-single-reference-fallback", action="store_true", + help="多参考图不可用时允许单参考图调试占位") parser.add_argument("--prompt", type=str, help="提示词") parser.add_argument("--references", type=str, nargs="+", help="参考图路径列表") parser.add_argument("--output", type=str, help="输出路径") @@ -344,10 +385,13 @@ def main(): args = parser.parse_args() - adapter = MultiReferenceVideoAdapter() + adapter = MultiReferenceVideoAdapter( + live_capability_check=args.live_check, + allow_single_reference_fallback=args.allow_single_reference_fallback + ) if args.check_api: - capabilities = adapter.check_api_capabilities() + capabilities = adapter.check_api_capabilities(live=args.live_check) print(f"\n📊 API 能力报告:") print(f" 多参考图支持: {capabilities['multi_reference_supported']}") print(f" 最大参考图数: {capabilities['max_references']}") diff --git a/video-ai-system/engines/shot-qc-automation.py b/video-ai-system/engines/shot-qc-automation.py index cc754bf..cca1cd4 100644 --- a/video-ai-system/engines/shot-qc-automation.py +++ b/video-ai-system/engines/shot-qc-automation.py @@ -585,7 +585,12 @@ def main(): print(f"\n⚠️ QC 跳过 (依赖不可用)") sys.exit(0) else: - print(f"\n❌ QC 失败: {result.get('error', 'Unknown error')}") + if result.get("error"): + print(f"\n❌ QC 失败: {result['error']}") + else: + issues = result.get("issues") or [] + issue_text = ";".join(issues) if issues else "未通过阈值" + print(f"\n❌ QC 未通过: {issue_text}") sys.exit(1) diff --git a/video-ai-system/engines/voice-emotion-compiler.py b/video-ai-system/engines/voice-emotion-compiler.py index e0aec8e..340822f 100644 --- a/video-ai-system/engines/voice-emotion-compiler.py +++ b/video-ai-system/engines/voice-emotion-compiler.py @@ -20,17 +20,24 @@ import os import sys import json import argparse +import importlib.util from pathlib import Path from datetime import datetime PROJECT_ROOT = Path(__file__).parent.parent sys.path.insert(0, str(PROJECT_ROOT / "engines")) -# 导入现有的 TTS 引擎 +# 导入现有的 TTS 引擎。文件名是 tts-engine.py,不能用普通 import。 +tts_engine_path = PROJECT_ROOT / "engines" / "tts-engine.py" try: - from tts_engine import generate_speech, generate_by_character, load_voice_config -except ImportError: - print("⚠️ 无法导入 tts-engine,将使用简化模式") + spec = importlib.util.spec_from_file_location("tts_engine", tts_engine_path) + tts_engine = importlib.util.module_from_spec(spec) + spec.loader.exec_module(tts_engine) + generate_speech = tts_engine.generate_speech + generate_by_character = tts_engine.generate_by_character + load_voice_config = tts_engine.load_voice_config +except Exception as exc: + print(f"⚠️ 无法导入 tts-engine,将使用简化模式: {exc}") generate_speech = None generate_by_character = None @@ -270,7 +277,7 @@ class VoiceEmotionCompiler: variants = [ {"label": "基准", "params": base_params}, - {"label": "语速+10%", "params": {**base_params, "rate": f"+{int(base_params['rate'].strip('%+')) + 10}%"}, + {"label": "语速+10%", "params": {**base_params, "rate": f"+{int(base_params['rate'].strip('%+')) + 10}%"}}, {"label": "音调+5Hz", "params": {**base_params, "pitch": f"+{int(base_params['pitch'].strip('Hz+')) + 5}Hz"}}, {"label": "音量+10%", "params": {**base_params, "volume": f"+{int(base_params['volume'].strip('%+')) + 10}%"}}, ] diff --git a/video-ai-system/experience/D144-8-MODULE-VERIFICATION.hdlp b/video-ai-system/experience/D144-8-MODULE-VERIFICATION.hdlp new file mode 100644 index 0000000..74c8003 --- /dev/null +++ b/video-ai-system/experience/D144-8-MODULE-VERIFICATION.hdlp @@ -0,0 +1,263 @@ +# D144 · 视频AI系统8模块验收记录 + +> HLDP://video-ai-system/experience/D144-8-MODULE-VERIFICATION +> 日期: 2026-06-24 +> 入口: 腾讯AI提交的 8 大模块工程验收 +> 结论: 框架已进入仓库,但不能整体视为生产完成;需要按下方缺口继续补齐。 + +--- + +## 总结 + +``` +overall_status: PARTIAL_PASS +production_ready: false +main_blockers: + - 主角资产包生成未真正接通图片生成适配器 + - 口型同步依赖 Wav2Lip 未安装,不能解决“人物说台词” + - 多参考图能力未做真实付费验证,默认不能用于一致性承诺 + - EP01 一键生产 CLI 仍读取占位台词,不满足“剧本怎么写就怎么拍” + - 字幕标准工具链仍需独立开发,不在本次8模块内完成 +``` + +--- + +## 模块验收 + +### 1. CHAR-HERO-DESIGN-PACKER + +``` +status: NOT_READY +syntax: PASS_AFTER_FIX +production_ready: false +``` + +发现: +- 原代码直接导入不存在的 Python `image_api_adapter`,仓库当前只有 JS 图片适配器,启动即崩。 +- 原代码会在资产不完整时把 `manifest.hdlp` 写成 `APPROVED`,会污染后续角色锁定。 +- 原提示词带有未经剧本/资产锁确认的视觉默认值,例如白发、蓝眼、蓝袍、皮克斯风格,容易造成角色漂移。 + +已修: +- 图片适配器未接通时不崩溃,明确提示未生成。 +- 只有 4/4 资产完整生成时才允许 `APPROVED`;否则为 `DRAFT_GENERATED`。 +- 默认风格改为 3D国风漫剧,并要求服装来自角色资产清单,不得自由改色。 + +后续: +- 需要开发 Python 到现有 JS 图片适配器的桥接,或统一改成 Node CLI 调用。 +- 需要把“主角辨识度设计稿/正侧全身/表情表/色彩锁”作为独立资产包生成和人工确认流程。 + +--- + +### 2. CHARACTER-DISTINCTIVENESS-QC + +``` +status: PARTIAL_PASS +syntax: PASS +report_output: PASS_AFTER_FIX +production_ready: false +``` + +实测: +- 输入 `video-ai-system/assets/references/EP01-P0/ref-char003-subai-plus-tdz-plaque.png` +- 输出 `/tmp/guanghulab-module-check/character-qc.json` +- 结果: `overall_score: 6.35/10`, `verdict: FAIL` + +说明: +- 这个结论与编辑意见“主角太普通、像路人甲”一致。 +- 当前算法是基础 OpenCV 分数,只能做第一层粗筛,不能替代人眼/多模型视觉评审。 + +已修: +- 增加 `--output`,允许质检报告落盘进入经验库。 + +后续: +- 接入图像理解模型做“主角感/路人感/记忆点”语义评分。 +- 加入同镜头前后角色一致性对比,而不是只看单张图。 + +--- + +### 3. MULTI-REFERENCE-VIDEO-ADAPTER + +``` +status: GUARDED_NOT_VERIFIED +syntax: PASS +production_ready: false +``` + +发现: +- 原 `--check-api` 会直接提交真实视频生成请求,可能产生费用。 +- 原代码只读仓库 `.env`,不读本机密钥文件。 +- 多参考图未确认时自动回退单参考图,会误导牌匾/角色/场景一致性判断。 + +已修: +- 默认 `--check-api` 只做无付费预检。 +- 只有显式传入 `--live-check` 才会提交真实 API 探测请求。 +- 读取本机 `~/guanghulab-local-secrets/video-ai-system.env`。 +- 多参考图未确认时不自动回退;只有显式 `--allow-single-reference-fallback` 才允许调试占位。 + +后续: +- 需要一次受控 live-check,确认 Seedance/豆包视频 API 是否真支持多参考图。 +- 如果不支持,必须走“角色视频 + 牌匾/场景后期合成”的工程路线。 + +--- + +### 4. VOICE-EMOTION-COMPILER + +``` +status: PASS_FOR_TTS_PARAM_COMPILE +syntax: PASS_AFTER_FIX +production_ready: partial +``` + +发现: +- 原代码有语法错误。 +- 原代码用普通 import 导入 `tts-engine.py`,文件名含连字符,无法导入。 + +已修并实测: +- 修复语法错误。 +- 用动态导入接上 `tts-engine.py`。 +- 实测生成苏白情绪配音 MP3 成功: `/tmp/guanghulab-module-check/subai-emotion.mp3` + +后续: +- Edge-TTS 可做低成本测试,但商业成片建议继续 A/B 测豆包语音、火山语音或更适合角色对白的声音模型。 +- 需要按角色建立“台词情绪标签 -> 音色/语速/音高/停顿”表。 + +--- + +### 5. LIPSYNC-ADAPTER + +``` +status: FAIL_DEPENDENCY_MISSING +syntax: PASS_AFTER_FIX +production_ready: false +``` + +发现: +- Wav2Lip 未安装。 +- 原代码在 Wav2Lip 不可用时复制原视频并返回成功,会把“没做口型”伪装为“口型完成”。 + +已修: +- 默认无 Wav2Lip 时返回失败。 +- 只有显式传入 `--allow-fallback-copy` 才允许复制原视频,并标记为调试占位。 + +实测: +- 当前返回失败: `Wav2Lip 不可用,未执行真实口型同步` + +后续: +- 安装 Wav2Lip 或改接可商用口型/视频驱动 API。 +- 需要口型 QC:音频峰值与嘴部开合是否同步,不能只看生成成功。 + +--- + +### 6. AUDIO-MIXER + +``` +status: BASIC_PASS +production_ready: partial +``` + +实测: +- 单音轨输出成功: `/tmp/guanghulab-module-check/mix-single.mp3` + +缺口: +- 当前对白压低 BGM 是简化处理,不是真正精细侧链压缩。 +- 需要对白优先、BGM 自动 ducking、响度标准、峰值保护、短视频平台响度目标。 + +后续: +- 开发基于 FFmpeg sidechaincompress / loudnorm 的商业混音预设。 +- 输出混音 QC 报告:对白响度、BGM 响度、峰值、电平余量。 + +--- + +### 7. SHOT-QC-AUTOMATION + +``` +status: PARTIAL_PASS +syntax: PASS +production_ready: false +``` + +实测: +- 输入移动硬盘样片: `TEST-SUBTITLE-007-RUN002-REFERENCE-DRAMA.mp4` +- 输出 `/tmp/guanghulab-module-check/qc-after-fix.json` +- 结果: 检测到横屏 `1112x834`,失败原因 `竖屏比例错误` + +已修: +- 原 CLI 失败时只显示 `Unknown error`;已改成输出真实失败项。 +- 依赖清单补充 `numpy`, `opencv-python`, `requests`。 + +缺口: +- OCR 未安装,字幕/牌匾文字检查被跳过。 +- 现代物品检测仍是 TODO。 +- 换脸检查只是粗糙直方图,不足以判定角色一致性。 + +后续: +- 安装/配置 OCR。 +- 接 YOLO 或视觉模型做现代物品、遮挡、文字、角色漂移检查。 + +--- + +### 8. EP01-SHOT03-PRODUCTION-CLI + +``` +status: DRY_RUN_ONLY +syntax: PASS +production_ready: false +``` + +实测: +- `--dry-run` 可执行完整步骤列表。 + +重大问题: +- 配置读取仍显示 `台词: 苏白原文台词`,不是剧本原文台词。 +- 这不满足用户要求:剧本怎么写,就怎么拍;不能用占位台词进入生产。 + +后续: +- 必须接入剧本/分镜头源文件,逐字锁定台词。 +- 每个镜头需要输出“剧本文本 -> 提示词 -> 画面 -> 配音 -> 字幕”的可追溯链路。 + +--- + +## 本次工程修复清单 + +``` +fixed_files: + - engines/voice-emotion-compiler.py + - engines/char-hero-design-packer/char-hero-design-packer.py + - engines/character-distinctiveness-qc/character-distinctiveness-qc.py + - engines/lipsync-adapter.py + - engines/multi-reference-video-adapter.py + - engines/shot-qc-automation.py + - requirements-video-ai.txt +``` + +--- + +## 下一步优先级 + +``` +P0: + - 字幕商业标准渲染工具链 + - 真实口型同步方案 + - 剧本原文锁定与 EP01 CLI 台词读取修复 + - 主角资产包真实生成与人工确认 + +P1: + - 多参考图 live-check + - 角色一致性跨镜头 QC + - BGM/对白混音 loudness + ducking + +P2: + - OCR/牌匾文字 QC + - 现代物品检测 + - 成本账本与模型可用性检查 +``` + +--- + +## 验收结论 + +``` +腾讯AI这次提交的8个模块,不能按“全部开发完成”验收。 +准确结论是: 工程骨架已建立,其中语音参数编译、基础混音、基础QC可继续用; +主角资产生成、多参考视频、口型同步、EP01一键生产仍是生产阻塞项。 +``` diff --git a/video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS.hdlp b/video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS.hdlp index 88405af..944eabf 100644 --- a/video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS.hdlp +++ b/video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS.hdlp @@ -1,7 +1,7 @@ # 付费才能修仙 · 3D漫剧主线 · 项目状态 > HLDP://video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS -> 更新: D143 · 2026-06-23 · preview-002复盘·制片厂化重启 +> 更新: D144 · 2026-06-24 · 8模块验收·生产阻塞项确认 > 铸渊 ICE-GL-ZY001 > 国作登字-2026-A-00037559 @@ -119,6 +119,7 @@ preview-003: 暂不生成。 | 苏白TTS配音 | ✅ 工程测试通过 | `outputs/tests/TEST-TTS-001-SUBAI-RUN-001-REPORT.hdlp` | | 模型/成本路线 | ✅ 已建立 | `knowledge/D144-MODEL-COST-ROUTE.hdlp` | | 腾讯AI开发交接 | ✅ 已建立 | `plans/D144-TENCENT-AI-DEV-HANDOFF.hdlp` | +| 腾讯AI 8模块代码 | 🟡 部分通过 | `experience/D144-8-MODULE-VERIFICATION.hdlp` · 框架已入仓,生产阻塞项仍在 | | 广告牌资产 | ✅ 草案 | `assets/props/PROP-FREE-AD-BOARD/manifest.hdlp` | | 广告牌文字贴图 | ✅ PNG已生成 | `assets/props/PROP-FREE-AD-BOARD/texture/free-ad-board-texture.png` | | 百宗会场景资产 | ✅ 草案 | `assets/envs/ENV-002-Baizonghui/manifest.hdlp` | @@ -218,6 +219,11 @@ preview-003: 暂不生成。 - [ ] 开发 reference-subtitle-analyzer / ASS渲染 / 字体管理 / 安全区QC 字幕工具链 - [x] 重定性 RUN-002: 牌匾一致性失败,但百宗会人群氛围可用 - [x] 测试苏白Edge-TTS工程配音 → `outputs/tests/TEST-TTS-001-SUBAI-RUN-001-REPORT.hdlp` +- [x] 验收腾讯AI 8模块代码 → `experience/D144-8-MODULE-VERIFICATION.hdlp` +- [ ] 接通主角资产包真实图片生成适配器,禁止未完整资产写入 APPROVED +- [ ] 安装或替换真实口型同步方案,禁止复制视频冒充口型完成 +- [ ] 修复 EP01-SHOT03 CLI 台词读取,占位台词不得进入生产 +- [ ] 受控验证 Seedance/豆包视频多参考图能力,未验证前不得承诺跨镜一致 - [x] 建立模型/成本路线 → `knowledge/D144-MODEL-COST-ROUTE.hdlp` - [x] 建立腾讯AI人格体开发交接清单 → `plans/D144-TENCENT-AI-DEV-HANDOFF.hdlp` - [ ] 生成E1-SHOT03专用苏白底片: 上方/身后预留牌匾空间 diff --git a/video-ai-system/requirements-video-ai.txt b/video-ai-system/requirements-video-ai.txt index 8f3ab0b..fa9ce37 100644 --- a/video-ai-system/requirements-video-ai.txt +++ b/video-ai-system/requirements-video-ai.txt @@ -2,3 +2,10 @@ edge-tts>=7.2.8 pysrt>=1.1.2 cairosvg>=2.9.0 Pillow>=12.2.0 +numpy>=2.0.0 +opencv-python>=4.10.0 +requests>=2.32.0 + +# Optional production QC dependencies: +# pytesseract>=0.3.13 # requires system tesseract binary +# ultralytics>=8.3.0 # modern-item detection, not wired yet