12032 lines
481 KiB
Markdown
12032 lines
481 KiB
Markdown
# CODEX_PROGRESS.md
|
||
|
||
## 当前项目阶段
|
||
|
||
当前阶段:生产化补齐进行中(真实图片/TTS/视频资产落库、国内/海外可替换真实视频 Provider 驱动、后台用户高危操作、成本阈值、队列 worker 消费、细粒度 RBAC、审计导出、单句 TTS 连续重试片段元数据保留、本地存储路径稳定化、成本优化策略硬落地、AI Router V1、Router 队列化 V1、爆款诊断 V1、Prompt Library / 题材套路库前台化 V1、模式库运营闭环 V1、真人视频小样预检 / 验收闭环 V1、真人小样测试台 V1、真人视频真实 Provider 小样验收脚本 V1、真人视频 Prompt Engine V1、MiniMax LipSyncProvider 占位接入、首条真人短剧一集压测用例整理、压测项目导入/Prompt准备和 Mock 全链路成片验收已完成)
|
||
|
||
## 已完成阶段
|
||
|
||
- 阶段 00:读取 docs 并输出开发计划
|
||
- 阶段 01:初始化项目骨架
|
||
- 阶段 02:数据库 schema
|
||
- 阶段 03:用户认证
|
||
- 阶段 04:文件上传和 MinIO
|
||
- 阶段 05:项目创建流程
|
||
- 阶段 06:上传小说解析
|
||
- 阶段 07:AI 原创小说 mock
|
||
- 阶段 08:故事圣经
|
||
- 阶段 09:角色圣经
|
||
- 阶段 10:长篇记忆
|
||
- 阶段 11:分集计划
|
||
- 阶段 12:脚本和分镜
|
||
- 阶段 13:BullMQ 队列
|
||
- 阶段 14:AI Provider 抽象
|
||
- 阶段 15:图片生成 mock
|
||
- 阶段 16:TTS / 字幕 / FFmpeg
|
||
- 阶段 17:后台管理
|
||
- 阶段 18:uni-app 用户端
|
||
- 阶段 19:订单额度
|
||
- 阶段 20:内容审核
|
||
- 阶段 21:真实 AI Provider 接入
|
||
- 阶段 22:MVP 验收
|
||
- 阶段 23:API 加密传输
|
||
- 生产化优化:单句 TTS 连续重试片段元数据保留
|
||
- 生产化修复:后台视频预览本地存储路径稳定化
|
||
- 生产化优化:成本优化策略硬落地
|
||
- 生产化优化:AI Router V1 / 镜头评分 / 自动选模型
|
||
- 生产化优化:质检任务化 / Router 队列化 V1
|
||
- 生产化优化:爆款诊断 / 拉片分析 V1
|
||
- 生产化优化:Prompt Library / 题材套路库 / IP 设定宇宙前台化 V1
|
||
- 生产化优化:模式库运营闭环 V1
|
||
- 生产化优化:真人视频小样预检 / 验收闭环 V1
|
||
- 生产化优化:真人小样测试台 V1
|
||
- 生产化优化:真人视频真实 Provider 小样验收脚本 V1
|
||
- 生产化优化:真人视频 Prompt Engine V1
|
||
- 生产化优化:MiniMax LipSyncProvider 占位接入
|
||
- 生产化优化:首条真人短剧一集压测用例整理
|
||
- 生产化优化:首条真人短剧压测项目导入 / Prompt 准备
|
||
- 生产化优化:首条真人短剧 Mock 全链路成片验收
|
||
|
||
## 正在进行
|
||
|
||
- 生产化上线补齐与验收
|
||
|
||
## 待开发阶段
|
||
|
||
- 生产环境真实 Key / 真实 Sora 付费调用 E2E 验收
|
||
- 更细的权限表 UI、权限配置页面和多租户数据范围策略
|
||
|
||
## 阶段记录
|
||
|
||
### 阶段 00:读取 docs 并输出开发计划
|
||
|
||
完成时间:2026-05-31 17:00:00 CST
|
||
|
||
完成内容:
|
||
|
||
- 读取并梳理 docs/system_a 核心文档。
|
||
- 明确系统 A MVP 为 AI 原创小说 3 集 MP4 与上传小说 1 集 MP4 两条闭环。
|
||
- 标记阶段编号、数据库补充字段、队列清单、上传格式、支付额度前置等待确认点。
|
||
|
||
修改文件:
|
||
|
||
- 无
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- find docs/system_a -maxdepth 1 -type f
|
||
- wc -l docs/system_a/*.md
|
||
- rg 文档标题
|
||
- sed 阅读核心文档
|
||
|
||
测试结果:
|
||
|
||
- 只读阶段,无代码测试。
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,无法执行 git status。
|
||
|
||
下一步建议:
|
||
|
||
- 进入阶段 01:初始化项目骨架。
|
||
|
||
### 阶段 01:初始化项目骨架
|
||
|
||
完成时间:2026-05-31 17:03:26 CST
|
||
|
||
完成内容:
|
||
|
||
- 创建 npm workspaces monorepo。
|
||
- 初始化 backend 为最小 NestJS API 服务。
|
||
- 初始化 admin 为 Geeker-Admin 可接入的 Vue/Vite 后台骨架。
|
||
- 初始化 user-app 为带 manifest/pages 配置的用户端 H5 骨架,保留后续 uni-app 接入位置。
|
||
- 初始化 workers 作为后续 BullMQ / FFmpeg worker 入口。
|
||
- 初始化 deploy 与本地 MySQL、Redis、MinIO docker-compose.dev.yml。
|
||
- 创建 .env.example、README.md、storage 占位目录。
|
||
|
||
修改文件:
|
||
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- package.json
|
||
- package-lock.json
|
||
- tsconfig.base.json
|
||
- .gitignore
|
||
- .env.example
|
||
- README.md
|
||
- backend/
|
||
- admin/
|
||
- user-app/
|
||
- workers/
|
||
- deploy/
|
||
- storage/
|
||
|
||
运行命令:
|
||
|
||
- node -v
|
||
- npm -v
|
||
- npm install
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- npm run dev:backend
|
||
- npm run dev:admin
|
||
- npm run dev:user
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5175
|
||
- curl -I http://127.0.0.1:5174
|
||
|
||
测试结果:
|
||
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 1 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后台骨架 HTTP 200
|
||
- 用户端 H5 骨架 HTTP 200
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm install 后 audit 提示 13 个依赖风险,暂未执行 npm audit fix --force,避免阶段 01 被破坏性升级影响。
|
||
- user-app 当前是可运行 H5 骨架,并保留 manifest/pages 配置;完整 uni-app 插件接入留到用户端阶段。
|
||
- 5173 端口已有其他 Node 进程占用,本阶段后台改用 5175。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 01。
|
||
- 审核通过后进入阶段 02:数据库 schema。
|
||
|
||
### 阶段 02:数据库 schema
|
||
|
||
完成时间:2026-05-31 17:17:57 CST
|
||
|
||
完成内容:
|
||
|
||
- 选择 Prisma 6.19.3 作为 MySQL 8 ORM。
|
||
- 根据 docs/system_a/05 及相关订单、Provider、审核、日志文档创建 30 张核心表模型。
|
||
- 覆盖 users、projects、novel_sources、novel_chapters、copyright_records、story_bibles、world_bibles、characters、character_images、character_memories、episodes、episode_scripts、storyboard_shots、shot_images、plot_memories、plot_threads、continuity_checks、assets、render_tasks、provider_configs、provider_logs、orders、quota_accounts、quota_logs、revision_requests、content_reviews、case_showcases、analytics_events、system_configs、operation_logs。
|
||
- 添加核心唯一约束和索引:用户邮箱/手机号、项目状态、章节顺序、角色类型、分集编号、分镜顺序、任务幂等 key、Provider 配置、订单号、额度账户等。
|
||
- 生成初始 migration.sql。
|
||
- 创建 seed.ts,包含管理员示例用户、mock TextProvider、系统阶段配置、示例额度账户。
|
||
- 在 README.md 补充数据库命令和 ORM 选择说明。
|
||
|
||
修改文件:
|
||
|
||
- package.json
|
||
- package-lock.json
|
||
- backend/package.json
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/prisma/schema.prisma
|
||
- backend/prisma/migrations/20260531093000_init_system_a/migration.sql
|
||
- backend/prisma/seed.ts
|
||
|
||
运行命令:
|
||
|
||
- npm view prisma@6 version --json
|
||
- npm install -w backend @prisma/client@6.19.3
|
||
- npm install -D -w backend prisma@6.19.3
|
||
- DATABASE_URL=... npm run db:validate
|
||
- DATABASE_URL=... npm run prisma:generate -w backend
|
||
- npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script --output prisma/migrations/20260531093000_init_system_a/migration.sql
|
||
- DATABASE_URL=... npm run prisma:migrate -w backend -- --name init_system_a --create-only
|
||
- npx tsc --noEmit --target ES2022 --module CommonJS --moduleResolution Node --esModuleInterop --skipLibCheck --strict backend/prisma/seed.ts
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
|
||
测试结果:
|
||
|
||
- Prisma schema validate:通过
|
||
- Prisma Client generate:通过
|
||
- seed.ts TypeScript 编译检查:通过
|
||
- migration.sql 离线生成:通过,包含 30 张表
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 1 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前仍提示依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
|
||
补充记录:2026-05-31 17:37:37 CST
|
||
|
||
- 已确认问题原因:`.env.example` 中的 `ai_manga` 是占位账号,之前尚未在 MySQL 中创建;Linux root 权限不等于 MySQL root 账号权限。
|
||
- 已从本机宝塔/aaPanel 配置读取 MySQL root 管理凭据,没有打印密码。
|
||
- 已创建 `ai_manga` 数据库和 `ai_manga` 本地用户。
|
||
- 已使用 `prisma migrate deploy` 应用现有 migration。
|
||
- 已执行 `npm run db:seed`。
|
||
- 已验证库中存在 31 张表,其中 30 张业务表加 1 张 Prisma 迁移表。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 02。
|
||
- 提供可用 MySQL DATABASE_URL 后执行迁移和 seed。
|
||
- 审核通过后进入阶段 03:用户认证。
|
||
|
||
### 阶段 03:用户认证
|
||
|
||
完成时间:2026-05-31 17:28:53 CST
|
||
|
||
完成内容:
|
||
|
||
- 实现 PrismaService,供后续业务模块统一访问数据库。
|
||
- 实现 UsersModule 和 UsersService。
|
||
- 实现 AuthModule、AuthController、AuthService、JwtAuthGuard。
|
||
- 支持 POST /api/auth/register 用户注册。
|
||
- 支持 POST /api/auth/login 用户登录。
|
||
- 支持 POST /api/auth/logout 占位退出。
|
||
- 支持 GET /api/auth/profile 获取当前用户信息。
|
||
- 额外支持 GET /api/profile,兼容阶段指令中的 /profile 验收口径。
|
||
- 使用 bcryptjs 对密码哈希。
|
||
- 使用 JWT Bearer Token 鉴权。
|
||
- 用户表 role 字段预留 user/operator/admin 等后台权限。
|
||
- 增加 RequestIdMiddleware、ApiResponseInterceptor、AllExceptionsFilter。
|
||
- 全局成功响应格式为 `{ code, message, data, request_id }`。
|
||
- 全局异常响应格式为 `{ code, message, data: null, request_id }`。
|
||
- README.md 补充认证接口说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/package.json
|
||
- backend/src/app.module.ts
|
||
- backend/src/app.controller.ts
|
||
- backend/src/app.controller.spec.ts
|
||
- README.md
|
||
- package-lock.json
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/prisma/prisma.module.ts
|
||
- backend/src/prisma/prisma.service.ts
|
||
- backend/src/common/request-with-id.ts
|
||
- backend/src/common/request-id.middleware.ts
|
||
- backend/src/common/api-response.interceptor.ts
|
||
- backend/src/common/all-exceptions.filter.ts
|
||
- backend/src/users/user.types.ts
|
||
- backend/src/users/users.module.ts
|
||
- backend/src/users/users.service.ts
|
||
- backend/src/auth/auth.dto.ts
|
||
- backend/src/auth/auth.types.ts
|
||
- backend/src/auth/current-user.decorator.ts
|
||
- backend/src/auth/jwt-auth.guard.ts
|
||
- backend/src/auth/auth.service.ts
|
||
- backend/src/auth/auth.controller.ts
|
||
- backend/src/auth/auth.module.ts
|
||
- backend/src/auth/auth.service.spec.ts
|
||
- backend/src/auth/jwt-auth.guard.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- npm install -w backend @nestjs/jwt bcryptjs
|
||
- npm install -D -w backend @types/express
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -i http://127.0.0.1:3000/api/auth/profile
|
||
- curl -i http://127.0.0.1:3000/api/profile
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,3 个测试文件,7 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 7 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- GET /api/health:返回统一成功响应
|
||
- GET /api/auth/profile 未带 token:返回 401 Missing bearer token
|
||
- GET /api/profile 未带 token:返回 401 Missing bearer token
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 仍提示依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
|
||
补充记录:2026-05-31 17:37:37 CST
|
||
|
||
- 已重启后端并注入 DATABASE_URL。
|
||
- 已完成真实接口联调:POST /api/auth/register 成功,POST /api/auth/login 成功,GET /api/auth/profile 带 token 成功。
|
||
- 修复运行态 NestJS 依赖注入问题:为 AuthController、ProfileController、AuthService、JwtAuthGuard、UsersService 增加显式 `@Inject(...)`。
|
||
- 新增 `db:deploy` / `prisma:deploy` 脚本,服务器已有 migration 时优先用 deploy,避免 `migrate dev` 需要 shadow database 权限。
|
||
- 重新运行 npm run lint、npm run typecheck、npm test、npm run build,全部通过。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 03。
|
||
- 提供可用 MySQL DATABASE_URL 后先执行 `npm run db:migrate` 与 `npm run db:seed`,再做真实注册登录接口联调。
|
||
- 审核通过后进入阶段 04:文件上传和 MinIO。
|
||
|
||
### 阶段 04:文件上传和 MinIO
|
||
|
||
完成时间:2026-05-31 17:44:38 CST
|
||
|
||
完成内容:
|
||
|
||
- 实现 AssetsModule、AssetsController、AssetsService、StorageService。
|
||
- 支持 POST /api/assets/upload 通用私有资产上传。
|
||
- 支持 POST /api/projects/:projectId/novel/upload 小说文件上传。
|
||
- 支持 GET /api/assets/:assetId 查询当前用户自己的私有资产。
|
||
- 上传接口全部受 JWT Bearer Token 保护。
|
||
- 小说上传当前支持 txt 和 md,pdf/docx 保留到后续解析阶段。
|
||
- 文件默认写入 `assets` 表,`visibility=private`。
|
||
- 接口不返回原始文件公网 URL,`file_url` 保持 null。
|
||
- 本机未启动 MinIO 时默认使用本地 mock 私有存储:`storage/private/...`。
|
||
- StorageService 已预留 MinIO 客户端;设置 `STORAGE_DRIVER=minio` 并配置 `MINIO_*` 后可切换。
|
||
- `.env.example` 增加 `STORAGE_DRIVER=local`,并调整本地存储路径到仓库根 storage。
|
||
- README.md 补充上传接口说明。
|
||
- 增加资产上传单元测试。
|
||
|
||
修改文件:
|
||
|
||
- .env.example
|
||
- .gitignore
|
||
- README.md
|
||
- backend/package.json
|
||
- backend/src/app.module.ts
|
||
- backend/src/auth/auth.module.ts
|
||
- package-lock.json
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/assets/asset.types.ts
|
||
- backend/src/assets/upload.dto.ts
|
||
- backend/src/assets/storage.service.ts
|
||
- backend/src/assets/assets.service.ts
|
||
- backend/src/assets/assets.controller.ts
|
||
- backend/src/assets/assets.module.ts
|
||
- backend/src/assets/assets.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- npm install -w backend minio multer
|
||
- npm install -D -w backend @types/multer
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl POST /api/auth/register
|
||
- MySQL 插入阶段 04 测试项目
|
||
- curl POST /api/projects/:projectId/novel/upload -F file=@stage04-novel.txt
|
||
- MySQL 查询 assets 表
|
||
- curl GET /api/assets/:assetId
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,4 个测试文件,10 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 10 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 真实注册测试用户成功
|
||
- 真实创建测试项目成功
|
||
- 真实上传 txt 小说成功,返回 asset_type=novel_text,visibility=private,storage_backend=local,next_step=copyright_confirm
|
||
- assets 表记录 file_url 为 NULL,file_path 为 local:// 前缀
|
||
- 本地文件写入 storage/private/novels/YYYY-MM-DD
|
||
- 未登录访问 GET /api/assets/:assetId 返回 401
|
||
- 带 token 查询自己的 asset 成功
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- 本机没有 MinIO 9000/9001 服务监听,因此本阶段用本地 mock private 存储完成联调。
|
||
- docx/pdf 文件格式尚未开放,留到上传小说解析阶段处理。
|
||
- npm audit 仍提示依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 04。
|
||
- 如要真实 MinIO 联调,先启动 MinIO 并设置 `STORAGE_DRIVER=minio`。
|
||
- 审核通过后进入阶段 05:项目创建流程。
|
||
|
||
### 阶段 05:项目创建流程
|
||
|
||
完成时间:2026-05-31 17:49:49 CST
|
||
|
||
完成内容:
|
||
|
||
- 实现 ProjectsModule、ProjectsController、ProjectsService。
|
||
- 支持 POST /api/projects 创建登录用户项目。
|
||
- 支持 GET /api/projects 查询当前用户项目列表。
|
||
- 支持 GET /api/projects/:id 查询项目详情。
|
||
- 支持 PATCH /api/projects/:id 更新项目基础配置。
|
||
- 支持 POST /api/projects/:id/cancel 取消项目。
|
||
- 支持 DELETE /api/projects/:id 软删除项目,当前实现为归档到 `archived`。
|
||
- 新项目默认状态为 `source_selecting`。
|
||
- `input_mode` 当前开放 `ai_original` 和 `upload`,`admin_import` 预留后台导入。
|
||
- 根据创建模式填充默认风格、输出类型、质量档位、目标集数和版权状态。
|
||
- 增加项目所有权校验,用户只能访问自己的项目,管理员预留跨项目能力。
|
||
- 文件上传模块改为调用 ProjectsService 校验项目归属,避免给非项目所有者上传小说。
|
||
- README.md 补充项目接口说明。
|
||
- 增加项目服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- README.md
|
||
- backend/src/app.module.ts
|
||
- backend/src/assets/assets.module.ts
|
||
- backend/src/assets/assets.service.ts
|
||
- backend/src/assets/assets.service.spec.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/projects/project.types.ts
|
||
- backend/src/projects/project.dto.ts
|
||
- backend/src/projects/projects.service.ts
|
||
- backend/src/projects/projects.controller.ts
|
||
- backend/src/projects/projects.module.ts
|
||
- backend/src/projects/projects.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl POST /api/auth/register
|
||
- curl POST /api/projects
|
||
- curl GET /api/projects
|
||
- curl GET /api/projects/:id
|
||
- curl PATCH /api/projects/:id
|
||
- curl GET /api/projects/:id 使用另一个用户 token
|
||
- curl POST /api/projects/:id/cancel
|
||
- curl DELETE /api/projects/:id
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,5 个测试文件,15 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 15 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 真实注册测试用户成功
|
||
- 真实创建 upload 项目成功,返回 status=source_selecting
|
||
- 真实查询项目列表成功,包含刚创建项目
|
||
- 真实查询项目详情成功
|
||
- 真实更新项目标题和目标集数成功
|
||
- 使用另一个用户 token 查询该项目返回 403 Project is private
|
||
- 真实取消项目成功,状态变为 cancelled
|
||
- 真实软删除项目成功,状态变为 archived
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 仍提示依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 项目删除当前为软删除归档,不物理删除数据库记录和已上传文件。
|
||
- 本阶段只实现项目创建和基础流转,不做上传小说解析、AI 原创、队列或真实 Provider。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 05。
|
||
- 审核通过后进入阶段 06:上传小说解析。
|
||
|
||
### 阶段 06:上传小说解析
|
||
|
||
完成时间:2026-05-31 18:09:02 CST
|
||
|
||
完成内容:
|
||
|
||
- 安装 `mammoth` 和 `pdf-parse`,用于 docx 与文本型 pdf 抽取。
|
||
- StorageService 增加私有对象读取能力,支持读取 `local://` 和 `minio://` 路径。
|
||
- 小说上传白名单扩展为 txt、md、docx、文本型 pdf。
|
||
- 新增 NovelsModule、NovelsController、NovelsService、NovelParserService。
|
||
- 支持 POST /api/projects/:projectId/copyright/confirm 确认上传小说版权。
|
||
- 支持 GET /api/projects/:projectId/copyright 查询版权确认记录。
|
||
- 支持 POST /api/projects/:projectId/novel/paste 保存粘贴文本来源。
|
||
- 支持 POST /api/projects/:projectId/novel/parse 解析上传 asset 或粘贴 source。
|
||
- 支持 GET /api/projects/:projectId/novel/parse-result 查询解析结果。
|
||
- 支持 PATCH /api/novel-chapters/:chapterId 手动编辑章节。
|
||
- 解析前强制校验版权确认,未确认时返回 400。
|
||
- 解析流程写入 `novel_sources` 和 `novel_chapters`。
|
||
- 文本清洗会处理 BOM、空行、部分广告/水印/链接噪声。
|
||
- 章节识别支持 `第1章`、`第一章`、`Chapter 1`、`001 标题`、`序章`、`楔子`、`番外` 等格式。
|
||
- 章节识别失败时按字数切分,并在 parse_report 中记录 warning。
|
||
- 解析成功后项目状态进入 `novel_uploaded`;解析失败时进入 `text_parse_failed`。
|
||
- 手动编辑章节后状态标记为 `edited`。
|
||
- README.md 补充小说解析与版权接口说明。
|
||
- 增加小说解析和小说服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- package.json
|
||
- package-lock.json
|
||
- backend/package.json
|
||
- README.md
|
||
- backend/src/app.module.ts
|
||
- backend/src/assets/assets.service.ts
|
||
- backend/src/assets/assets.service.spec.ts
|
||
- backend/src/assets/storage.service.ts
|
||
- backend/src/projects/project.types.ts
|
||
- backend/src/projects/projects.service.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/novels/novel.dto.ts
|
||
- backend/src/novels/novel.types.ts
|
||
- backend/src/novels/novel-parser.service.ts
|
||
- backend/src/novels/novel-parser.service.spec.ts
|
||
- backend/src/novels/novels.controller.ts
|
||
- backend/src/novels/novels.module.ts
|
||
- backend/src/novels/novels.service.ts
|
||
- backend/src/novels/novels.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- npm view mammoth version
|
||
- npm view pdf-parse version
|
||
- npm install -w backend mammoth pdf-parse
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- Node fetch 真实接口联调:注册、创建项目、上传 txt、未确认版权解析、确认版权、解析、查结果、编辑章节、粘贴文本
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,7 个测试文件,24 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 24 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 真实注册测试用户成功
|
||
- 真实创建 upload 项目成功
|
||
- 真实上传 txt 小说成功
|
||
- 未确认版权调用 POST /api/projects/:projectId/novel/parse 返回 400
|
||
- 确认版权成功,返回 next_step=novel_parse
|
||
- 真实解析上传 txt 成功,识别 2 个章节,parse_report.strategy=heading
|
||
- 清洗测试链接噪声成功,removed_line_count=1
|
||
- GET /api/projects/:projectId/novel/parse-result 返回 2 个章节
|
||
- PATCH /api/novel-chapters/:chapterId 成功,章节状态变为 edited
|
||
- POST /api/projects/:projectId/novel/paste 成功创建粘贴文本 source
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 本机没有 MinIO 9000/9001 服务监听,因此 MinIO 读取路径只做代码预留,本阶段真实联调用本地 private 存储完成。
|
||
- pdf 当前仅支持文本型 PDF;扫描件 OCR 不在本阶段实现。
|
||
- 本阶段只做 deterministic 文本解析,不做 AI 改编、故事分析、任务队列或真实 Provider。
|
||
- 真实联调产生了测试用户、项目、资产、小说来源和章节数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 06。
|
||
- 审核通过后进入阶段 07:AI 原创小说 mock。
|
||
|
||
### 阶段 07:AI 原创小说 mock
|
||
|
||
完成时间:2026-05-31 18:16:31 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 OriginalNovelsController 和 OriginalNovelMockService。
|
||
- 支持 POST /api/projects/:projectId/original/idea 生成 mock 故事创意。
|
||
- 支持 POST /api/projects/:projectId/original/outline 生成 mock 故事大纲和分章大纲。
|
||
- 支持 POST /api/projects/:projectId/original/chapters 生成 mock 章节正文。
|
||
- 支持 POST /api/projects/:projectId/original/self-check 执行 mock 自检。
|
||
- 支持 GET /api/projects/:projectId/original/result 查询原创小说 mock 结果。
|
||
- 原创接口强制要求项目 `input_mode=ai_original`,上传小说项目调用会返回 400。
|
||
- mock 结果写入 `novel_sources`,`source_type=ai_original`。
|
||
- mock 章节写入 `novel_chapters`,状态为 `generated`。
|
||
- mock 生成过程记录到 `parse_report`,`provider=mock_novel_provider`。
|
||
- 生成 idea 后项目状态进入 `novel_generating`。
|
||
- 生成章节后项目状态进入 `novel_uploaded`。
|
||
- 自检结果写入 `parse_report.self_check`,通过后 source 状态为 `checked`。
|
||
- 自检覆盖主角一致性、主线明确、冲突强度、可视化摘要、短视频钩子。
|
||
- README.md 补充 AI 原创小说 mock 接口说明。
|
||
- 增加原创小说 mock 单元测试。
|
||
|
||
修改文件:
|
||
|
||
- README.md
|
||
- backend/src/novels/novels.module.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/novels/original-novel.dto.ts
|
||
- backend/src/novels/original-novel.types.ts
|
||
- backend/src/novels/original-novel-mock.service.ts
|
||
- backend/src/novels/original-novel-mock.service.spec.ts
|
||
- backend/src/novels/original-novels.controller.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- tail -n 80 /tmp/ai-manga-backend.log
|
||
- Node fetch 真实接口联调:注册、创建 upload 项目、验证 upload 项目调用原创接口被拒绝、创建 ai_original 项目、生成 idea、生成 outline、生成 chapters、自检、查询 result
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,8 个测试文件,29 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 29 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后端日志确认 original 路由全部映射成功
|
||
- 真实注册测试用户成功
|
||
- 真实创建 upload 项目成功,调用 original/idea 返回 400
|
||
- 真实创建 ai_original 项目成功
|
||
- POST /original/idea 成功,返回 source_id 和 mock idea
|
||
- POST /original/outline 成功,生成 3 个分章大纲
|
||
- POST /original/chapters 成功,生成 3 个章节并写入 `novel_chapters`
|
||
- POST /original/self-check 成功,self_check.passed=true,score=100
|
||
- GET /original/result 成功,返回 source、idea、outline、self_check 和 3 个章节
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 本阶段只做 deterministic mock,不接真实 AI Provider,也不实现 Provider 抽象、队列或成本记录。
|
||
- 生成内容是固定模板拼装,质量只用于 MVP 流程联调,不代表最终小说质量。
|
||
- 真实联调产生了测试用户、项目、小说来源和章节数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 07。
|
||
- 审核通过后进入阶段 08:故事圣经。
|
||
|
||
### 阶段 08:故事圣经
|
||
|
||
完成时间:2026-05-31 18:25:56 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 StoryBiblesModule、StoryBiblesController、StoryBiblesService。
|
||
- 支持 POST /api/projects/:projectId/story-bible/generate 生成故事圣经。
|
||
- 支持 GET /api/projects/:projectId/story-bible 查询最新故事圣经和版本列表。
|
||
- 支持 GET /api/projects/:projectId/story-bible?version=N 查询指定版本。
|
||
- 支持 PATCH /api/projects/:projectId/story-bible 编辑故事圣经并创建新版本。
|
||
- 支持 POST /api/projects/:projectId/story-bible/confirm 确认故事圣经。
|
||
- 生成前要求项目已有小说来源和章节,可接上传解析结果或 AI 原创 mock 结果。
|
||
- 生成时从 `novel_sources.parse_report`、`novel_chapters.summary`、`novel_chapters.visual_summary` 提取故事要素。
|
||
- 故事圣经覆盖一句话简介、主线目标、核心冲突、核心卖点、风格基调、世界规则、时间线、伏笔、禁用设定和结局方向。
|
||
- 故事圣经写入 `story_bibles`,初始状态为 `waiting_confirm`。
|
||
- 编辑不会覆盖旧记录,而是创建 version+1 的新版本。
|
||
- 确认时把当前版本状态改为 `confirmed`,并把同项目旧 confirmed 版本置为 `superseded`。
|
||
- 生成时项目状态流转到 `story_bible_generating`,生成完成到 `waiting_story_confirm`。
|
||
- 确认后项目状态流转到 `story_confirmed`。
|
||
- README.md 补充故事圣经接口说明。
|
||
- 增加故事圣经服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- README.md
|
||
- backend/src/app.module.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/story-bibles/story-bible.dto.ts
|
||
- backend/src/story-bibles/story-bible.types.ts
|
||
- backend/src/story-bibles/story-bibles.controller.ts
|
||
- backend/src/story-bibles/story-bibles.module.ts
|
||
- backend/src/story-bibles/story-bibles.service.ts
|
||
- backend/src/story-bibles/story-bibles.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- rg 故事圣经 / story-bible 相关文档和代码
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- tail -n 90 /tmp/ai-manga-backend.log
|
||
- Node fetch 真实接口联调:注册、创建无章节项目并验证生成被拒绝、创建 ai_original 项目、生成原创 idea/outline/chapters、生成故事圣经、查询、编辑 v2、确认、查询项目状态
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,9 个测试文件,34 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 34 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后端日志确认 story-bible 路由全部映射成功
|
||
- 无小说来源/章节时调用 story-bible/generate 被拒绝
|
||
- 真实 AI 原创 mock 生成章节成功
|
||
- 真实生成故事圣经成功,version=1,status=waiting_confirm
|
||
- GET /story-bible 返回当前版本和版本列表
|
||
- PATCH /story-bible 成功创建 version=2
|
||
- POST /story-bible/confirm 成功,故事圣经状态变为 confirmed
|
||
- GET /projects/:id 确认项目状态为 story_confirmed
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 本阶段故事圣经为 deterministic 提取/拼装,不调用真实 AI Provider。
|
||
- `world_bibles` 表暂未单独写入;世界规则先落在 `story_bibles.world_summary`,后续如拆 WorldBibleModule 再迁移。
|
||
- 真实联调产生了测试用户、项目、小说来源、章节和故事圣经数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 08。
|
||
- 审核通过后进入阶段 09:角色圣经。
|
||
|
||
### 阶段 09:角色圣经
|
||
|
||
完成时间:2026-05-31 18:34:22 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 CharactersModule、CharactersController、CharactersService。
|
||
- 支持 POST /api/projects/:projectId/characters/extract 从已确认故事圣经和小说章节抽取角色草稿。
|
||
- 支持 GET /api/projects/:projectId/characters 查询角色列表,默认不返回 deleted,可通过 include_deleted=true 包含软删除角色。
|
||
- 支持 POST /api/projects/:projectId/characters 手动新增角色。
|
||
- 支持 PATCH /api/characters/:characterId 编辑角色。
|
||
- 支持 DELETE /api/characters/:characterId 软删除未锁定角色。
|
||
- 支持 POST /api/projects/:projectId/characters/confirm 确认角色库并锁定角色。
|
||
- 抽取前要求项目已有 confirmed 故事圣经;未确认时返回 400。
|
||
- 角色抽取当前为 deterministic mock,默认生成主角、反派、配角 3 类角色。
|
||
- 抽取结果写入 `characters` 表,状态为 `generated`。
|
||
- 手动新增角色状态为 `edited`,编辑未锁定角色后状态标记为 `edited`。
|
||
- 确认角色库会把 `draft`、`generated`、`edited` 状态角色锁定为 `locked`。
|
||
- 锁定后禁止修改姓名、角色类型、性别、年龄、身份和核心外观字段;允许继续补充服装规则、表情风格等非核心描述。
|
||
- 项目状态流转覆盖 `character_extracting`、`waiting_character_confirm`、`character_confirmed`。
|
||
- README.md 补充角色圣经接口说明。
|
||
- 增加角色圣经服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
- backend/src/app.module.ts
|
||
- backend/src/projects/project.types.ts
|
||
|
||
新增文件:
|
||
|
||
- backend/src/characters/character.dto.ts
|
||
- backend/src/characters/character.types.ts
|
||
- backend/src/characters/characters.service.ts
|
||
- backend/src/characters/characters.controller.ts
|
||
- backend/src/characters/characters.module.ts
|
||
- backend/src/characters/characters.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- rg 角色圣经 / characters 相关文档和代码
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- tail -n 100 /tmp/ai-manga-backend.log
|
||
- Node fetch 真实接口联调:注册、创建未确认故事圣经项目并验证抽取被拒绝、创建 ai_original 项目、生成原创章节、生成并确认故事圣经、抽取角色、列表、编辑、手动新增、删除、确认锁定、验证 locked 限制、查询项目状态
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,10 个测试文件,41 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 41 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后端日志确认角色圣经路由全部映射成功
|
||
- 未确认故事圣经时调用 POST /characters/extract 返回 400
|
||
- 真实 AI 原创 mock 生成章节成功
|
||
- 真实生成并确认故事圣经成功,story_bible_id=3
|
||
- 真实抽取角色成功,生成 3 个角色,首个角色为林晚
|
||
- GET /projects/:projectId/characters 返回 3 个未删除角色
|
||
- PATCH 角色服装规则成功
|
||
- POST 手动新增配角顾南成功
|
||
- DELETE 手动角色成功,状态变为 deleted
|
||
- POST /characters/confirm 成功,抽取角色全部变为 locked
|
||
- locked 角色修改核心姓名字段返回 400
|
||
- locked 角色修改非核心服装规则成功,状态保持 locked
|
||
- GET /projects/:id 确认项目状态为 character_confirmed
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 本阶段角色抽取为 deterministic mock / 模板生成,不调用真实 AI Provider。
|
||
- 本阶段不生成角色图片、不生成 anchor 图,也不接入 ImageProvider 或队列。
|
||
- `anchor_asset_id` 字段保留,但本阶段不写入。
|
||
- 真实联调产生了测试用户、项目、小说来源、章节、故事圣经和角色数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 09。
|
||
- 审核通过后进入阶段 10:长篇记忆。
|
||
|
||
### 阶段 10:长篇记忆
|
||
|
||
完成时间:2026-05-31 18:51:19 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 MemoriesModule、MemoriesController、MemoriesService。
|
||
- 支持 GET /api/projects/:projectId/plot-memories 查询剧情记忆,可按 memory_type、status、episode_id 过滤。
|
||
- 支持 POST /api/projects/:projectId/plot-memories/generate 从 confirmed 故事圣经、locked 角色库和小说章节/分集摘要生成长篇记忆。
|
||
- 支持 POST /api/projects/:projectId/plot-memories 手动新增剧情记忆。
|
||
- 支持 PATCH /api/plot-memories/:memoryId 更新剧情记忆,覆盖标记 resolved/archived 等人工维护场景。
|
||
- 支持 GET /api/projects/:projectId/memory-context?episode_no=N 获取分集生成前上下文。
|
||
- 支持 GET /api/characters/:characterId/memories 查询角色记忆。
|
||
- 支持 GET /api/projects/:projectId/plot-threads 查询剧情线。
|
||
- 支持 POST /api/projects/:projectId/plot-threads 手动新增剧情线。
|
||
- 支持 PATCH /api/plot-threads/:threadId 更新剧情线状态、预计/实际解决集数等。
|
||
- 支持 POST /api/episodes/:episodeId/continuity-check 执行规则版连续性检查。
|
||
- 记忆生成前要求项目已有 confirmed 故事圣经和 locked 角色库;否则返回 400。
|
||
- 生成结果写入 `plot_memories`、`plot_threads` 和 `character_memories`。
|
||
- 默认剧情记忆覆盖章节事件、未解决冲突、伏笔、世界规则、人物关系变化、重要道具状态和下一集钩子。
|
||
- 默认剧情线覆盖主线目标、反派计划和角色成长线。
|
||
- `memory-context` 会聚合故事圣经、锁定角色、活跃剧情记忆、开放剧情线、前 3 集摘要和上一集结尾钩子,供下一阶段分集计划使用。
|
||
- locked 角色非核心资料补充时,会自动写入 `character_memories.profile_adjustment`。
|
||
- 连续性检查可发现角色未承接、伏笔未推进、上一集钩子未承接、缺少结尾钩子、开放剧情线未推进和明显破坏世界观的内容。
|
||
- README.md 补充长篇记忆接口说明。
|
||
- 增加长篇记忆服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
- backend/src/app.module.ts
|
||
- backend/src/characters/characters.service.ts
|
||
- backend/src/characters/characters.service.spec.ts
|
||
|
||
新增文件:
|
||
|
||
- backend/src/memories/memory.dto.ts
|
||
- backend/src/memories/memory.types.ts
|
||
- backend/src/memories/memories.service.ts
|
||
- backend/src/memories/memories.controller.ts
|
||
- backend/src/memories/memories.module.ts
|
||
- backend/src/memories/memories.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- rg 长篇记忆 / memory / plot_memories / character_memories / continuity 相关文档和代码
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- tail -n 140 /tmp/ai-manga-backend.log
|
||
- Node fetch 真实接口联调:注册、创建未满足条件项目并验证记忆生成被拒绝、创建 ai_original 项目、生成原创章节、生成并确认故事圣经、验证未锁角色时记忆生成被拒绝、抽取并确认角色、生成剧情记忆、列表、手动新增/标记剧情记忆、剧情线新增/更新、locked 角色补充并记录角色记忆、直接插入测试分集、获取第 5 集记忆上下文、执行连续性检查、查询项目状态
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,11 个测试文件,48 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 48 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后端日志确认长篇记忆路由全部映射成功
|
||
- 未确认故事圣经时调用 POST /plot-memories/generate 返回 400
|
||
- 已确认故事圣经但未锁定角色时调用 POST /plot-memories/generate 返回 400
|
||
- 真实生成长篇记忆成功,生成 plot_memories=11、character_memories=12、plot_threads=3
|
||
- GET /projects/:projectId/plot-memories 成功返回剧情记忆列表
|
||
- 手动新增剧情记忆成功,PATCH 标记 resolved 成功
|
||
- GET /projects/:projectId/plot-threads 成功返回剧情线列表
|
||
- 手动新增剧情线成功,PATCH 更新为 progressing 成功
|
||
- locked 角色补充服装规则成功,并在 GET /characters/:characterId/memories 中看到 profile_adjustment
|
||
- GET /projects/:projectId/memory-context?episode_no=5 成功返回前 3 集摘要和上一集结尾钩子
|
||
- POST /episodes/:episodeId/continuity-check 成功发现“突然觉醒超能力”世界观冲突,result_status=fail
|
||
- GET /projects/:id 确认项目状态保持 character_confirmed,下一阶段可进入分集计划
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 本阶段长篇记忆为 deterministic mock / 规则生成,不调用真实 AI Provider。
|
||
- 本阶段不接入 EmbeddingProvider、不做向量检索、不进 BullMQ 队列,也不记录 Provider 成本。
|
||
- 分集接口尚未实现;真实联调中的第 2-5 集测试数据通过 Prisma 直接插入,用于验证 memory-context 和 continuity-check。
|
||
- 真实联调产生了测试用户、项目、小说来源、章节、故事圣经、角色、剧情记忆、剧情线、角色记忆、分集和连续性检查数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 10。
|
||
- 审核通过后进入阶段 11:分集计划。
|
||
|
||
### 阶段 11:分集计划
|
||
|
||
完成时间:2026-05-31 18:58:23 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 EpisodesModule、EpisodesController、EpisodesService。
|
||
- 支持 POST /api/projects/:projectId/episodes/generate-plan 生成分集计划。
|
||
- 支持 GET /api/projects/:projectId/episodes 查询项目分集列表。
|
||
- 支持 PATCH /api/episodes/:episodeId 编辑确认前分集。
|
||
- 支持 POST /api/projects/:projectId/episodes/confirm 确认分集计划。
|
||
- 分集生成前要求项目已有 confirmed 故事圣经、locked 角色库、小说章节和 active 长篇记忆;缺失时返回 400。
|
||
- 分集生成当前为 deterministic mock,从故事圣经、角色圣经、长篇记忆、剧情线和小说章节生成分集。
|
||
- 每集写入 `episodes` 表,包含标题、剧情摘要、开头钩子、中段冲突、结尾悬念、关联章节和预计时长。
|
||
- 生成分集时项目状态先进入 `episode_planning`,生成完成后进入 `waiting_episode_confirm`。
|
||
- 编辑分集会把分集状态标记为 `edited`,并让项目保持 `waiting_episode_confirm`。
|
||
- 确认分集前校验集数连续、每集具备标题/摘要/钩子/冲突/预计时长。
|
||
- 确认分集会把 `draft`、`generated`、`edited` 状态分集更新为 `confirmed`,项目状态变为 `episode_confirmed`。
|
||
- 已 confirmed 分集不可继续编辑,后续返工留给修改申请/返工流程。
|
||
- README.md 补充分集计划接口说明。
|
||
- 增加分集计划服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
- backend/src/app.module.ts
|
||
- backend/src/projects/project.types.ts
|
||
|
||
新增文件:
|
||
|
||
- backend/src/episodes/episode.dto.ts
|
||
- backend/src/episodes/episode.types.ts
|
||
- backend/src/episodes/episodes.service.ts
|
||
- backend/src/episodes/episodes.controller.ts
|
||
- backend/src/episodes/episodes.module.ts
|
||
- backend/src/episodes/episodes.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- rg 分集计划 / episodes / episode_planning 相关文档和代码
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- tail -n 180 /tmp/ai-manga-backend.log
|
||
- Node fetch 真实接口联调:注册、创建 ai_original 项目、验证缺少上下文时分集生成被拒绝、生成原创章节、生成并确认故事圣经、抽取并确认角色、验证缺少长篇记忆时分集生成被拒绝、生成长篇记忆、生成 3 集分集计划、查询分集、编辑第 1 集、确认分集、验证 confirmed 分集禁止编辑、查询项目状态
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,12 个测试文件,55 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 55 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后端日志确认分集计划路由全部映射成功
|
||
- 缺少故事圣经/角色/记忆上下文时调用 POST /episodes/generate-plan 返回 400
|
||
- 已确认故事圣经和角色但缺少 active 长篇记忆时调用 POST /episodes/generate-plan 返回 400
|
||
- 真实生成 3 集分集计划成功,每集都有 opening_hook、middle_conflict 和 ending_hook
|
||
- GET /projects/:projectId/episodes 成功返回 3 集
|
||
- PATCH /episodes/:episodeId 成功编辑第 1 集,状态变为 edited
|
||
- POST /projects/:projectId/episodes/confirm 成功,3 集全部变为 confirmed
|
||
- confirmed 分集继续 PATCH 返回 400
|
||
- GET /projects/:id 确认项目状态为 episode_confirmed
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 本阶段分集计划为 deterministic mock / 规则生成,不调用真实 AI Provider。
|
||
- 本阶段不生成单集脚本、不生成分镜、不进 BullMQ 队列,也不记录 Provider 成本。
|
||
- 分集确认后暂不支持重排/拆分/合并/返工;后续通过修改申请或返工流程补充。
|
||
- 真实联调产生了测试用户、项目、小说来源、章节、故事圣经、角色、长篇记忆、剧情线和分集数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 11。
|
||
- 审核通过后进入阶段 12:脚本和分镜。
|
||
|
||
### 阶段 12:脚本和分镜
|
||
|
||
完成时间:2026-05-31 19:07:37 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 ScriptsModule、ScriptsController、ScriptsService。
|
||
- 支持 POST /api/episodes/:episodeId/script/generate 生成单集脚本。
|
||
- 支持 GET /api/episodes/:episodeId/script 查询最新脚本和版本列表。
|
||
- 支持 PATCH /api/episodes/:episodeId/script 编辑未确认脚本。
|
||
- 支持 POST /api/episodes/:episodeId/script/confirm 确认单集脚本。
|
||
- 支持 POST /api/episodes/:episodeId/storyboard/generate 生成分镜。
|
||
- 支持 GET /api/episodes/:episodeId/storyboard 查询分镜镜头列表。
|
||
- 支持 PATCH /api/storyboard-shots/:shotId 编辑未确认镜头。
|
||
- 支持 DELETE /api/storyboard-shots/:shotId 删除未确认镜头。
|
||
- 支持 POST /api/episodes/:episodeId/storyboard/confirm 确认分镜。
|
||
- 支持 POST /api/storyboard-shots/:shotId/regenerate-prompt 重生未确认镜头 Prompt。
|
||
- 脚本生成前要求分集已 confirmed,且项目已有 confirmed 故事圣经和 locked 角色库;缺失时返回 400。
|
||
- 脚本写入 `episode_scripts`,包含 `script_text`、`narration_text`、`dialogue_json`、version 和 status。
|
||
- 脚本生成时项目状态进入 `script_generating`,生成完成后进入 `waiting_script_confirm`。
|
||
- 脚本确认后状态为 `confirmed`,项目状态变为 `script_confirmed`,旧 confirmed 版本会标记为 `superseded`。
|
||
- 分镜生成前要求已有 confirmed 单集脚本;未确认脚本时返回 400。
|
||
- 分镜写入 `storyboard_shots`,默认每集生成 10 个镜头。
|
||
- 每个镜头包含场景名、地点、角色 JSON、画面描述、动作描述、台词/旁白、镜头运动、特效、2-5 秒时长、Prompt 和负面 Prompt。
|
||
- Prompt 会带入角色固定年龄段、脸型、发型、服装范围,并加入防混脸、年龄/发色漂移、复杂多人镜头等负面约束。
|
||
- 分镜生成时项目状态进入 `storyboard_generating`,生成完成后进入 `waiting_storyboard_confirm`。
|
||
- 分镜确认前校验每个镜头必须有画面、动作、时长、Prompt 和负面 Prompt。
|
||
- 分镜确认后镜头状态变为 `confirmed`,项目状态变为 `storyboard_confirmed`。
|
||
- 已 confirmed 脚本和分镜不可继续编辑/删除/重生 Prompt。
|
||
- README.md 补充脚本和分镜接口说明。
|
||
- 增加脚本和分镜服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
- backend/src/app.module.ts
|
||
- backend/src/projects/project.types.ts
|
||
|
||
新增文件:
|
||
|
||
- backend/src/scripts/script.dto.ts
|
||
- backend/src/scripts/script.types.ts
|
||
- backend/src/scripts/scripts.service.ts
|
||
- backend/src/scripts/scripts.controller.ts
|
||
- backend/src/scripts/scripts.module.ts
|
||
- backend/src/scripts/scripts.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- rg 脚本 / 分镜 / storyboard / episode_scripts / storyboard_shots / Prompt 相关文档和代码
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- tail -n 200 /tmp/ai-manga-backend.log
|
||
- Node fetch 真实接口联调:注册、创建 ai_original 项目、生成原创章节、生成并确认故事圣经、抽取并确认角色、生成长篇记忆、生成并确认分集计划、验证未确认脚本时分镜生成被拒绝、生成脚本、查询脚本、编辑脚本、确认脚本、验证 confirmed 脚本禁止编辑、生成 10 个分镜镜头、查询分镜、编辑镜头、重生 Prompt、确认分镜、验证 confirmed 镜头禁止编辑、查询项目状态
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend test:通过,13 个测试文件,63 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 63 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后端日志确认脚本和分镜路由全部映射成功
|
||
- 未确认脚本时调用 POST /storyboard/generate 返回 400
|
||
- 真实生成单集脚本成功,脚本文本包含结构化脚本段落
|
||
- GET /episodes/:episodeId/script 成功返回最新脚本和版本列表
|
||
- PATCH /episodes/:episodeId/script 成功编辑旁白,状态变为 edited
|
||
- POST /episodes/:episodeId/script/confirm 成功,脚本状态变为 confirmed
|
||
- confirmed 脚本继续 PATCH 返回 400
|
||
- POST /episodes/:episodeId/storyboard/generate 成功生成 10 个镜头
|
||
- 每个镜头都有 visual_desc、duration 和 prompt_text
|
||
- GET /episodes/:episodeId/storyboard 成功返回 10 个镜头
|
||
- PATCH /storyboard-shots/:shotId 成功编辑镜头,状态变为 edited
|
||
- POST /storyboard-shots/:shotId/regenerate-prompt 成功,Prompt 包含“高质量韩漫风”
|
||
- POST /episodes/:episodeId/storyboard/confirm 成功,10 个镜头全部 confirmed
|
||
- confirmed 镜头继续 PATCH 返回 400
|
||
- GET /projects/:id 确认项目状态为 storyboard_confirmed
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 本阶段脚本和分镜为 deterministic mock / 规则生成,不调用真实 AI Provider。
|
||
- 本阶段不生成分镜图片、不接入 ImageProvider、不进 BullMQ 队列,也不记录 Provider 成本。
|
||
- 分镜确认后暂不支持返工;后续通过修改申请或返工流程补充。
|
||
- 真实联调产生了测试用户、项目、小说来源、章节、故事圣经、角色、长篇记忆、剧情线、分集、脚本和分镜数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 人工审核阶段 12。
|
||
- 审核通过后进入阶段 13:BullMQ 队列。
|
||
|
||
### 阶段 13:BullMQ 队列
|
||
|
||
完成时间:2026-05-31 19:39:54 CST
|
||
|
||
完成内容:
|
||
|
||
- 安装 backend / workers 的 `bullmq` 和 `ioredis` 依赖。
|
||
- 新增 QueuesModule、QueuesController、QueuesService。
|
||
- 新增任务类型、任务状态、队列名、任务类型到队列映射、默认重试次数配置。
|
||
- 支持 POST /api/projects/:projectId/tasks 创建项目任务。
|
||
- 支持 GET /api/projects/:projectId/tasks 查询项目任务。
|
||
- 支持 GET /api/tasks/:taskId 查询单个任务及队列归属。
|
||
- 支持 GET /api/admin/tasks 管理员查询任务。
|
||
- 支持 POST /api/admin/tasks/:taskId/retry 管理员重试 failed / manual_required 任务。
|
||
- 支持 POST /api/admin/tasks/:taskId/cancel 管理员取消任务,并尽量移除该任务所有 attempt job。
|
||
- 支持 POST /api/admin/tasks/:taskId/manual-required 管理员标记任务进入人工介入状态。
|
||
- 支持 POST /api/admin/tasks/recover-stale 恢复过久未完成的 running / retrying 任务。
|
||
- 支持 GET /api/admin/queues 查询 BullMQ 各队列 waiting、active、delayed、failed、completed、paused 计数。
|
||
- 创建任务先落 `render_tasks`,再入 BullMQ;入队失败时不丢 DB 任务,返回 `queue_backend=bullmq_unavailable`。
|
||
- 默认幂等 key 使用 `project_id + episode_id + shot_id + task_type + input_hash`。
|
||
- `input_hash` 基于稳定 JSON 序列化后 SHA-256 生成,字段顺序不同但内容相同会命中同一幂等任务。
|
||
- 校验项目 owner/admin 权限,校验 episode_id / shot_id 必须属于项目。
|
||
- 管理员接口要求 JWT 中 role 为 `admin`。
|
||
- worker 入口状态输出已包含 BullMQ 后端、Redis URL 脱敏展示和完整队列清单。
|
||
- 发现并修复 BullMQ v5 自定义 jobId 不允许冒号的问题,改为 `task-<id>-attempt-<n>` 格式。
|
||
- README.md 补充 BullMQ 队列接口说明。
|
||
- 增加队列服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- package-lock.json
|
||
- backend/package.json
|
||
- workers/package.json
|
||
- backend/src/app.module.ts
|
||
- workers/src/main.ts
|
||
- workers/src/main.spec.ts
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/queues/task.types.ts
|
||
- backend/src/queues/task.dto.ts
|
||
- backend/src/queues/queues.service.ts
|
||
- backend/src/queues/queues.controller.ts
|
||
- backend/src/queues/queues.module.ts
|
||
- backend/src/queues/queues.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- redis-cli ping
|
||
- npm install -w backend bullmq ioredis
|
||
- npm install -w workers bullmq ioredis
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend -- queues.service.spec.ts
|
||
- npm test -w workers
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- Node BullMQ debug 入队验证
|
||
- Node fetch 真实接口联调:注册普通用户、创建项目、创建任务、重复幂等创建、查询任务、注册并提升 admin、管理员重试、取消、人工介入、管理员任务列表、队列统计
|
||
|
||
测试结果:
|
||
|
||
- redis-cli ping:PONG
|
||
- backend typecheck:通过
|
||
- backend 队列服务单测:通过,6 个测试通过
|
||
- workers test:通过,1 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 14 个测试文件,69 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后端日志确认队列路由全部映射成功
|
||
- 真实联调创建任务成功写入 `render_tasks`,入队 `story_queue` 成功,job_id 为 `task-3-attempt-0`
|
||
- 相同 input_json 字段顺序不同的重复创建命中同一任务,返回 `idempotent=true`
|
||
- 管理员重试 failed 任务成功,状态变为 `retrying`,retry_count 变为 1,job_id 为 `task-3-attempt-1`
|
||
- 管理员取消任务成功,状态变为 `cancelled`,当前 job 移除成功
|
||
- 管理员标记人工介入成功,状态变为 `manual_required`,error_code 为 `NEEDS_OPERATOR`
|
||
- GET /api/admin/queues 成功返回队列统计,novel_queue、parse_queue、story_queue 状态均为 ok
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- worker 当前只声明队列清单和状态输出,还未启动真实消费者处理图片、音频、字幕、视频或 QC 任务。
|
||
- 本阶段不接入真实 AI Provider,不记录真实 Provider 成本,不扣减额度。
|
||
- 真实联调产生了测试用户、项目和 render_tasks 数据,未清理。
|
||
- 修复 BullMQ jobId 格式前曾产生一次 `bullmq_unavailable` 测试任务记录,保留为联调痕迹。
|
||
|
||
下一步建议:
|
||
|
||
- 跳过人工审核后进入阶段 14:AI Provider 抽象。
|
||
|
||
### 阶段 14:AI Provider 抽象
|
||
|
||
完成时间:2026-05-31 19:56:25 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 ProvidersModule、ProvidersController、ProvidersService。
|
||
- 新增 Provider 类型、模式、日志状态、安全输出类型和默认 mock provider 配置。
|
||
- 支持 TextProvider、NovelProvider、ImageProvider、VideoProvider、VoiceProvider、ModerationProvider、QualityCheckProvider、FileParseProvider、EmbeddingProvider。
|
||
- 支持 GET /api/admin/providers 查询 Provider 配置。
|
||
- 支持 POST /api/admin/providers/bootstrap-mocks 写入或更新 9 个默认 mock Provider。
|
||
- 支持 POST /api/admin/providers/execute 执行指定类型 Provider。
|
||
- 支持 PATCH /api/admin/providers/:providerId 更新 Provider 配置。
|
||
- 支持 POST /api/admin/providers/:providerId/test 测试指定 Provider。
|
||
- 支持 GET /api/admin/provider-logs 查询 Provider 请求/响应/失败日志。
|
||
- 支持 GET /api/admin/costs 聚合 Provider 成本。
|
||
- Provider 执行会从 `provider_configs` 选择启用配置,按 priority 排序,primary 失败后支持 fallback。
|
||
- Provider 执行会写入 `provider_logs`,包含 provider、task、project、request、response、input_size、output_size、cost、status、错误信息和时间。
|
||
- 传入 `task_id` 时会回写 `render_tasks`:执行前 running,成功后 success,并记录 provider_id、provider_request_id、cost_estimate、cost_actual。
|
||
- 当前 real mode 不会调用外部模型,会返回 `REAL_PROVIDER_NOT_CONFIGURED` 并触发 fallback。
|
||
- mock driver 支持文本、小说、图片占位、视频占位、TTS 占位、内容审核、质量检查、文件解析和 embedding 向量占位。
|
||
- Provider 输入和配置更新会拒绝 `api_key`、`secret`、`token`、`password`、`credential` 等疑似密钥字段。
|
||
- Provider 配置和日志输出会对疑似密钥字段脱敏。
|
||
- `backend/prisma/seed.ts` 更新为写入 9 个默认 mock Provider。
|
||
- README.md 补充 AI Provider 抽象接口说明。
|
||
- 增加 Provider 服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- backend/prisma/seed.ts
|
||
- backend/src/app.module.ts
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/providers/provider.types.ts
|
||
- backend/src/providers/provider.dto.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.controller.ts
|
||
- backend/src/providers/providers.module.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- rg Provider / provider / AI Provider 相关文档和代码
|
||
- npm run typecheck -w backend
|
||
- npx tsc --noEmit --target ES2022 --module CommonJS --moduleResolution Node --esModuleInterop --skipLibCheck --strict backend/prisma/seed.ts
|
||
- npm test -w backend -- providers.service.spec.ts
|
||
- DATABASE_URL=... npm run db:seed
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- Node fetch 真实接口联调:注册并提升 admin、bootstrap mock providers、查询 providers、执行 TextProvider、创建 render_task 后执行 ImageProvider、指定 provider test、验证疑似密钥字段拒绝、查询 provider logs、查询 costs
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- seed.ts TypeScript 编译检查:通过
|
||
- backend Provider 服务单测:通过,6 个测试通过
|
||
- db:seed:通过,已写入或更新默认 mock Provider 配置
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 15 个测试文件,75 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后端日志确认 Provider 路由全部映射成功
|
||
- 真实联调 POST /api/admin/providers/bootstrap-mocks 成功,返回 9 个 mock Provider
|
||
- GET /api/admin/providers 成功,确认 TextProvider 和 ImageProvider 均为 mock
|
||
- POST /api/admin/providers/execute 执行 TextProvider 成功,写入 success provider_log
|
||
- POST /api/admin/providers/execute 执行 ImageProvider 成功,返回 `mock://image/...png`
|
||
- ImageProvider 执行传入 task_id 后,对应 render_task 状态变为 success,并写入 provider_id 和 provider_request_id
|
||
- POST /api/admin/providers/:providerId/test 成功执行指定 Provider
|
||
- 传入 `input_json.api_key` 被拒绝,返回 400
|
||
- GET /api/admin/provider-logs 成功返回日志
|
||
- GET /api/admin/costs 成功返回 mock 成本聚合,总成本为 0
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 当前 Provider 全部为 deterministic mock,不调用真实 AI Provider。
|
||
- 真实 Provider、真实限流、真实计费、额度扣减和外部错误码映射留到后续阶段。
|
||
- 前面已实现的原创小说、故事圣经、角色、记忆、分集、脚本和分镜仍是各自服务内的 deterministic mock,尚未逐步迁移为统一 Provider 调用。
|
||
- 真实联调产生了测试 admin、项目、render_task 和 provider_logs 数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 跳过人工审核后进入阶段 15:图片生成 mock。
|
||
|
||
### 阶段 15:图片生成 mock
|
||
|
||
完成时间:2026-05-31 20:15:52 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 ImagesModule、ImagesController、ImagesService。
|
||
- 新增图片 DTO、安全输出类型、角色图类型和分镜图类型。
|
||
- 支持 POST /api/characters/:characterId/generate-images 生成角色候选图、锚点图和表情图。
|
||
- 支持 GET /api/characters/:characterId/images 查询角色图片。
|
||
- 支持 POST /api/characters/:characterId/set-anchor 设置角色锚点图。
|
||
- 支持 POST /api/storyboard-shots/:shotId/images/generate 生成单个分镜 preview / final 图片。
|
||
- 支持 GET /api/storyboard-shots/:shotId/images 查询单个分镜图片。
|
||
- 支持 POST /api/episodes/:episodeId/shot-images/generate 批量生成某集 confirmed 分镜图片。
|
||
- 角色图片生成要求角色状态为 locked。
|
||
- 分镜图片生成要求 storyboard_shots.status=confirmed。
|
||
- 角色图 Prompt 组合角色姓名、角色类型、性别、年龄、身份、外貌、脸型、发型、眼睛、体型、服装和道具规则。
|
||
- 分镜图 Prompt 组合项目、镜头、场景、地点、画面、动作、台词、旁白、运镜、特效和锁定角色描述。
|
||
- 分镜图 Prompt 会引用角色 `anchor_asset_id`,用于后续真实 ImageProvider 做角色一致性约束。
|
||
- 每次图片生成都会创建 `render_tasks`,调用 `ImageProvider` mock,写入 `provider_logs`。
|
||
- mock 图片会保存为本地私有 SVG 文件,写入 `assets`,asset_type=image,visibility=private。
|
||
- 角色图片写入 `character_images`,分镜图片写入 `shot_images`。
|
||
- 设置锚点图会更新 `character_images.is_anchor` 和 `characters.anchor_asset_id`。
|
||
- 项目状态会随图片阶段更新为 `character_image_generated`、`preview_images_generated` 或 `final_images_generated`。
|
||
- README.md 补充图片生成 mock 接口说明。
|
||
- 增加图片服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/app.module.ts
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/images/image.dto.ts
|
||
- backend/src/images/image.types.ts
|
||
- backend/src/images/images.service.ts
|
||
- backend/src/images/images.controller.ts
|
||
- backend/src/images/images.module.ts
|
||
- backend/src/images/images.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- rg 图片 / ImageProvider / 角色图 / 锚点 / shot_images / character_images 相关文档和代码
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend -- images.service.spec.ts
|
||
- npm run lint
|
||
- npm test
|
||
- npm run build
|
||
- Node fetch 真实接口联调:注册用户、创建项目、准备 locked 角色、准备 confirmed 分集和分镜、生成角色图、设置锚点图、查询角色图、生成分镜 preview 图、查询分镜图、批量生成 episode final 图、验证 assets / render_tasks / provider_logs
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend 图片服务单测:通过,5 个测试通过
|
||
- npm run lint:通过
|
||
- npm test:通过,backend 16 个测试文件,80 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 真实联调生成角色图片 2 张,自动设置 anchor_asset_id
|
||
- GET /characters/:id/images 返回 2 张角色图,图片 asset_path 为 local private SVG
|
||
- POST /storyboard-shots/:id/images/generate 成功生成 preview 图
|
||
- GET /storyboard-shots/:id/images 返回分镜图
|
||
- POST /episodes/:id/shot-images/generate 成功批量生成 final 图
|
||
- 真实联调项目写入 4 个 image assets、4 个 image render_tasks、4 条 ImageProvider provider_logs
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 当前图片是 SVG mock 占位图,不是真实模型生成图片。
|
||
- 图片质检仅预留字段 `quality_score=92`,尚未接入 QualityCheckProvider。
|
||
- 图片生成目前同步执行 Provider mock,尚未由 worker 消费 image_queue。
|
||
- 真实联调产生了测试用户、项目、角色、分集、分镜、assets、render_tasks、provider_logs 数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 跳过人工审核后进入阶段 16:TTS / 字幕 / FFmpeg。
|
||
|
||
### 阶段 16:TTS / 字幕 / FFmpeg
|
||
|
||
完成时间:2026-05-31 20:30:10 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 MediaModule、MediaController、MediaService。
|
||
- 新增音频生成、字幕生成和视频渲染 DTO 与安全输出类型。
|
||
- 支持 POST /api/episodes/:episodeId/audio/generate 生成单集旁白音频。
|
||
- 支持 POST /api/episodes/:episodeId/subtitle/generate 生成单集 SRT 字幕。
|
||
- 支持 POST /api/episodes/:episodeId/video/render 渲染单集视频。
|
||
- 支持 GET /api/episodes/:episodeId/media-assets 查询单集音频、字幕和视频资产。
|
||
- 音频生成要求已有 confirmed 单集脚本,会组合脚本旁白、分镜旁白和台词作为 TTS 输入。
|
||
- 音频生成通过 `VoiceProvider` mock 执行,写入 `render_tasks`、`provider_logs` 和本地私有 WAV 资产。
|
||
- 字幕生成要求已有 confirmed 分镜,会按镜头时长生成 SRT cues,并写入本地私有 `.srt` 资产。
|
||
- 视频渲染要求已有 confirmed 分镜和 generated 分镜图,缺少分镜图时返回 400。
|
||
- 视频渲染默认复用最新音频和字幕;不存在时会自动生成。
|
||
- 视频渲染通过 `VideoProvider` mock 记录执行日志,默认使用 FFmpeg 读取私有分镜图、音频和字幕并写入本地私有 MP4 资产。
|
||
- `prefer_ffmpeg=false` 或本机缺少 FFmpeg 时保留 mock fallback。
|
||
- 项目状态随媒体阶段更新为 `audio_generated`、`subtitle_generated`、`video_rendered`。
|
||
- README.md 补充 TTS / 字幕 / FFmpeg 接口说明。
|
||
- 增加媒体服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/app.module.ts
|
||
- backend/src/projects/project.types.ts
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/media/media.dto.ts
|
||
- backend/src/media/media.types.ts
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.controller.ts
|
||
- backend/src/media/media.module.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- command -v ffmpeg
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend -- media.service.spec.ts
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- Node fetch 真实接口联调:注册用户、创建项目、准备 confirmed 单集脚本、confirmed 分镜、generated 分镜图,生成 audio、subtitle、video,并验证 assets / render_tasks / provider_logs
|
||
|
||
测试结果:
|
||
|
||
- 阶段完成时本机 `ffmpeg` 未安装,因此阶段 16 当次视频联调使用 mock fallback。
|
||
- backend typecheck:通过
|
||
- backend 媒体服务单测:通过,5 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 17 个测试文件,85 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 真实联调 POST /episodes/:episodeId/audio/generate 成功生成 audio asset,mime_type 为 audio/wav,task_status 为 success
|
||
- 真实联调 POST /episodes/:episodeId/subtitle/generate 成功生成 subtitle asset,mime_type 为 application/x-subrip,生成 1 条 SRT cue
|
||
- 真实联调 POST /episodes/:episodeId/video/render 成功生成 video asset,mime_type 为 video/mp4,status 为 mock,`ffmpeg_used=false`
|
||
- 真实联调 GET /episodes/:episodeId/media-assets 返回 3 个媒体资产
|
||
- 真实联调写入 1 个 audio asset、1 个 subtitle asset、1 个 video asset
|
||
- 真实联调写入 `audio_generate`、`subtitle_generate`、`video_render` 各 1 个 success render_task
|
||
- 真实联调写入 VoiceProvider 和 VideoProvider success provider_log 各 1 条
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 当前 TTS 为静音 WAV mock,不调用真实 TTS Provider。
|
||
- 当前 TTS 为静音 WAV mock,但视频已切换为真实 FFmpeg 合成。
|
||
- 音频、字幕和视频目前同步执行 Provider mock,尚未由 worker 消费 audio/subtitle/video 队列。
|
||
- 未接入 BGM、音效、字幕样式、封面图和真实视频编码参数。
|
||
- 真实联调产生了测试用户、项目、分集、分镜、assets、render_tasks、provider_logs 数据,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 跳过人工审核后进入阶段 17:后台管理。
|
||
|
||
补充记录:2026-05-31 20:40:04 CST
|
||
|
||
- 已在 AlmaLinux 9.7 上安装 RPM Fusion free 仓库和 FFmpeg。
|
||
- 已安装 `ffmpeg-5.1.9-2.el9.x86_64`、`ffmpeg-libs-5.1.9-2.el9.x86_64` 及相关音视频依赖。
|
||
- 已验证 `ffmpeg -version` 可用,`libx264` 和 `aac` 编码器可用。
|
||
- 已用 FFmpeg 生成 1 秒 smoke test MP4,并用 `ffprobe` 验证输出文件时长和大小。
|
||
- 注意:此时阶段 16 业务代码仍生成 MP4 placeholder;后续如需真实合成,需要改造 `MediaService.createVideoBuffer` 使用 FFmpeg 拼接分镜图、音频和字幕。
|
||
|
||
补充记录:2026-05-31 20:46:04 CST
|
||
|
||
- 已将 `MediaService.createVideoBuffer` 从 FFmpeg mock 改为真实 FFmpeg 合成。
|
||
- 默认视频渲染会读取私有分镜图资产、WAV 音频资产和 SRT 字幕资产,写入临时目录后用 FFmpeg 生成 1080x1920 MP4。
|
||
- 每个分镜图会按 `storyboard_shots.duration` 生成视频片段,再通过 concat demuxer 合并。
|
||
- 字幕通过 FFmpeg `subtitles` filter 烧录进画面,音频转码为 AAC。
|
||
- `prefer_ffmpeg=false` 仍保留 mock fallback;FFmpeg 不存在时仍返回 `mock_ffmpeg_unavailable`。
|
||
- FFmpeg 合成失败或输入资产无法读取时,会把 `video_render` 任务标记为 `failed`,并写入 `VIDEO_RENDER_FAILED`。
|
||
- 真实联调成功生成 active video asset,返回 `ffmpeg_used=true`、`render_backend=ffmpeg`。
|
||
- `ffprobe` 验证输出包含 1080x1920 H.264 视频流和 AAC 音频流,时长 4 秒。
|
||
- 真实联调写入 1 个 image asset、1 个 audio asset、1 个 subtitle asset、1 个 active video asset。
|
||
- 真实联调写入 `shot_image_generate`、`audio_generate`、`subtitle_generate`、`video_render` 各 1 个 success render_task。
|
||
- 真实联调写入 ImageProvider、VoiceProvider、VideoProvider success provider_log 各 1 条。
|
||
- 补充验证:`npm run lint`、`npm run typecheck`、`npm test`、`npm run build` 均通过;backend 17 个测试文件,85 个测试通过。
|
||
|
||
### 阶段 17:后台管理
|
||
|
||
完成时间:2026-05-31 21:04:26 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 AdminModule、AdminController、AdminService。
|
||
- 新增后台 DTO 和安全输出辅助。
|
||
- 支持 GET /api/admin/dashboard 查询仪表盘指标。
|
||
- 支持 GET /api/admin/projects 查询项目列表,包含 owner、episode/asset/task 计数和最近任务。
|
||
- 支持 GET /api/admin/projects/:projectId 查询项目详情,包含小说源、章节、故事圣经摘要、角色、分集、素材、任务、Provider 日志、版权记录和成本。
|
||
- 支持 PATCH /api/admin/projects/:projectId/status 调整项目状态,并写入 operation_logs。
|
||
- 支持 GET /api/admin/users 查询用户列表和项目/素材计数。
|
||
- 支持 GET /api/admin/assets 查询素材列表。
|
||
- 支持 GET /api/admin/novel-sources 查询小说源列表,包含项目和章节数量。
|
||
- 支持 GET /api/admin/novel-chapters 查询章节列表,支持项目、小说源和状态筛选。
|
||
- 支持 GET /api/admin/characters 查询角色资源列表,包含项目、图片数量和长篇记忆数量。
|
||
- 支持 GET /api/admin/storyboard-shots 查询分镜资源列表,包含项目、分集、图片数量和最新分镜图 asset。
|
||
- 支持 GET /api/admin/works 查询成品漫剧列表,按 video asset 汇总项目、用户、分集和渲染任务。
|
||
- 支持 GET /api/admin/copyright-records 查询版权确认记录。
|
||
- 后台接口统一要求 admin 角色。
|
||
- admin 前端从静态骨架升级为可登录、可请求真实 API 的 Vue/Vite 控制台。
|
||
- 前端支持仪表盘、项目管理、小说管理、角色资源、分镜资源、成品漫剧、任务管理、AI Provider、成本日志、用户管理、素材管理和版权记录视图。
|
||
- 前端接入已有任务接口,支持失败任务重试、取消、转人工。
|
||
- 前端接入已有 Provider 接口,支持初始化 mock providers、查看 Provider 配置和 Provider 日志。
|
||
- `backend/prisma/seed.ts` 改为生成真实 bcrypt 管理员密码,默认本地账号 `admin@example.com` / `Admin123!`,支持 `SEED_ADMIN_PASSWORD` 覆盖。
|
||
- README.md 补充后台管理接口、资源管理入口、管理端地址和本地管理员账号说明。
|
||
- 增加后台服务单元测试。
|
||
|
||
修改文件:
|
||
|
||
- backend/prisma/seed.ts
|
||
- backend/src/app.module.ts
|
||
- backend/src/projects/project.types.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- .env.example
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.types.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.module.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- admin/src/api/client.ts
|
||
|
||
运行命令:
|
||
|
||
- rg / sed 阅读后台管理设计文档、验收文档、现有 admin/API 代码
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend -- admin.service.spec.ts
|
||
- npm run typecheck -w admin
|
||
- npm run build -w admin
|
||
- DATABASE_URL=... npm run db:seed
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- Node fetch 真实接口联调:admin 登录、仪表盘、项目列表、项目详情、任务列表、队列统计、Provider 列表、成本、用户列表、素材列表、版权记录
|
||
- Node fetch 真实资源联调:小说源列表、章节列表、角色资源、分镜资源、成品漫剧
|
||
- Node fetch 真实任务操作联调:创建 failed render_task,调用 retry、manual-required、cancel
|
||
- npx tsc --noEmit ... backend/prisma/seed.ts
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:5175
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend Admin 服务单测:通过,4 个测试通过
|
||
- admin typecheck:通过
|
||
- admin build:通过
|
||
- db:seed:通过,已更新本地 admin@example.com 为可登录 admin 用户
|
||
- 后端健康检查返回 code=0,status=ok
|
||
- 后台真实联调 admin 登录成功,role=admin
|
||
- GET /api/admin/dashboard 成功返回 total_users、total_projects、failed_tasks、queue_backlog、ai_cost_actual 等指标
|
||
- GET /api/admin/projects 成功返回项目列表
|
||
- GET /api/admin/projects/:projectId 成功返回项目详情和关联计数
|
||
- GET /api/admin/tasks、/admin/queues、/admin/providers、/admin/costs、/admin/users、/admin/assets、/admin/copyright-records 均通过真实联调
|
||
- GET /api/admin/novel-sources、/admin/novel-chapters、/admin/characters、/admin/storyboard-shots、/admin/works 均通过真实联调
|
||
- 成品漫剧联调成功返回阶段 16 生成的 video asset,并关联项目、分集和 render_task
|
||
- 任务操作真实联调成功:failed 任务 retry 后进入 retrying,随后可转 manual_required,再取消为 cancelled
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 18 个测试文件,89 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- admin dev server 已在 `http://127.0.0.1:5175` 返回 200,并热更新到新后台页面
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 后台当前是轻量 Vue/Vite 控制台,还不是完整 Geeker-Admin 二开工程。
|
||
- 内容审核、订单额度、模板管理仅保留入口方向,具体业务留到后续阶段。
|
||
- 用户管理当前只读,未做禁用用户、改角色、重置密码等高危操作。
|
||
- 项目状态调整已写 operation_logs,但完整操作日志查询页尚未实现。
|
||
- 真实联调产生了一个 stage17 测试 render_task 及操作痕迹,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 跳过人工审核后进入阶段 18:uni-app 用户端。
|
||
|
||
### 阶段 18:uni-app 用户端
|
||
|
||
完成时间:2026-05-31 21:36:00 CST
|
||
|
||
完成内容:
|
||
|
||
- 将 user-app 从静态 H5 骨架升级为可连接真实 API 的用户端制作台。
|
||
- 用户端支持登录、注册、退出和本地 token 恢复。
|
||
- 支持新建 AI 原创 / 上传小说改编项目,并可查看和切换我的项目。
|
||
- 支持 AI 原创小说一键生成:idea、outline、chapters、self-check。
|
||
- 支持上传小说入口:粘贴文本、H5 文件选择、版权确认和解析。
|
||
- 支持故事圣经生成和确认。
|
||
- 支持角色抽取、角色锚点图生成入口和角色库确认。
|
||
- 支持长篇记忆生成,补齐分集计划前置依赖。
|
||
- 支持分集计划生成、分集选择和分集确认。
|
||
- 支持单集脚本生成/确认、分镜生成/确认、分镜图生成、音频字幕生成和 FFmpeg 视频合成。
|
||
- 支持项目任务进度、失败任务数量和任务错误信息查看。
|
||
- 支持成品视频列表、私有视频预览和私有 MP4 下载。
|
||
- 用户端样式按 H5 优先设计,移动端为底部导航和单列流程,PC 宽屏为左侧导航和两栏制作台。
|
||
- 保留 uni-app `pages.json`、`manifest.json` 和页面路由文件,后续微信小程序/App 可继续迁移。
|
||
- 后端新增 `GET /api/assets/:assetId/download` 私有下载接口,校验 asset 归属后返回文件流。
|
||
- 全局 API 响应拦截器支持跳过 `StreamableFile`,避免下载流被 JSON envelope 包裹。
|
||
- README.md 补充用户端 H5、私有下载接口和阶段状态说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/assets/assets.controller.ts
|
||
- backend/src/assets/assets.service.ts
|
||
- backend/src/assets/assets.service.spec.ts
|
||
- backend/src/common/api-response.interceptor.ts
|
||
- user-app/manifest.json
|
||
- user-app/pages.json
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/workflow.ts
|
||
- user-app/src/pages/auth/login.vue
|
||
- user-app/src/pages/projects/create.vue
|
||
- user-app/src/pages/projects/source-select.vue
|
||
- user-app/src/pages/projects/original-setting.vue
|
||
- user-app/src/pages/projects/upload-novel.vue
|
||
- user-app/src/pages/projects/copyright.vue
|
||
- user-app/src/pages/projects/story-bible.vue
|
||
- user-app/src/pages/projects/characters.vue
|
||
- user-app/src/pages/projects/episodes.vue
|
||
- user-app/src/pages/projects/storyboard.vue
|
||
- user-app/src/pages/projects/progress.vue
|
||
- user-app/src/pages/projects/result.vue
|
||
- user-app/src/pages/user/projects.vue
|
||
- user-app/src/pages/user/profile.vue
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- rg / sed 阅读用户端阶段文档、现有 user-app、后端 API controller / dto / service
|
||
- npm view @dcloudio/uni-app version
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w user-app
|
||
- npm test -w backend -- assets.service.spec.ts
|
||
- npm run build -w user-app
|
||
- Node fetch 真实用户端流程联调:注册用户、创建原创项目、原创小说、故事圣经、角色、长篇记忆、分集、脚本、分镜、分镜图、音频、字幕、视频合成、私有下载
|
||
- curl http://127.0.0.1:5174
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- user-app typecheck:通过
|
||
- backend Assets 服务单测:通过,4 个测试通过
|
||
- user-app build:通过
|
||
- 用户端 dev server 已在 `http://127.0.0.1:5174` 返回 200,并热更新到新页面
|
||
- 真实用户端流程联调成功:临时用户创建 1 集原创项目,生成 video asset `29`
|
||
- 真实联调 FFmpeg 返回 `ffmpeg_used=true`、`render_backend=ffmpeg`
|
||
- 私有下载接口返回 `content-type=video/mp4`、`content-length=222085`,MP4 头部探测为 `ftypisom`
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 18 个测试文件,90 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 当前用户端仍以 Vue/Vite H5 可运行版本为主,没有正式切换到 `@dcloudio/vite-plugin-uni` 构建链。
|
||
- 微信小程序/App 的文件选择、下载保存、分享、支付、登录授权等平台能力尚未适配。
|
||
- 用户端当前不提供深度编辑页;故事圣经、角色、分集、脚本和分镜的编辑能力仍主要在 API / 后台侧。
|
||
- 订单额度、支付冻结和正式生成前扣费尚未接入。
|
||
- 真实联调产生了一个 stage18 测试用户、项目、任务、素材和 MP4 资产,未清理。
|
||
|
||
补充记录:2026-05-31 21:46:00 CST
|
||
|
||
- 用户反馈用户端访问异常。
|
||
- 已确认用户端 dev server 正常监听 `0.0.0.0:5174`,后端正常监听 `0.0.0.0:3000`。
|
||
- Vite 当前外网访问地址为 `http://152.53.37.118:5174/`。
|
||
- 修复用户端默认 API 地址:外网 IP/域名访问时自动请求同主机 `:3000/api`,避免浏览器把 `127.0.0.1:3000` 当作用户本机。
|
||
- README.md 已同步说明动态 API 默认行为。
|
||
|
||
补充记录:2026-05-31 21:52:00 CST
|
||
|
||
- 用户再次反馈无法访问前端页面。
|
||
- 已定位本机 firewalld 未放行 TCP `5174` 和 `3000`,公网访问会被防火墙挡住。
|
||
- 已执行 `firewall-cmd --add-port=5174/tcp --add-port=3000/tcp` 和 permanent 持久化后 reload。
|
||
- 已验证 firewalld 查询 `5174/tcp`、`3000/tcp` 均为 yes。
|
||
- 已验证 `http://152.53.37.118:5174/` 返回 HTTP 200,`http://152.53.37.118:3000/api/health` 返回后端健康检查成功。
|
||
- README.md 已补充公网调试访问需放行 TCP `5174` 和 `3000`。
|
||
|
||
下一步建议:
|
||
|
||
- 跳过人工审核后进入阶段 19:订单额度。
|
||
|
||
### 阶段 19:订单额度
|
||
|
||
完成时间:2026-05-31 22:08:00 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 BillingModule、BillingController、BillingService。
|
||
- 基于现有 `orders`、`quota_accounts`、`quota_logs` 表实现套餐、订单、额度账户和额度流水。
|
||
- 支持 GET /api/billing/packages 公开查看 4 个套餐:试用版、标准短剧版、连载测试版、高端定制版。
|
||
- 支持 GET /api/billing/quota 查询当前用户额度账户,不存在时自动创建 0 额度账户。
|
||
- 支持 GET /api/billing/quota/logs 查询当前用户额度流水。
|
||
- 支持 GET /api/billing/orders 查询当前用户订单。
|
||
- 支持 POST /api/billing/orders 创建 pending 订单。
|
||
- 支持 POST /api/billing/orders/:orderId/mock-pay 模拟支付,订单标记 paid,并写入 recharge 额度流水。
|
||
- 支持 GET /api/projects/:projectId/quota/estimate 估算项目生成额度。
|
||
- 支持 POST /api/projects/:projectId/quota/freeze 冻结项目额度,项目 `payment_status` 变为 `quota_frozen`。
|
||
- 支持 POST /api/projects/:projectId/quota/release 释放项目冻结额度。
|
||
- 视频合成前校验项目必须已冻结额度或已支付。
|
||
- 视频合成成功后自动扣减冻结额度,写入 deduct 额度流水,项目 `payment_status` 变为 `paid`。
|
||
- 支持 GET /api/admin/orders 管理员查看订单。
|
||
- 支持 GET /api/admin/quota-accounts 管理员查看额度账户。
|
||
- 支持 POST /api/admin/users/:userId/quota/grant 管理员手动赠送额度。
|
||
- 用户端新增“额度”导航和额度中心,支持套餐、模拟支付、订单、额度账户和项目预估。
|
||
- 用户端制作台新增支付/额度卡片,视频合成前会自动尝试冻结额度。
|
||
- 管理端新增“订单额度”页面,展示订单和额度账户。
|
||
- README.md 补充订单额度接口、视频合成额度约束和阶段状态。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/app.module.ts
|
||
- backend/src/media/media.module.ts
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- admin/src/App.vue
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/billing/billing.dto.ts
|
||
- backend/src/billing/billing.types.ts
|
||
- backend/src/billing/billing.service.ts
|
||
- backend/src/billing/billing.controller.ts
|
||
- backend/src/billing/billing.module.ts
|
||
- backend/src/billing/billing.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- rg / sed 阅读订单额度设计文档、现有 Prisma 表、媒体合成服务和用户端页面
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend -- billing.service.spec.ts media.service.spec.ts
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- npm run typecheck -w admin
|
||
- Node fetch 真实接口联调:套餐、注册用户、创建项目、创建订单、模拟支付、额度冻结、额度流水
|
||
- Node fetch 真实生成联调:未冻结时视频合成拒绝,模拟支付和冻结后视频合成成功并扣减额度
|
||
- Node fetch 管理员接口联调:admin/orders、admin/quota-accounts
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- billing + media 单测:通过,2 个测试文件,11 个测试通过
|
||
- user-app typecheck:通过
|
||
- user-app build:通过
|
||
- admin typecheck:通过
|
||
- 真实订单额度联调成功:标准短剧版 mock 支付后可用额度 120,1 集项目预估 69,冻结后可用额度 51、项目状态 `quota_frozen`
|
||
- 真实生成联调成功:未冻结时 `/video/render` 返回 `Project quota must be frozen before formal video render`
|
||
- 冻结后视频合成成功生成 video asset `42`,项目 `payment_status=paid`
|
||
- 扣减后额度账户:available=51、frozen=0、used=69
|
||
- 额度流水顺序包含 deduct、freeze、recharge
|
||
- 管理员订单和额度账户接口均通过真实联调
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 19 个测试文件,96 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端、用户端、管理端本地 HTTP 均返回 200
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 当前支付为 mock,不接入微信支付、支付宝、Stripe 或真实回调验签。
|
||
- 套餐暂为代码常量,未做后台可配置套餐表。
|
||
- 额度预估按默认每集 6 个镜头估算,后续可结合实际分镜数量动态重算。
|
||
- 系统失败后的冻结额度自动释放/重试占用策略尚未细化,目前成功扣减、手动 release 可释放。
|
||
- 真实联调产生了 stage19 测试用户、订单、额度流水、项目、任务和素材资产,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 跳过人工审核后进入阶段 20:内容审核。
|
||
|
||
### 阶段 20:内容审核
|
||
|
||
完成时间:2026-05-31 22:32:40 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 ReviewsModule、ReviewsController、ReviewsService。
|
||
- 基于现有 `content_reviews` 表实现项目文本审核、素材审核、用户审核记录列表和管理员审核处理。
|
||
- 基于现有 `case_showcases` 表实现用户公开案例授权、用户案例列表、管理员案例列表和发布/驳回处理。
|
||
- 支持 POST /api/projects/:projectId/reviews/text,对项目文本或请求体 `content` 执行内容审核。
|
||
- 支持 GET /api/projects/:projectId/reviews 查询当前项目审核记录。
|
||
- 支持 POST /api/assets/:assetId/review,对 image/video/audio/subtitle/document 等素材执行审核。
|
||
- 支持 POST /api/projects/:projectId/showcase/authorize 提交公开案例授权。
|
||
- 支持 GET /api/projects/:projectId/showcase 查看项目公开案例授权记录。
|
||
- 支持 GET /api/admin/content-reviews 管理员查询审核队列。
|
||
- 支持 PATCH /api/admin/content-reviews/:reviewId 管理员通过、修改、驳回、屏蔽或转人工。
|
||
- 支持 GET /api/admin/case-showcases 管理员查看公开案例授权。
|
||
- 支持 PATCH /api/admin/case-showcases/:showcaseId 管理员授权、发布或驳回公开案例。
|
||
- 内容审核复用阶段 14 的 `ModerationProvider` mock,命中敏感关键词时写入 `manual_required`,否则写入 `passed`。
|
||
- 需要人工处理的审核会把项目状态标记为 `manual_required`。
|
||
- 后台管理新增“内容审核”页,支持筛选审核状态、处理审核项、发布/驳回公开案例。
|
||
- 用户端新增“审核”导航和制作台审核卡片,支持文本审核、成品视频审核、审核状态查看和公开案例授权。
|
||
- README.md 补充内容审核接口、后台能力、用户端接入和当前阶段状态。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/app.module.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- admin/src/App.vue
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/reviews/review.dto.ts
|
||
- backend/src/reviews/review.types.ts
|
||
- backend/src/reviews/reviews.controller.ts
|
||
- backend/src/reviews/reviews.service.ts
|
||
- backend/src/reviews/reviews.module.ts
|
||
- backend/src/reviews/reviews.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- rg / sed 阅读内容审核、后台管理、Codex 阶段文档、现有 Prisma schema、Provider mock、后台和用户端页面
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend -- reviews.service.spec.ts
|
||
- npm run typecheck -w admin
|
||
- npm run typecheck -w user-app
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- Node fetch 真实内容审核联调:注册用户、创建项目、文本审核、敏感文本触发人工、上传素材、素材审核、公开案例授权、管理员审核通过、管理员发布案例
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl -I http://127.0.0.1:5175
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- reviews 单测:通过,1 个测试文件,8 个测试通过
|
||
- admin typecheck:通过
|
||
- user-app typecheck:通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 20 个测试文件,104 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 真实内容审核联调成功:clean 文本 `passed`,含“违规”的文本 `manual_required`,管理员更新后 `passed`
|
||
- 真实资产审核联调成功:上传 document asset `43` 后审核 `passed`
|
||
- 真实公开案例联调成功:用户授权后后台发布为 `published/public`
|
||
- 真实联调项目 `26` 共写入 4 条审核记录和 1 条公开案例记录
|
||
- 后端健康检查返回 code=0,用户端 H5 和管理端 HTTP 均返回 200
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- npm audit 当前提示 8 个依赖风险,未执行强制修复,避免破坏阶段成果。
|
||
- 当前内容审核为 mock moderation,不接入真实内容安全平台、版权库、OCR/ASR/视频抽帧审核或人工工单系统。
|
||
- 管理员通过审核不会自动恢复此前因风险被标记为 `manual_required` 的项目状态,后续可结合完整人工审核工作流细化状态回滚。
|
||
- 公开案例授权和发布当前只记录授权状态与可见性,未做真实前台案例广场。
|
||
- 真实联调产生了 stage20 测试用户、项目、素材、审核记录和公开案例记录,未清理。
|
||
|
||
下一步建议:
|
||
|
||
- 跳过人工审核后进入阶段 21:真实 AI Provider 接入。
|
||
|
||
### 阶段 21:真实 AI Provider 接入
|
||
|
||
完成时间:2026-05-31 22:58:00 CST
|
||
|
||
完成内容:
|
||
|
||
- 使用 OpenAI 官方文档确认 Responses API、Image API、Moderation、Embeddings 和 Text to Speech 的当前接入形态。
|
||
- 新增 `DEFAULT_OPENAI_PROVIDER_CONFIGS`,支持一键初始化 OpenAI real provider 配置。
|
||
- 新增 `POST /api/admin/providers/bootstrap-openai`。
|
||
- `ProvidersService` 支持 `real` 模式,按 `config_json.driver` 调用:
|
||
- `openai_responses` -> `/v1/responses`
|
||
- `openai_moderation` -> `/v1/moderations`
|
||
- `openai_embeddings` -> `/v1/embeddings`
|
||
- `openai_image_generation` -> `/v1/images/generations`
|
||
- `openai_audio_speech` -> `/v1/audio/speech`
|
||
- Provider 配置只保存 `api_key_env` 这类环境变量引用,不保存真实密钥;原始 `api_key`、`token`、`secret` 等字段仍会被拒绝或脱敏。
|
||
- 真实图片和 TTS 调用日志只保存 URL/大小/hash 等元数据,不把 base64 图片或音频字节写入 `provider_logs`。
|
||
- OpenAI 图片和 TTS real provider 默认优先级低于 mock,避免现有 mock 图片/本地音频生产链路在未接真实资产落库前误消耗真实模型。
|
||
- 后台 AI Provider 页面支持初始化 OpenAI Provider、查看 driver、指定 provider 测试并展示测试结果。
|
||
- README 补充真实 Provider 环境变量、接口和当前边界说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/provider.types.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.controller.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w admin
|
||
- npm test -w backend -- providers.service.spec.ts
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- Node fetch 真实接口冒烟:admin 登录、bootstrap OpenAI Provider、查询 Provider、指定 OpenAI TextProvider 执行并在无 `OPENAI_API_KEY` 时 fallback 到 mock
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- admin typecheck:通过
|
||
- backend Provider 单测:通过,10 个测试通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 20 个测试文件 108 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 后端健康检查:通过
|
||
- 真实接口冒烟:`bootstrap-openai` 返回 6 个 OpenAI Provider;指定 `openai-responses-text` 时因未配置 `OPENAI_API_KEY` 记录 failed attempt,并成功 fallback 到 `mock-text`
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- 本机未配置真实 `OPENAI_API_KEY`,因此本阶段只做了 mock fetch 单测和配置/路由验证;未向 OpenAI 发起真实付费调用。
|
||
- 原创小说、故事圣经、角色、记忆、分集、脚本和分镜仍是各自服务内 deterministic 生成逻辑,后续可逐步迁移到统一 Provider。
|
||
- 图片/TTS real provider 已能测试调用,但现有图片、音频、视频生产链路仍默认 mock/本地合成,真实图片和音频资产落库需要后续阶段接入。
|
||
- VideoProvider 暂无 OpenAI 视频生成真实驱动,仍保持 mock。
|
||
|
||
下一步建议:
|
||
|
||
- 进入 MVP 验收,按原创小说 3 集 MP4 与上传小说 1 集 MP4 两条链路做端到端检查。
|
||
|
||
### 阶段 22:MVP 验收
|
||
|
||
完成时间:2026-06-01 00:15:00 CST
|
||
|
||
完成内容:
|
||
|
||
- 使用本机 API 跑通系统 A 两条 MVP 闭环。
|
||
- AI 原创小说 3 集链路:注册验收用户、mock 支付充值、创建原创项目、生成原创构思/大纲/章节、自检、故事圣经、角色、角色锚点图、长篇记忆、3 集分集计划、3 集脚本、3 集分镜、30 张正式分镜图、3 集音频、3 集字幕、3 个 FFmpeg MP4、私有下载校验、成品视频审核和公开案例授权。
|
||
- 上传小说 1 集链路:TXT 文件上传、版权确认、小说解析、故事圣经、角色、角色锚点图、长篇记忆、1 集分集计划、脚本、分镜、10 张正式分镜图、音频、字幕、FFmpeg MP4、私有下载校验、成品视频审核和公开案例授权。
|
||
- 后台详情校验项目、素材和任务数量。
|
||
- 验收发现并修复 mock 文本审核误伤安全规则提示的问题:`不得生成违法、低俗、仇恨、侵权...` 这类合规约束不再被 `违法` 关键词误判;真实风险词仍会进入 `manual_required`。
|
||
- 更新 README 当前阶段、版权授权枚举、MVP 验收结果和 mock moderation 说明。
|
||
|
||
验收数据:
|
||
|
||
- 验收用户:`mvp-1780243409631@example.com`,用户 ID `30`
|
||
- AI 原创项目:项目 ID `28`,3 集,状态 `video_rendered`,支付状态 `paid`
|
||
- 上传小说项目:项目 ID `29`,1 集,状态 `video_rendered`,支付状态 `paid`
|
||
- 原创 MP4 asset:`112`、`115`、`118`,私有下载均为 `video/mp4`,大小分别约 367 KB、386 KB、375 KB
|
||
- 上传 MP4 asset:`135`,私有下载为 `video/mp4`,大小约 399 KB
|
||
- 额度账户:`total_quota=1200`,`used_quota=196`,`available_quota=1004`,`frozen_quota=0`
|
||
- 原创文本复审:review `13`,`passed`
|
||
- 上传文本复审:review `14`,`passed`
|
||
- 视频审核:原创 3 条和上传 1 条均 `passed`
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- Node fetch MVP 验收脚本:AI 原创 3 集、上传小说 1 集、私有 MP4 下载、审核、额度和后台详情校验
|
||
- npm test -w backend -- providers.service.spec.ts
|
||
- npm run typecheck -w backend
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
|
||
测试结果:
|
||
|
||
- AI 原创 3 集 MP4:通过
|
||
- 上传小说 1 集 MP4:通过
|
||
- 私有下载校验:4 个视频均返回 `video/mp4`,大小均大于 300 KB
|
||
- 视频审核:通过
|
||
- 文本复审:通过
|
||
- backend Provider 单测:通过,11 个测试通过
|
||
- backend typecheck:通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 20 个测试文件 109 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- MVP 验收使用 mock 支付、mock 图片、mock TTS 和本地 FFmpeg 合成;真实图片/TTS 资产落库、真实支付、真实内容安全平台仍需生产化阶段接入。
|
||
- 因本机未配置 `OPENAI_API_KEY`,文本/视频审核的 OpenAI moderation real provider 会先记录 `OPENAI_API_KEY_NOT_CONFIGURED` 失败 attempt,再 fallback 到 mock moderation。
|
||
- 第一轮验收产生了项目 `27` 的半成品数据,第二轮完整验收项目为 `28` 和 `29`,未清理历史测试数据。
|
||
- 公开案例授权当前为用户提交 `pending/authorized` 流程,未做真实前台案例广场。
|
||
|
||
下一步建议:
|
||
|
||
- 规划生产化阶段:真实图片/TTS 资产落库、OpenAI key 配置策略、真实支付、worker 异步消费、审核工单和微信小程序/App 适配。
|
||
|
||
### 阶段 23:API 加密传输
|
||
|
||
完成时间:2026-06-01 00:32:22 CST
|
||
|
||
完成内容:
|
||
|
||
- 保留并完善 HTTPS 强制策略:生产默认要求 HTTPS,支持反向代理 `X-Forwarded-Proto=https`,生产 CORS 改为显式白名单。
|
||
- 新增 `GET /api/crypto/handshake`,使用短期内存会话完成 ECDH P-256 握手。
|
||
- 前后端使用 `ECDH P-256 + HKDF-SHA256` 派生 AES-256-GCM 会话密钥。
|
||
- 后端新增加密请求中间件:识别加密信封,解密 JSON 请求体后再进入原有 Controller/Service。
|
||
- 后端响应包装和异常过滤器支持加密返回:JSON 成功响应、业务异常响应都会在加密请求上下文中返回 AES-GCM 密文。
|
||
- 后台管理和用户端 API Client 支持按配置启用加密信封:开启后请求前加密业务 payload,收到响应后解密再渲染。
|
||
- 用户端小说文件上传改为先转 base64 文件 payload,再作为加密 JSON 请求发送。
|
||
- 私有素材下载在加密请求下返回加密 JSON 文件 payload,前端解密后生成 Blob,避免成品 MP4 以明文业务响应返回。
|
||
- 前端生产环境默认同源 `/api`,显式 `VITE_API_BASE_URL` 禁止使用 `http://`。
|
||
- API 加密新增后台开关 `security.api_crypto_enabled`,测试默认关闭,上线后可在后台“配置管理”手动开启。
|
||
- 新增 `GET /api/client-config`,前端启动请求前读取加密开关;`API_CRYPTO_ENABLED=true/false` 和 `VITE_API_CRYPTO_ENABLED=true/false` 可强制覆盖。
|
||
- 补充 `.env.example`、README 和 Nginx HTTPS 部署示例。
|
||
|
||
修改文件:
|
||
|
||
- .env.example
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
- backend/src/app.module.ts
|
||
- backend/src/main.ts
|
||
- backend/src/assets/assets.controller.ts
|
||
- backend/src/common/all-exceptions.filter.ts
|
||
- backend/src/common/api-response.interceptor.ts
|
||
- backend/src/common/api-crypto.controller.ts
|
||
- backend/src/common/api-crypto.service.ts
|
||
- backend/src/common/encrypted-request.middleware.ts
|
||
- backend/src/common/secure-transport.middleware.ts
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.types.ts
|
||
- backend/prisma/seed.ts
|
||
- admin/src/App.vue
|
||
- admin/src/api/crypto.ts
|
||
- admin/src/api/client.ts
|
||
- user-app/src/api/crypto.ts
|
||
- user-app/src/api/client.ts
|
||
- deploy/README.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/common/api-crypto.controller.ts
|
||
- backend/src/common/api-crypto.service.ts
|
||
- backend/src/common/api-crypto.service.spec.ts
|
||
- backend/src/common/encrypted-request.middleware.ts
|
||
- backend/src/common/secure-transport.middleware.spec.ts
|
||
- admin/src/api/crypto.ts
|
||
- user-app/src/api/crypto.ts
|
||
- deploy/nginx.https.example.conf
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w admin
|
||
- npm run typecheck -w user-app
|
||
- npm run lint
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run build
|
||
- PORT=3010 HTTPS_REQUIRED=false npm run start -w backend
|
||
- Node fetch 加密握手 + 加密 GET /api/health 冒烟
|
||
- PORT=3011 API_CRYPTO_ENABLED=auto HTTPS_REQUIRED=false npm run start -w backend
|
||
- curl http://127.0.0.1:3011/api/client-config
|
||
- curl http://127.0.0.1:3011/api/health
|
||
- PORT=3012 API_CRYPTO_ENABLED=true HTTPS_REQUIRED=false npm run start -w backend
|
||
- curl http://127.0.0.1:3012/api/client-config
|
||
- curl -i http://127.0.0.1:3012/api/health
|
||
- Node fetch 强制开启下的加密 GET /api/health 冒烟
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- admin typecheck:通过
|
||
- user-app typecheck:通过
|
||
- npm run lint:通过
|
||
- npm run typecheck:通过
|
||
- npm test:通过,backend 22 个测试文件 113 个测试通过,workers 1 个测试通过,admin/user-app 暂无测试文件并以 passWithNoTests 通过
|
||
- npm run build:通过
|
||
- 加密 API 冒烟:`GET /api/crypto/handshake` 成功,带 `x-api-encrypted: v1` 的 `GET /api/health` 返回加密信封,Node 客户端解密后得到 `code=0`、`status=ok`
|
||
- 默认关闭冒烟:`API_CRYPTO_ENABLED=auto` 且数据库配置不可用/未开启时,`GET /api/client-config` 返回 `api_crypto_enabled=false`,普通 `GET /api/health` 明文 JSON 正常返回。
|
||
- 强制开启冒烟:`API_CRYPTO_ENABLED=true` 时,普通 `GET /api/health` 返回 400;带加密 headers 的 `GET /api/health` 返回加密信封并可解密为 `status=ok`。
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- 应用层加密保护请求体和响应体;HTTP 方法、路径、域名和 query string 仍属于传输元数据,生产必须继续使用 HTTPS,且不要把敏感内容放进 query。
|
||
- 加密会话当前保存在单进程内存中;多实例部署需要粘性会话,或把 session 私钥/盐迁移到 Redis 等共享存储。
|
||
- 当前前端加密实现面向 H5 浏览器 WebCrypto;微信小程序/App 需要后续补平台 crypto adapter。
|
||
- 后台开关只对 `API_CRYPTO_ENABLED=auto` 生效;如果环境变量显式设置为 `true` 或 `false`,会覆盖数据库配置。
|
||
|
||
下一步建议:
|
||
|
||
- 进入生产化安全补强:敏感 query 改 POST body、加密会话 Redis 化、CSP/XSS 防护、真实证书部署、微信小程序/App 加密适配。
|
||
|
||
### MVP 易用性修复:后台中文说明 / 额度页排版 / AI Provider 配置入口
|
||
|
||
完成时间:2026-06-01 12:34 CST
|
||
|
||
完成内容:
|
||
|
||
- 后台仪表盘、项目、小说、角色、分镜、成品、订单额度、审核、任务、Provider、成本、用户、素材、配置、版权等页面的 status/type/key 展示改为 `英文码(中文说明)` 或对应中文说明。
|
||
- 后台 AI Provider 页面新增“AI 接入配置”说明区,明确真实 OpenAI/兼容 Provider 的密钥填写在后端环境变量,不在后台保存明文。
|
||
- Provider 表格补充模型环境变量、密钥环境变量和接口地址列,方便运营和部署人员定位配置项。
|
||
- 用户端额度/支付区域改为更稳定的自适应网格,套餐卡、额度数字、订单行在 H5/PC 窄宽度下不再互相挤压。
|
||
- 用户端额度、订单、审核、素材等常见状态展示改为中文短标签,减少 raw code 撑破布局。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w admin
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w admin
|
||
- npm run build -w user-app
|
||
|
||
测试结果:
|
||
|
||
- admin typecheck:通过
|
||
- user-app typecheck:通过
|
||
- admin build:通过
|
||
- user-app build:通过
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- 后台 Provider 页现在显示应填的环境变量名;真实密钥仍需要在服务器后端运行环境或 backend/.env 中填写,并重启后端。
|
||
|
||
下一步建议:
|
||
|
||
- 填入 OPENAI_API_KEY 后,在后台 AI Provider 页面点击“初始化 OpenAI Provider”和“测试”,验证真实模型链路。
|
||
|
||
### 后台运营体验优化:资源预览 / 中文展示 / AI 接入后台配置
|
||
|
||
完成时间:2026-06-01 13:52 CST
|
||
|
||
完成内容:
|
||
|
||
- 后台状态、类型、风险、授权、任务等字段对运营显示中文,不再默认展示英文枚举码。
|
||
- 小说源、章节、角色、分镜、素材、成品漫剧增加预览入口;图片、视频、音频、文本类资源可在后台抽屉内预览或下载。
|
||
- 后端 admin 资源接口补充小说文本预览、章节正文预览、角色设定详情、分镜提示词/动作/旁白等预览字段。
|
||
- AI Provider 增加后台运行配置接口 `PATCH /api/admin/providers/:providerId/runtime-config`,支持后台配置 API Key、Base URL、模型、超时、启停和优先级。
|
||
- API Key 不再要求运营修改服务器环境变量;后台输入后,后端用 AES-256-GCM 加密保存到 Provider 配置中,列表只显示已配置/未配置,不回显明文。
|
||
- README 和 `.env.example` 补充 `PROVIDER_SECRET_KEY` 说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.types.ts
|
||
- backend/src/providers/provider.dto.ts
|
||
- backend/src/providers/providers.controller.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- admin/src/api/client.ts
|
||
- admin/src/api/crypto.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- README.md
|
||
- .env.example
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w admin
|
||
- npm test -w backend -- providers.service.spec.ts
|
||
- npm run build -w backend
|
||
- npm run build -w admin
|
||
- npm test -w backend
|
||
- 重启 3000 后端 dist 进程
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- 登录 admin 后 GET /api/admin/providers
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- admin typecheck:通过
|
||
- providers.service.spec.ts:通过,12 个测试通过
|
||
- backend build:通过
|
||
- admin build:通过
|
||
- backend 全量测试:通过,22 个测试文件 114 个测试通过
|
||
- 后端 3000 已重启到新构建,健康检查返回 `status=ok`
|
||
- 后台页面 5175 返回 200,`GET /api/admin/providers` 返回 15 条 Provider 配置
|
||
|
||
遗留问题:
|
||
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
- 生产环境建议显式设置 `PROVIDER_SECRET_KEY`;否则 Provider 密钥加密会回退使用 `JWT_SECRET`。
|
||
- 后台预览依赖已有私有素材下载接口;如果素材实体缺失或文件在本地/MinIO 不存在,预览会提示下载失败。
|
||
|
||
下一步建议:
|
||
|
||
- 在后台 AI 接入页初始化 OpenAI 接入,选择目标 Provider 点“配置”,填入 API Key 后测试真实模型链路。
|
||
|
||
### 后台用户管理:人工加余额
|
||
|
||
完成时间:2026-06-01 14:10 CST
|
||
|
||
完成内容:
|
||
|
||
- 用户管理页新增“人工加余额”操作区,运营可选择用户、填写增加额度和备注后提交。
|
||
- 用户列表新增总额度、可用额度和快捷“加余额”操作,直接复用当前表单额度与备注。
|
||
- 后台页面调用现有 `POST /api/admin/users/:userId/quota/grant` 接口,额度变更会进入后端额度账户和额度流水。
|
||
- 切换到用户管理页时同步刷新用户列表与额度账户,避免运营看到旧余额。
|
||
- README 补充后台用户人工加余额入口说明。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w admin
|
||
- npm run build -w admin
|
||
|
||
测试结果:
|
||
|
||
- admin typecheck:通过
|
||
- admin build:通过
|
||
|
||
遗留问题:
|
||
|
||
- 当前只实现“增加额度/余额”,未做扣减、冻结调整、禁用额度账户等高风险操作。
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
|
||
下一步建议:
|
||
|
||
- 后台用户管理可继续补“额度流水明细/最近订单/最近项目”抽屉,方便运营核对加余额原因。
|
||
|
||
### 后台运营闭环:用户详情抽屉 / 内部额度模式 / 上线验收
|
||
|
||
完成时间:2026-06-01 22:36 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复后台用户管理页“人工加余额”区域在中等宽度下重叠的问题,改为稳定的多列栅格和移动端单列布局。
|
||
- 新增 `GET /api/admin/users/:userId/detail` 后台接口,返回用户基础信息、额度账户、额度流水、订单记录、最近项目、最近素材和最近操作。
|
||
- 后台用户管理列表新增“详情”按钮,打开用户详情抽屉;抽屉内可核对额度流水、项目、订单、素材和操作记录,素材可继续走预览入口。
|
||
- 用户端 H5 隐藏套餐、模拟支付和订单展示;当前内部测试模式只展示额度账户、项目预估和冻结额度,余额由后台人工增加。
|
||
- README 更新为“内部测试额度模式”,补充用户详情接口和后台运营说明。
|
||
- 后端 dist 服务已重启到新构建,当前监听 `0.0.0.0:3000`。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- user-app/src/pages/index/index.vue
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w admin
|
||
- npm run typecheck -w user-app
|
||
- npm test -w backend -- admin.service.spec.ts
|
||
- npm run typecheck
|
||
- npm test
|
||
- npm run lint
|
||
- DATABASE_URL=mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga npm run prisma:validate -w backend
|
||
- npm run build
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5175
|
||
- curl -I http://127.0.0.1:5174
|
||
- Node fetch 验收:管理员登录、用户列表、用户详情、注册测试用户、创建项目、额度预估、后台人工加额度、用户侧查余额
|
||
|
||
测试结果:
|
||
|
||
- backend/admin/user-app/workers 全量 typecheck:通过
|
||
- backend/admin/user-app/workers 全量 lint:通过
|
||
- backend 全量测试:通过,22 个测试文件 115 个测试通过
|
||
- admin 测试:无测试文件,按 `--passWithNoTests` 通过
|
||
- user-app 测试:无测试文件,按 `--passWithNoTests` 通过
|
||
- workers 测试:通过,1 个测试通过
|
||
- Prisma schema validate:通过(需要带 `DATABASE_URL`)
|
||
- 全 workspace build:通过
|
||
- 后端健康检查:通过,`status=ok`
|
||
- 后台 5175:返回 200
|
||
- 用户端 5174:返回 200
|
||
- 后台用户详情真实接口:通过,测试用户详情返回 `project_count=2`、`asset_count=59`、`quota_log_count=5`
|
||
- 内部额度真实接口:通过,新注册测试用户 `launch-check-1780324339354@example.com`,项目 `31`,后台加 10 额度后用户侧可用额度为 `10`
|
||
|
||
上线验收结论:
|
||
|
||
- 内部测试 / 自己人试用:可以继续使用。当前链路支持后台加额度、用户端按额度生成、后台查看用户详情和资源预览。
|
||
- 正式公网商业上线:暂不能宣布已达标。真实图片/TTS/视频 Provider 的生产调用、资产落库、失败重试、成本控制、内容安全平台、支付/开票或彻底移除支付域模型、用户禁用/改角色/重置密码/额度冲正等后台高风险操作还需要按生产标准补齐。
|
||
|
||
遗留问题:
|
||
|
||
- 当前用户端不展示支付入口;历史 mock 支付接口保留用于回归测试,后续如果对外收费,需要重新按真实支付网关设计。
|
||
- 图片/TTS/视频链路已有抽象和本地合成,但生产环境仍需切换真实 Provider 调用、成本记录、失败重试和资产一致性验收。
|
||
- 后台用户管理已具备详情和加余额,但扣减/冲正、禁用用户、改角色、重置密码、操作二次确认与审计策略尚未实现。
|
||
- API 加密开关仍按测试默认关闭;正式环境需要 HTTPS、`PROVIDER_SECRET_KEY`、`JWT_SECRET`、`API_CRYPTO_ENABLED` 和后台配置同步完成。
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
|
||
下一步建议:
|
||
|
||
- 进入正式上线补齐阶段:先做真实图片/TTS/视频 Provider 生产链路和资产落库验收,再补后台用户高危操作与额度冲正审计。
|
||
|
||
### 生产化补齐:真实图片 / TTS / 视频二进制资产落库
|
||
|
||
完成时间:2026-06-02 00:26 CST
|
||
|
||
完成内容:
|
||
|
||
- Provider 执行结果新增内部 `return_binary` 开关:业务生成链路可拿真实二进制,后台 Provider 测试默认不返回大体积 base64。
|
||
- OpenAI 图片 Provider 返回的 `b64_json` 会作为短暂 `content_base64` 交给图片生成服务;`provider_logs` 只记录 URL、字节数、hash、prompt 等摘要,不写入 base64。
|
||
- OpenAI TTS Provider 返回的音频 buffer 会作为短暂 `content_base64` 交给音频生成服务;`provider_logs` 只记录音频字节数、hash、mime、voice 等摘要。
|
||
- 图片生成链路改为优先保存 Provider 返回的真实图片字节,或下载 HTTP(S) `asset_url`;拿不到真实素材时才回退 SVG mock 占位图。
|
||
- 图片生成成功后回填 `render_tasks.output_asset_id`,后台可从任务追到真实图片资产。
|
||
- TTS 链路改为优先保存真实音频字节或下载音频 URL;拿不到真实素材时才回退静音 WAV。
|
||
- 视频渲染链路支持 Provider 返回 `content_base64` 时直接保存 Provider MP4;否则继续用 FFmpeg 读取分镜图、音频和字幕合成本地 MP4。
|
||
- README 更新图片、TTS、视频生产链路说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/provider.dto.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- backend/src/images/images.service.ts
|
||
- backend/src/images/images.service.spec.ts
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend -- images.service.spec.ts media.service.spec.ts providers.service.spec.ts
|
||
- npm test -w backend
|
||
- npm run build -w backend
|
||
- 重启 3000 后端 dist 进程
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- 定向测试:通过,3 个测试文件 27 个测试通过
|
||
- backend 全量测试:通过,22 个测试文件 120 个测试通过
|
||
- backend build:通过
|
||
- 后端 3000 已重启到新构建,健康检查返回 `status=ok`
|
||
|
||
上线验收结论:
|
||
|
||
- 图片/TTS 资产落库链路已具备真实 Provider 生产能力:后台配置真实 Provider 并调高优先级后,业务生成会保存真实图片/音频私有资产。
|
||
- 视频链路已支持 Provider 二进制 MP4 落库;当前默认仍可使用 FFmpeg 本地合成,VideoProvider 真实驱动仍需按所选视频模型另接。
|
||
|
||
遗留问题:
|
||
|
||
- 本机未配置真实 OpenAI Key,本轮未发起真实付费调用;已通过 mock fetch 单测验证 OpenAI 图片/TTS 二进制进入业务链路。
|
||
- 图片质量检查、失败自动重试、队列 worker 异步消费和真实视频 Provider 驱动仍需继续生产化。
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
|
||
下一步建议:
|
||
|
||
- 继续补后台用户高危操作与额度冲正审计,或先接入指定真实视频 Provider 驱动并做一次真实付费 E2E 验收。
|
||
|
||
### 生产化补齐:后台用户高危操作与额度冲正审计
|
||
|
||
完成时间:2026-06-02 00:45 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增后台用户状态管理接口:`PATCH /api/admin/users/:userId/status`,支持启用/停用用户,禁止管理员停用自己。
|
||
- 新增后台用户角色管理接口:`PATCH /api/admin/users/:userId/role`,支持普通用户 / 管理员角色切换,禁止管理员移除自己的 admin 角色。
|
||
- 新增后台重置密码接口:`POST /api/admin/users/:userId/reset-password`,可输入新密码或自动生成临时密码;操作日志不保存明文密码。
|
||
- 新增后台额度冲正接口:`POST /api/admin/users/:userId/quota/adjust`,支持正向补额度和反向扣减可用额度,扣减时校验可用余额。
|
||
- 后台人工加余额和额度冲正都会写入额度流水,并额外写入 `operation_logs` 审计记录。
|
||
- 用户详情抽屉新增“运营操作”区,运营可在同一处执行状态、角色、密码、额度冲正操作并查看最新流水和最近操作。
|
||
- 修复后台用户管理“人工加余额”区域在中等宽度下的重叠风险,改成 `auto-fit` 自适应栅格。
|
||
- README 更新后台用户运营能力和内部额度模式说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- backend/src/billing/billing.controller.ts
|
||
- backend/src/billing/billing.dto.ts
|
||
- backend/src/billing/billing.service.ts
|
||
- backend/src/billing/billing.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run build -w admin
|
||
- npm test -w backend -- admin.service.spec.ts billing.service.spec.ts
|
||
- npm run lint
|
||
- npm test
|
||
- DATABASE_URL=mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga npm run prisma:validate -w backend
|
||
- npm run build
|
||
- 重启 3000 后端 dist 进程
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5175
|
||
- curl -I http://127.0.0.1:5174
|
||
- Node fetch 烟测:管理员登录、新注册测试用户、人工加额度、额度冲正、用户禁用/恢复、角色变更/恢复、重置密码后登录、用户详情审计查询
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- admin build:通过
|
||
- 定向测试:通过,2 个测试文件 19 个测试通过
|
||
- 全 workspace lint/typecheck:通过
|
||
- backend 全量测试:通过,22 个测试文件 128 个测试通过
|
||
- admin 测试:无测试文件,按 `--passWithNoTests` 通过
|
||
- user-app 测试:无测试文件,按 `--passWithNoTests` 通过
|
||
- workers 测试:通过,1 个测试通过
|
||
- Prisma schema validate:通过
|
||
- 全 workspace build:通过
|
||
- 后端 3000 已重启到 PID `3698670`,健康检查返回 `status=ok`
|
||
- 后台 5175:返回 200
|
||
- 用户端 5174:返回 200
|
||
- 真实接口烟测通过:测试用户 `ops-smoke-1780331993114@example.com`,最终 `quota_available=15`、`status=active`、`role=user`,重置密码后登录成功;用户详情返回 `admin_correction_deduct` / `admin_grant` 额度流水和状态、角色、密码、冲正操作日志。
|
||
|
||
遗留问题:
|
||
|
||
- 高危操作暂未加二次确认弹窗和细粒度 RBAC;目前统一由 admin 角色执行并记录审计日志。
|
||
- 当前目录不是 Git 仓库,按用户要求暂不提交 Git。
|
||
|
||
下一步建议:
|
||
|
||
- 跑全量验收并重启服务;随后继续补生产级失败重试、成本阈值、队列 worker 消费和真实视频 Provider 驱动。
|
||
|
||
### 生产化补齐:失败重试 / 成本阈值 / 队列 worker 消费
|
||
|
||
完成时间:2026-06-02 01:00 CST
|
||
|
||
完成内容:
|
||
|
||
- Provider 运行配置新增成本保护字段:`max_cost_per_call` 和 `daily_cost_limit`,后台 AI 接入页可直接填写单次成本上限和当日成本上限。
|
||
- Provider 执行前会按 `cost_rule_json` 和环境变量 `PROVIDER_MAX_COST_PER_CALL` / `PROVIDER_DAILY_COST_LIMIT` 做成本预检,超过阈值会拦截调用并写入 failed provider log。
|
||
- Provider 执行后会再次检查实际估算成本和输出大小,防止输出超出 Provider 成本规则。
|
||
- 新增 worker 内部接口 `POST /api/internal/worker/tasks/:taskId/execute`,使用 `WORKER_SECRET` 鉴权。
|
||
- QueuesService 新增 `executeQueuedTask`,按任务类型映射到 Text/Novel/Image/Voice/Video/Moderation/QC/FileParse Provider。
|
||
- worker 包从占位状态升级为 BullMQ 消费器:订阅全部队列,收到 job 后调用后端内部执行接口。
|
||
- worker 执行失败时,后端会按任务 `max_retry` 自动重入队;达到上限后转为 `manual_required`,后台可继续人工介入。
|
||
- 后台用户详情中的状态、角色、重置密码、额度冲正操作增加二次确认弹窗。
|
||
- README 更新 worker、成本阈值和后台能力说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/provider.dto.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- backend/src/queues/queues.module.ts
|
||
- backend/src/queues/queues.service.ts
|
||
- backend/src/queues/queues.service.spec.ts
|
||
- backend/src/queues/worker-tasks.controller.ts
|
||
- workers/src/main.ts
|
||
- workers/src/main.spec.ts
|
||
- admin/src/App.vue
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w workers
|
||
- npm test -w backend -- providers.service.spec.ts queues.service.spec.ts
|
||
- npm test -w workers
|
||
- npm run build -w admin
|
||
- npm run lint
|
||
- npm test
|
||
- DATABASE_URL=mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga npm run prisma:validate -w backend
|
||
- npm run build
|
||
- 重启 3000 后端 dist 进程
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5175
|
||
- curl -I http://127.0.0.1:5174
|
||
- Node fetch 烟测:新建项目任务、调用内部 worker 执行接口、Provider 成本阈值拦截与恢复
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- workers typecheck:通过
|
||
- Provider / Queue 定向测试:通过,2 个测试文件 25 个测试通过
|
||
- workers 测试:通过,1 个测试通过
|
||
- admin build:通过
|
||
- 全 workspace lint/typecheck:通过
|
||
- backend 全量测试:通过,22 个测试文件 133 个测试通过
|
||
- admin 测试:无测试文件,按 `--passWithNoTests` 通过
|
||
- user-app 测试:无测试文件,按 `--passWithNoTests` 通过
|
||
- workers 测试:通过,1 个测试通过
|
||
- Prisma schema validate:通过
|
||
- 全 workspace build:通过
|
||
- 后端 3000 已重启到 PID `3741838`,健康检查返回 `status=ok`
|
||
- 后台 5175:返回 200
|
||
- 用户端 5174:返回 200
|
||
- 真实内部 worker 烟测通过:测试用户 `worker-smoke-1780332971727@example.com`,项目 `32`,任务 `135` 通过 `/api/internal/worker/tasks/135/execute` 执行后状态为 `success`,provider_log 为 `success`。
|
||
- 真实成本阈值烟测通过:临时把 `mock-text` 设置为 `flat_cost=2`、`max_cost_per_call=1`,执行被 503 拦截,错误为 `PROVIDER_COST_LIMIT_EXCEEDED`;随后已恢复 `mock-text` 成本规则为 `{ flat_cost: 0, unit: 'mock' }`。
|
||
|
||
遗留问题:
|
||
|
||
- worker 当前是通用 Provider 任务消费,图片/音频/视频资产生成业务接口仍保留同步链路;后续可把具体业务生成步骤逐步改成完全异步编排。
|
||
- 真实视频 Provider 驱动仍需按选定视频模型单独接入。
|
||
- 细粒度 RBAC 仍未做权限表和角色矩阵,目前高危后台接口仍统一要求 admin。
|
||
|
||
下一步建议:
|
||
|
||
- 跑全量验收并重启服务;随后接真实视频 Provider 驱动或补 RBAC/审计导出。
|
||
|
||
### 生产化补齐:真实视频 Provider 驱动 / 细粒度 RBAC / 审计导出
|
||
|
||
完成时间:2026-06-02 01:18 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 OpenAI Sora 视频 Provider 默认配置 `openai-video`,`/api/admin/providers/bootstrap-openai` 会写入 `VideoProvider` real provider。
|
||
- 重复初始化 OpenAI Provider 时会保留已加密保存的 API Key、Base URL、超时和成本阈值,避免误清空线上配置。
|
||
- Provider 执行层新增 `openai_video_generation` 驱动:按 OpenAI Videos API 异步流程创建视频任务、轮询状态,业务链路需要二进制时下载 MP4。
|
||
- `openai_video_generation` 的 `provider_logs` 只记录视频 ID、状态、字节数、hash、mime 等摘要,不把 `content_base64` 写入日志。
|
||
- 视频生产链路继续复用阶段 16 能力:Provider 返回 MP4 二进制时直接落私有视频资产,否则回退 FFmpeg 本地合成。
|
||
- 新增 RBAC helper,后台按 `admin/operator/finance/auditor` 和 `admin:read`、`users:write`、`billing:write`、`providers:write`、`audit:export` 等权限做后端强校验。
|
||
- 后台新增 `/api/admin/rbac/me`,前端按权限显示菜单和高危按钮;非 admin 角色不再只能靠页面隐藏。
|
||
- 新增审计日志列表和导出接口 `/api/admin/operation-logs`、`/api/admin/operation-logs/export`,导出操作本身也写入 `operation_logs`。
|
||
- 后台新增“审计日志”页面,支持按动作、对象类型、操作角色和时间筛选,并可导出 CSV。
|
||
- 后台用户角色可调整为 `user/admin/operator/finance/auditor`。
|
||
- README 和 `.env.example` 补充 `OPENAI_VIDEO_MODEL`、RBAC、Sora Video Provider 和审计导出说明。
|
||
|
||
修改文件:
|
||
|
||
- .env.example
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
- backend/src/auth/rbac.ts
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- backend/src/billing/billing.service.ts
|
||
- backend/src/providers/provider.types.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- backend/src/queues/queues.service.ts
|
||
- backend/src/reviews/reviews.service.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w admin
|
||
- npm run typecheck -w workers
|
||
- npm test -w backend
|
||
- npm run lint
|
||
- npm test
|
||
- DATABASE_URL=mysql://ai_manga:ai_manga_password@127.0.0.1:3306/ai_manga npm run prisma:validate -w backend
|
||
- npm run build
|
||
- npm test -w backend -- providers.service.spec.ts
|
||
- npm test -w backend -- admin.service.spec.ts
|
||
- npm run build -w backend
|
||
- 重启 3000 后端 dist 进程
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5175
|
||
- curl -I http://127.0.0.1:5174
|
||
- Node fetch 烟测:admin 登录、RBAC 权限查询、OpenAI Video Provider 存在性、审计导出、普通用户访问后台 RBAC 被拒绝
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- admin typecheck:通过
|
||
- workers typecheck:通过
|
||
- backend 全量测试:通过,22 个测试文件 136 个测试通过
|
||
- 全 workspace lint/typecheck:通过
|
||
- 全 workspace 测试:通过,backend 136 个测试、workers 1 个测试、admin/user-app 无测试文件按 `--passWithNoTests` 通过
|
||
- Prisma schema validate:通过
|
||
- 全 workspace build:通过
|
||
- 后端 3000 已重启到 PID `3816243`,健康检查返回 `status=ok`
|
||
- 后台 5175:返回 200
|
||
- 用户端 5174:返回 200
|
||
- 真实接口烟测通过:OpenAI Provider 列表包含 `openai-video`,驱动为 `openai_video_generation`;审计导出文件名为 `operation-logs-2026-06-02.csv`;普通用户访问 `/api/admin/rbac/me` 返回 403。
|
||
|
||
遗留问题:
|
||
|
||
- 本机未配置真实 `OPENAI_API_KEY`,本轮未发起真实 Sora 付费调用;已用 mock fetch 单测验证创建、轮询、下载 MP4 和日志脱敏。
|
||
- 当前 RBAC 为代码内角色矩阵,尚未做可配置权限表、权限配置 UI 和数据范围隔离。
|
||
|
||
下一步建议:
|
||
|
||
- 跑全 workspace 验收、重启后端和前端服务;随后在生产 Key 配好后做一次真实 Sora 视频小样 E2E 验收。
|
||
|
||
### 后台体验优化:OpenAI 统一接入
|
||
|
||
完成时间:2026-06-02 01:39 CST
|
||
|
||
完成内容:
|
||
|
||
- 后台 AI 接入默认改为“OpenAI 统一接入”,运营只需要填写一个 OpenAI API Key。
|
||
- 新增 `PATCH /api/admin/providers/openai/runtime-config`,批量把同一个 Key、Base URL、超时、成本阈值应用到全部 OpenAI Provider。
|
||
- 高级 Provider 配置不删除,默认折叠,只给技术人员单独调整模型、优先级、mock/real 切换和兼容服务。
|
||
- 统一配置支持“生产任务优先使用 OpenAI”,勾选后批量把 OpenAI Provider 优先级调到 220。
|
||
- 增加测试覆盖,确认统一 Key 批量保存时不会把明文写入配置。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/provider.dto.ts
|
||
- backend/src/providers/providers.controller.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w admin
|
||
- npm test -w backend -- providers.service.spec.ts
|
||
- npm run build -w admin
|
||
- npm run build -w backend
|
||
- 重启 3000 后端 dist 进程
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- Node fetch 烟测:admin 登录后调用 `/api/admin/providers/openai/runtime-config`
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- admin typecheck:通过
|
||
- Provider 定向测试:通过,18 个测试通过
|
||
- admin build:通过
|
||
- backend build:通过
|
||
- 后端 3000 已重启到 PID `3856864`,健康检查返回 `status=ok`
|
||
- 统一 OpenAI 配置烟测通过:批量更新 7 个 OpenAI Provider,Provider 列表仍包含 `openai-video`。
|
||
|
||
遗留问题:
|
||
|
||
- 本机仍未配置真实 OpenAI Key,未做真实付费调用。
|
||
|
||
下一步建议:
|
||
|
||
- 运营在后台“AI 接入”页只填统一 OpenAI Key;确认要真实生成时再勾选“生产任务优先使用 OpenAI”并做一次小样验收。
|
||
|
||
### OpenAI Key 防误耗额度保护
|
||
|
||
完成时间:2026-06-02 02:04 CST
|
||
|
||
完成内容:
|
||
|
||
- 后台“OpenAI 统一接入”的测试按钮改为“检查连接(不生成内容)”,只调用 `/api/admin/providers/openai/connection-check`。
|
||
- 新增 OpenAI 连接检查接口:仅请求 OpenAI `/models` 检查 Key/网络,不生成文本、图片、语音或视频,不写 `provider_logs`。
|
||
- 保存 OpenAI 统一配置时,未勾选“生产任务优先使用 OpenAI”会把全部 OpenAI Provider 优先级保持为 50,低于 mock,避免保存 Key 后自动切到真实模型。
|
||
- 高级 Provider 的真实测试增加前端二次确认;真实视频 Provider 测试按钮禁用。
|
||
- 后端 `/api/admin/providers/:providerId/test` 增加硬保护:真实 Provider 必须带 `confirm_paid_test=true`,真实视频 Provider 测试直接拒绝。
|
||
- 连接检查遇到 `PROVIDER_SECRET_DECRYPT_FAILED` 时返回中文提示,说明需要保持 `PROVIDER_SECRET_KEY/JWT_SECRET` 稳定或重新保存 Key,且不触发生成。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/provider.dto.ts
|
||
- backend/src/providers/providers.controller.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w admin
|
||
- npm test -w backend -- providers.service.spec.ts
|
||
- npm run build -w admin
|
||
- npm run build -w backend
|
||
- 重启 3000 后端 dist 进程
|
||
- Node fetch 安全烟测:admin 登录、OpenAI Provider 优先级检查、真实测试接口拦截、连接检查、provider_logs 总数对比
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- admin typecheck:通过
|
||
- Provider 定向测试:通过,22 个测试通过
|
||
- admin build:通过
|
||
- backend build:通过
|
||
- 后端 3000 已重启到 PID `3921216`,健康检查返回 `status=ok`
|
||
- 安全烟测通过:OpenAI Provider 共 7 个,优先级均为 50;已配置 Key 的 Provider 为 7 个;真实文本测试未带确认返回 `REAL_PROVIDER_TEST_CONFIRMATION_REQUIRED`;真实视频测试返回 `REAL_VIDEO_PROVIDER_TEST_DISABLED`;连接检查 `billed=false` 且 `provider_logs` 总数保持 147 不变。
|
||
|
||
遗留问题:
|
||
|
||
- 当前已保存的后台 Key 在本次重启环境下返回 `PROVIDER_SECRET_DECRYPT_FAILED`,说明保存 Key 时使用的 `PROVIDER_SECRET_KEY/JWT_SECRET` 与当前启动环境不一致;需要用同一服务密钥启动后端,或在当前稳定服务密钥下重新保存 OpenAI API Key。
|
||
- 本轮未调用任何文本/图片/TTS/视频生成接口,未做真实付费生成验收。
|
||
|
||
下一步建议:
|
||
|
||
- 固定生产 `PROVIDER_SECRET_KEY` 后重新保存一次 OpenAI API Key,再只点“检查连接(不生成内容)”确认 Key 可用;确认成本策略后再手动勾选“生产任务优先使用 OpenAI”做受控小样。
|
||
|
||
### 后端环境变量稳定加载
|
||
|
||
完成时间:2026-06-02 14:09 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增后端 `.env` 加载器,后端入口会在加载 `AppModule` 前读取根目录 `.env` 和 `backend/.env`。
|
||
- 加载优先级为:系统环境变量优先,其次 `.env` 文件;避免重启后 `DATABASE_URL`、`JWT_SECRET`、`PROVIDER_SECRET_KEY` 丢失。
|
||
- 创建本机 `.env`,写入本地数据库地址、端口、CORS、JWT 密钥和 `PROVIDER_SECRET_KEY`;未写入 OpenAI API Key。
|
||
- 用裸 `node backend/dist/main.js` 重启后端,验证不再需要手动在启动命令注入 `DATABASE_URL`。
|
||
- README 补充 `.env` 自动加载和 `PROVIDER_SECRET_KEY` 必须长期稳定的说明。
|
||
|
||
修改文件:
|
||
|
||
- .env
|
||
- backend/src/config/load-env.ts
|
||
- backend/src/main.ts
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- git status --short(当前目录不是 Git 仓库)
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- npm test -w backend -- providers.service.spec.ts
|
||
- 重启 3000 后端 dist 进程:`setsid -f node backend/dist/main.js ...`
|
||
- Node fetch 烟测:admin 登录、profile、Provider 列表、OpenAI 连接检查、provider_logs 总数对比
|
||
|
||
测试结果:
|
||
|
||
- backend typecheck:通过
|
||
- backend build:通过
|
||
- Provider 定向测试:通过,22 个测试通过
|
||
- 后端 3000 已重启到 PID `1309062`,健康检查返回 `status=ok`
|
||
- 裸启动烟测通过:`admin@example.com` 登录成功,`/api/auth/profile` 返回 admin,Provider 列表可读,OpenAI Provider 仍为 7 个且优先级均为 50。
|
||
- 连接检查未触发生成:返回 `billed=false`,`provider_logs` 总数保持 147 不变。
|
||
|
||
遗留问题:
|
||
|
||
- 旧的后台 OpenAI Key 仍返回 `PROVIDER_SECRET_DECRYPT_FAILED`,因为无法知道保存当时使用的服务加密密钥;现在已固定新的 `PROVIDER_SECRET_KEY`,需要在后台重新保存一次 OpenAI Key。
|
||
|
||
下一步建议:
|
||
|
||
- 在后台 AI 接入页重新保存 OpenAI API Key,然后只点击“检查连接(不生成内容)”;通过后再决定是否勾选“生产任务优先使用 OpenAI”。
|
||
|
||
### OpenAI Key 重新保存与连接确认
|
||
|
||
完成时间:2026-06-02 14:11 CST
|
||
|
||
完成内容:
|
||
|
||
- 用户已在后台重新保存 OpenAI API Key。
|
||
- 重新执行后台 OpenAI 连接检查,只调用 `/api/admin/providers/openai/connection-check`。
|
||
- 连接检查返回 `ok=true`,OpenAI `/models` 可访问,Key 能在当前稳定 `PROVIDER_SECRET_KEY` 下解密。
|
||
- OpenAI Provider 仍保持优先级 50,默认低于 mock,不会自动切到真实生成。
|
||
|
||
运行命令:
|
||
|
||
- Node fetch 安全烟测:admin 登录、Provider 列表、OpenAI 连接检查、provider_logs 总数对比
|
||
|
||
测试结果:
|
||
|
||
- OpenAI Provider:7 个
|
||
- 已配置 Key:7 个
|
||
- OpenAI Provider 优先级:50
|
||
- 连接检查:`ok=true`,`billed=false`,`endpoint=/models`,`model_count=118`
|
||
- `provider_logs` 总数前后保持 147 不变,确认未触发文本/图片/TTS/视频生成。
|
||
|
||
遗留问题:
|
||
|
||
- 当前仍未做真实生成小样;这是有意保留,避免未确认成本策略前消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 保持当前状态继续用 mock 做业务验收;如果要做真实 AI 小样,先设置单次/当日成本上限,再手动勾选“生产任务优先使用 OpenAI”,只跑一个受控小样。
|
||
|
||
### 小白使用手册补齐
|
||
|
||
完成时间:2026-06-02 14:24 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增根目录 `OPERATION_GUIDE.md`,不修改 `docs/` 需求文档目录。
|
||
- 手册按小白视角解释项目、故事圣经、角色圣经、锚点图、长篇记忆、分集计划、单集脚本、分镜、分镜图、TTS、字幕和视频。
|
||
- 补充用户端从注册/登录、新建项目、AI 原创/上传小说、版权确认、故事圣经、角色、分集、脚本、分镜、图片、音频、字幕、视频、下载的一整套操作流程。
|
||
- 补充后台运营流程:仪表盘、项目、小说、角色资源、分镜资源、成品漫剧、用户管理、额度、审核、任务、AI 接入、成本日志、系统配置和审计日志。
|
||
- 明确说明“场景”当前不是独立场景库,而是 AI 在分集/脚本/分镜中生成的场景名、地点、画面和动作字段,确认前可编辑。
|
||
- 增加“哪些内容 AI 生成,哪些需要人确认”的表格,以及常见问题排查表。
|
||
- README 增加 `OPERATION_GUIDE.md` 入口。
|
||
|
||
修改文件:
|
||
|
||
- OPERATION_GUIDE.md
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- ls -la
|
||
- rg 阅读当前 README、进度记录、用户端和后台页面入口
|
||
|
||
测试结果:
|
||
|
||
- 本阶段为纯文档补齐,未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
- 未运行代码测试;本次未修改业务代码。
|
||
|
||
遗留问题:
|
||
|
||
- 用户端页面本身仍缺少内嵌引导文案和步骤提示;当前先以独立手册形式补齐。
|
||
- 后续可把手册内容拆成后台“帮助/操作说明”页面和用户端流程提示。
|
||
|
||
下一步建议:
|
||
|
||
- 先按 `OPERATION_GUIDE.md` 用 mock 流程完整走一遍,熟悉每个确认点;确认操作理解后,再决定是否做真实 AI 小样。
|
||
|
||
### 产品内教程页补齐
|
||
|
||
完成时间:2026-06-02 14:42 CST
|
||
|
||
完成内容:
|
||
|
||
- 后台新增左侧“使用教程”页面,展示后台使用流程、故事圣经/角色圣经/场景/额度等概念说明、从小说到成品的操作顺序、后台常见排查和人工确认点。
|
||
- 用户端新增“教程”导航页,登录后可直接查看新手概念、一集从头到尾的步骤、角色/场景/额度等常见问题和新手建议。
|
||
- 用户端登录页增加“先看教程”折叠入口,未开始建项目前也能先理解基础流程。
|
||
- 用户端新增并注册 `src/pages/help/tutorial` 独立教程页面,给后续 uni-app 小程序/App 路由迁移预留。
|
||
- README 更新产品内教程入口说明。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/pages/help/tutorial.vue
|
||
- user-app/src/styles.css
|
||
- user-app/pages.json
|
||
- README.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- git status --short
|
||
- npm run typecheck -w admin
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w admin
|
||
- npm run build -w user-app
|
||
|
||
测试结果:
|
||
|
||
- 当前目录不是 git 仓库,`git status --short` 返回 `fatal: not a git repository`。
|
||
- 后台类型检查通过。
|
||
- 用户端类型检查通过。
|
||
- 后台生产构建通过。
|
||
- 用户端生产构建通过。
|
||
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
|
||
遗留问题:
|
||
|
||
- 当前教程为产品内摘要版,详细长文仍保留在根目录 `OPERATION_GUIDE.md`。
|
||
- 当前 Vite H5 入口仍以首页内导航为主;`pages.json` 的独立教程页为后续 uni-app 多端路由预留。
|
||
|
||
下一步建议:
|
||
|
||
- 让运营和测试先按用户端“教程”页走一遍 mock 流程;如果仍有不懂的字段,再把对应字段旁边补成就地提示。
|
||
|
||
### 上传小说解析 400 排查与前端保护
|
||
|
||
完成时间:2026-06-02 14:51 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户端请求 `POST /api/projects/33/novel/parse` 返回 `400 Bad Request`。
|
||
|
||
排查结论:
|
||
|
||
- 项目 `33` 是上传小说项目,当前 `copyright_status=pending`,项目状态 `source_selecting`。
|
||
- 项目 `33` 已有粘贴小说源 `source_id=16`,但 `copyright_records` 数量为 `0`。
|
||
- 后端解析接口要求上传小说必须先完成版权确认,因此返回 `Copyright must be confirmed before parsing novel`。
|
||
|
||
完成内容:
|
||
|
||
- 用户端上传小说区新增解析前置判断:未完成版权确认时禁用“解析小说”按钮。
|
||
- 用户端上传小说区新增提示文案:先保存/上传小说,再在下方完成版权确认,最后解析小说。
|
||
- 用户端版权确认按钮在已确认后显示“已确认”并禁用,避免重复点击。
|
||
- 用户端 API Client 增加常见英文错误的中文映射,后端返回英文 BadRequest 时前端显示中文可理解提示。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- rg 定位 `novel/parse` 前后端调用链
|
||
- mysql 查询项目 `33`、小说源、素材、版权记录和章节状态
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端生产构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 对项目 `33`:先在用户端点击“版权确认”的“确认”,再点击“解析小说”。
|
||
|
||
### 上传小说解析结果就地反馈
|
||
|
||
完成时间:2026-06-02 14:59 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户端点击“解析小说”后按钮只闪一下,页面附近没有明确显示是否成功,用户不知道下一步做什么。
|
||
|
||
排查结论:
|
||
|
||
- 项目 `33` 实际已解析成功,数据库中最新小说源 `parse_status=parsed`,章节已生成。
|
||
- 用户端只有顶部全局 `解析小说完成` 提示,上传小说卡片内没有解析结果、章节数、字数和下一步提示。
|
||
|
||
完成内容:
|
||
|
||
- 上传小说卡片内新增解析状态行:小说源 ID、解析状态、章节数、字数。
|
||
- 解析按钮新增动态文案:`解析中`、`解析小说`、`重新解析`。
|
||
- 解析成功后在上传小说卡片内固定显示:已拆出章节数、字数,以及下一步“故事圣经 -> 生成”。
|
||
- 点击解析后立即接收接口返回的 `source` 和 `chapters` 写入页面状态,再刷新工作台,避免用户只看到按钮闪烁。
|
||
- 粘贴小说且版权已确认时,自动解析返回结果也会同步到页面状态。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/pages/index/index.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- mysql 查询项目 `33`、小说源、章节状态
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端生产构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 用户解析成功后,直接看上传小说卡片里的绿色提示;下一步点击“故事圣经”的“生成”。
|
||
|
||
### 用户端全流程下一步指引
|
||
|
||
完成时间:2026-06-02 15:04 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户端点击“故事圣经 -> 生成”后虽然已生成,但页面没有明确告诉用户下一步应该“检查并确认故事圣经”,后续流程容易迷路。
|
||
|
||
完成内容:
|
||
|
||
- 用户端制作页新增顶部“当前下一步”提示卡,会根据项目当前数据自动显示下一步动作。
|
||
- 故事圣经卡片新增就地指引:未生成、生成中、待确认、已确认时分别提示下一步。
|
||
- 角色库卡片新增就地指引:提示抽取角色、生成锚点图、确认角色库和进入长篇记忆。
|
||
- 长篇记忆卡片新增就地指引:提示角色确认后生成记忆,完成后进入分集计划。
|
||
- 分集计划卡片新增就地指引:提示生成、检查摘要/钩子、确认分集,以及下一步生成脚本。
|
||
- 脚本和分镜卡片新增就地指引:提示生成脚本、确认脚本、生成分镜、确认分镜,以及下一步生成素材。
|
||
- 图片/音频/视频卡片新增就地指引:提示分镜图、音频字幕、合成视频的顺序。
|
||
- 内容审核卡片新增就地指引:提示合成视频后做文本/视频审核,审核通过后去成品页。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端生产构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 继续按用户端顶部“当前下一步”和各卡片绿色/灰色提示操作;如果某个字段仍看不懂,再补字段级说明。
|
||
|
||
### 用户端结果阅览与媒体任务反馈优化
|
||
|
||
完成时间:2026-06-02 15:19 CST
|
||
|
||
问题现象:
|
||
|
||
- 上传小说解析后刷新页面,输入框为空,用户感觉上传内容“全清空”,只有提示,看不到已保存/已解析的小说内容。
|
||
- “图片、音频和视频”区域点击分镜图、音频字幕、合成后,缺少成功/失败/进行中状态和错误提示。
|
||
- 媒体生成后没有明显的结果预览入口,用户不知道每一步到底生成了什么。
|
||
- 用户确认刚才生成链路是否使用了真实 OpenAI。
|
||
|
||
排查结论:
|
||
|
||
- 项目 `33` 已成功生成 10 张分镜图、1 个音频、1 个字幕和 1 个 MP4。
|
||
- Provider 日志显示项目 `33` 使用的是 `mock-image`、`mock-voice`、`mock-video`,成本均为 `0.0000`,没有真实 OpenAI 调用。
|
||
|
||
完成内容:
|
||
|
||
- 上传小说区刷新后会展示已保存小说信息:小说源、标题、作者、来源、解析状态和保存时间。
|
||
- 上传小说区新增章节预览列表,展示章节号、标题、字数、状态和正文片段。
|
||
- 上传小说文本框增加占位提示:已保存内容在下方预览,如需替换可重新粘贴。
|
||
- “图片、音频和视频”区域新增分步骤任务状态卡:分镜图、音频、字幕、视频。
|
||
- 每个媒体步骤展示成功/失败/进行中/未开始、成功数量、失败错误原因和下一步动作。
|
||
- 媒体素材列表新增预览/下载按钮。
|
||
- 新增通用素材预览区,支持图片、音频、视频内嵌预览;其他文件提示下载查看。
|
||
- 媒体流程下一步判断改为结合任务状态和素材结果,避免已生成后仍提示“下一步点分镜图”。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- mysql 查询项目 `33` 的项目状态、小说源、章节、任务、Provider 日志和素材。
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端生产构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 项目 `33` Provider 汇总:`mock-image` 10 次、`mock-voice` 1 次、`mock-video` 1 次,成本均为 `0.0000`。
|
||
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 用户端继续补字段级“这是什么”说明,尤其是故事圣经、角色字段、分镜字段和媒体任务字段。
|
||
|
||
### 下一步提示高亮与 mock 上线策略确认
|
||
|
||
完成时间:2026-06-02 15:27 CST
|
||
|
||
完成内容:
|
||
|
||
- 用户端“当前下一步”提示卡改成红色边框和红色标题,提升用户注意力。
|
||
- 核查当前 Provider 配置:mock Provider 9 个启用,优先级 100;real OpenAI Provider 7 个启用,优先级 50。
|
||
- 确认当前业务链路默认仍走 mock,不会因为已配置 OpenAI Key 就自动消耗真实额度。
|
||
- 确认后台已经有“生产任务优先使用 OpenAI”开关;勾选后会把 OpenAI Provider 优先级提高到 220。
|
||
|
||
上线策略建议:
|
||
|
||
- 不建议删除 mock Provider。mock 是内部测试、演示、回归测试、故障降级和成本保护的兜底能力。
|
||
- 不建议把 mock/real 勾选放到普通用户前端。普通用户看到这个会困惑,也可能误选真实生成导致成本不可控。
|
||
- 建议上线时由后台“AI 接入”统一控制:测试默认 mock;准备真实生产时由管理员在后台勾选“生产任务优先使用 OpenAI”,并设置单次/当日成本阈值。
|
||
- 对外用户端只展示业务流程和结果,不展示 Provider 模式。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- rg 查询用户端样式、后台 OpenAI 统一接入、Provider 逻辑。
|
||
- mysql 查询 Provider 配置模式、启用状态和优先级。
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端生产构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 真正上线前不要删除 mock;先在后台设置 OpenAI 成本阈值,再勾选“生产任务优先使用 OpenAI”,用 1 个测试项目跑小样验收。
|
||
|
||
### 角色锚点图 400 排查与流程顺序修正
|
||
|
||
完成时间:2026-06-02 15:34 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户端请求 `POST /api/characters/36/generate-images` 返回 `400 Bad Request`。
|
||
- 用户以为真实 OpenAI 图片生成失败。
|
||
|
||
排查结论:
|
||
|
||
- 角色 `36` 当前状态是 `generated`,还不是 `locked`。
|
||
- 项目 `35` 当前状态是 `waiting_character_confirm`,也就是角色库还未确认。
|
||
- 后端 `generateCharacterImages` 明确要求 `character.status === locked`,否则返回 `Locked character is required before image generation`。
|
||
- 这次 400 发生在调用 ImageProvider 之前,项目 `35` 没有新增 Provider 日志,因此没有触发 OpenAI,也没有产生图片成本。
|
||
- 当前 ImageProvider 配置为 `openai-image` real 优先级 `220`、`mock-image` 优先级 `100`;角色确认后再点锚点图会走真实 OpenAI 图片生成。
|
||
|
||
完成内容:
|
||
|
||
- 用户端 API Client 增加错误中文映射:`Locked character is required before image generation` -> `请先确认角色库,再生成角色锚点图。`
|
||
- 用户端角色流程提示修正为:先抽取角色 -> 检查角色 -> 确认角色库 -> 生成锚点图。
|
||
- 用户端“锚点图”按钮改为只有角色库确认后才可点击。
|
||
- 用户端点击锚点图时增加前置保护,未确认角色库会直接提示中文错误。
|
||
- 用户端角色状态增加 `locked` 中文展示为“已锁定”。
|
||
- 用户端下一步提示增加“真实 OpenAI 模式下锚点图会产生图片生成成本”的提醒。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- rg 定位 `generate-images` 前后端调用链。
|
||
- mysql 查询角色 `36`、项目 `35`、ImageProvider 优先级和项目 Provider 日志。
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端生产构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 本阶段未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 对项目 `35`:先点“确认角色库”,确认角色被锁定后,再点“锚点图”。因为当前 ImageProvider 已经是 OpenAI 优先,锚点图会走真实图片生成并产生成本。
|
||
|
||
### 角色锚点图耗时说明与悬浮下一步提示
|
||
|
||
完成时间:2026-06-02 15:42 CST
|
||
|
||
完成内容:
|
||
|
||
- 用户端角色锚点图生成中提示补充预计耗时:真实 OpenAI 通常每个角色约 20-90 秒;如果超时,当前后端约 60 秒后会回退 mock。
|
||
- 用户端角色锚点图生成成功后显示明确成功文案:`角色锚点图生成完成:已处理 N 个角色。`
|
||
- 用户端锚点图按钮会在未确认角色库、无待生成角色时给出中文提示,避免用户误点。
|
||
- 用户端“下一步”红色提示从页面内卡片改为固定悬浮提示,位于底部导航上方,可点击关闭;当下一步内容变化时会重新出现。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端生产构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 本阶段只改前端提示和文档,未调用 OpenAI、未运行真实生成、未消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 如果正式生产不允许 mock fallback,需要再把图片 Provider 策略改成“真实 Provider 失败即失败并提示”,而不是自动回退 mock。
|
||
|
||
### 生产链路禁用 mock 自动回退
|
||
|
||
完成时间:2026-06-02 15:52 CST
|
||
|
||
问题结论:
|
||
|
||
- 正式上线不能出现“OpenAI 超时失败,但系统自动回退 mock 并把任务标成成功”的行为。
|
||
- mock 只应保留给内部测试、演示和熟悉流程;生产优先 OpenAI 时,真实 Provider 失败必须让任务失败并提示原因。
|
||
|
||
完成内容:
|
||
|
||
- 图片生成调用 ImageProvider 时显式设置 `allow_fallback: false`,真实 OpenAI 超时不会再自动回退 `mock-image`。
|
||
- TTS、视频、内容审核和队列 worker 的 Provider 调用也统一改为 `allow_fallback: false`。
|
||
- 后台单个 Provider 测试接口改为只测试选中的 Provider,不允许真实 Provider 测试失败后 fallback mock。
|
||
- 图片 Provider 成功但没有返回 `content_base64` 或可下载图片 URL 时,不再生成 mock SVG,占位资产不会落库。
|
||
- TTS Provider 成功但没有返回音频内容时,不再生成静音 mock 音频。
|
||
- 视频 Provider 没有返回真实视频内容且 FFmpeg 不可用时,不再生成 mock MP4。
|
||
- 用户端新增中文错误提示:OpenAI 超时、图片/TTS/视频 Provider 没返回真实内容时会明确说明“真实素材未生成”。
|
||
- 已重新构建并重启后端,当前后端进程为 `1508518`,`/api/health` 正常。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/images/images.service.ts
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/queues/queues.service.ts
|
||
- backend/src/reviews/reviews.service.ts
|
||
- backend/src/images/images.service.spec.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- backend/src/queues/queues.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend
|
||
- npm run build -w backend
|
||
- npm run build -w user-app
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5174
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- 后端全量单测通过:22 个测试文件、144 个测试通过。
|
||
- 后端构建通过。
|
||
- 用户端构建通过。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 本阶段没有调用真实 OpenAI,没有消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 重新点一次角色锚点图时,如果 OpenAI 仍超时,前端会显示失败;需要从后台调高 OpenAI 图片 Provider 超时时间,或检查服务器到 OpenAI 的网络连通性。
|
||
|
||
### 角色锚点图预览与重生成流程
|
||
|
||
完成时间:2026-06-02 16:03 CST
|
||
|
||
问题结论:
|
||
|
||
- 角色锚点图生成后不能只显示任务成功,必须能预览当前锚点图、查看候选图、不满意时重生成或切换锚点。
|
||
- 后端已有角色图片列表、设为锚点和强制重生成能力,主要缺少用户端/后台运营入口。
|
||
|
||
完成内容:
|
||
|
||
- 用户端新增角色图片列表拉取:刷新项目时自动加载每个角色的锚点图和候选图。
|
||
- 用户端角色卡片展示当前锚点状态、候选图数量、候选图列表。
|
||
- 用户端支持点击“预览锚点”“预览候选图”“下载候选图”。
|
||
- 用户端支持从候选图中点击“设为锚点”。
|
||
- 用户端支持对单个角色点击“重生成”,会强制生成新锚点图并设为当前锚点。
|
||
- 用户端素材预览面板从媒体区内联面板改成全局浮层,角色区、媒体区、成品区预览都能立即弹出。
|
||
- 后台“角色资源”列表操作栏新增“锚点图”按钮,运营可直接预览角色锚点素材。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- admin/src/App.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- npm run typecheck -w admin
|
||
- npm run build -w admin
|
||
- curl -I http://127.0.0.1:5174
|
||
- curl -I http://127.0.0.1:5175
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端构建通过。
|
||
- 后台类型检查通过。
|
||
- 后台构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 后台返回 `200 OK`。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 本阶段没有调用真实 OpenAI,没有消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 如果要允许修改锁定角色的核心外貌字段,需要新增“角色回退编辑/重新确认”流程;当前后端只允许锁定后补充服装、道具、禁用规则等非核心字段,避免破坏后续角色一致性。
|
||
|
||
### OpenAI 图片超时配置调整
|
||
|
||
完成时间:2026-06-02 16:10 CST
|
||
|
||
问题现象:
|
||
|
||
- 角色锚点图真实 OpenAI 请求返回 `503 OPENAI_REQUEST_TIMEOUT`。
|
||
- 最新 ImageProvider 日志显示 `openai-image` 从 `2026-06-02 08:05:08.979` 等到 `08:06:08.981`,约 60 秒后超时。
|
||
|
||
排查结论:
|
||
|
||
- 当前数据库里所有 OpenAI Provider 的 `timeout_ms` 都被后台统一配置保存成了 `60000`。
|
||
- 生产链路已经禁用 mock fallback,所以真实 OpenAI 超时后会正确失败,不再生成 mock 占位图。
|
||
|
||
完成内容:
|
||
|
||
- 将当前数据库所有 `openai-*` Provider 的 `timeout_ms` 从 `60000` 更新为 `180000`。
|
||
- 后台“OpenAI 统一接入”默认超时时间改为 `180000`。
|
||
- 后台单个 Provider 高级配置的超时占位改为 `180000`。
|
||
- 后端 `openai-image` 默认初始化配置改为 `180000`。
|
||
- 重新构建并重启后端,当前后端进程为 `1538959`。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/provider.types.ts
|
||
- admin/src/App.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- mysql 查询/更新 provider_configs
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- npm run typecheck -w admin
|
||
- npm run build -w admin
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5175
|
||
|
||
测试结果:
|
||
|
||
- 数据库确认所有 `openai-*` Provider 超时为 `180000`。
|
||
- 后端类型检查通过。
|
||
- 后端构建通过。
|
||
- 后台类型检查通过。
|
||
- 后台构建通过。
|
||
- 后端 health 返回 `status=ok`。
|
||
- 后台返回 `200 OK`。
|
||
- 本阶段没有调用真实 OpenAI,没有消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 重新生成角色锚点图时会最多等待 180 秒;如果仍然超时,需要检查服务器到 OpenAI 的网络延迟/代理,或降低图片质量、尺寸后重试。
|
||
|
||
### 长任务可见进度提示
|
||
|
||
完成时间:2026-06-02 16:16 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户点击单个角色“重生成”后,只有按钮变灰,没有明显 loading、耗时和下一步反馈;非技术用户会误以为页面卡住。
|
||
|
||
完成内容:
|
||
|
||
- 用户端所有 `runAction` 动作新增计时器,展示已等待时间。
|
||
- 用户端顶部新增当前动作提示条,例如“正在生成角色锚点图 / 已等待 N 秒”。
|
||
- 用户端新增全局悬浮进度提示,展示当前动作、已等待时长和长任务说明。
|
||
- 角色卡片中新增单角色重生成提示,明确显示“正在重生成某角色的锚点图”。
|
||
- 角色锚点生成文案更新为:真实 OpenAI 通常 1-3 分钟,180 秒超时直接失败,不回退 mock。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl -I http://127.0.0.1:5174
|
||
- mysql 查询 ImageProvider 最近日志
|
||
|
||
测试结果:
|
||
|
||
- 用户端类型检查通过。
|
||
- 用户端构建通过。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 最近 ImageProvider 日志仍为旧 60 秒超时记录,180 秒配置后暂无新的图片生成日志。
|
||
- 本阶段没有调用真实 OpenAI,没有消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 更生产化的做法是把图片生成彻底改为后台队列任务:前端提交任务后轮询任务状态,用户可离开页面,完成后站内提示和自动刷新候选图。
|
||
|
||
### 视频合成 503 修复:默认走 FFmpeg 成片合成
|
||
|
||
完成时间:2026-06-02 16:46 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户端调用 `POST /api/episodes/25/video/render` 返回 `503 Service Unavailable`。
|
||
- 数据库任务和 Provider 日志显示 `VideoProvider openai-video` 失败,错误为 `Invalid value: '40'. Supported values are: '4', '8', '12', '16', and '20'.`
|
||
|
||
根因:
|
||
|
||
- `/video/render` 是“把分镜图、音频、字幕合成为最终 MP4”的接口,但当前真实 OpenAI 优先后误先调用了 `openai-video`。
|
||
- OpenAI Sora 视频生成的 `seconds` 不是任意成片时长,40 秒被 Provider 拒绝。
|
||
- 当前项目的分镜图和 TTS 真实生成日志是成功的,失败点只在最终视频合成误走视频生成 Provider。
|
||
|
||
完成内容:
|
||
|
||
- `MediaService.renderEpisodeVideo` 改为:默认 `prefer_ffmpeg !== false` 时直接走本地 FFmpeg 合成,不调用 `VideoProvider`。
|
||
- 只有显式传 `prefer_ffmpeg:false` 时才调用 `VideoProvider`,用于未来单独的 AI 视频生成/小样流程。
|
||
- 默认 FFmpeg 合成仍使用已有分镜图、音频和字幕,生产模式下 FFmpeg 不可用会失败,不生成 mock 成片。
|
||
- 新增单测锁定默认行为:本地 FFmpeg 合成不会调用 `VideoProvider`。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm test -w backend -- media.service.spec.ts
|
||
- npm test -w backend
|
||
- npm run build -w backend
|
||
- ffmpeg -version
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- `media.service` 单测通过:10 tests passed。
|
||
- 后端完整测试通过:22 files / 145 tests passed。
|
||
- 后端构建通过。
|
||
- 本机 FFmpeg 可用:5.1.9。
|
||
- 后端已重启,新进程 PID `1605147`,health 返回 `status=ok`。
|
||
- 本阶段没有调用真实 OpenAI,没有消耗额度。
|
||
|
||
下一步建议:
|
||
|
||
- 用户端重新点击“合成”后应走 FFmpeg 成片合成;如果素材齐全,应生成 MP4。
|
||
- 真正的 OpenAI/Sora 视频生成应单独做“AI 视频小样”入口,并限制 `seconds` 为 Provider 支持值,不再复用最终成片合成接口。
|
||
|
||
### 视频体验核查:声音 / 中文字幕 / Sora 成本说明
|
||
|
||
完成时间:2026-06-02 17:03 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户合成后发现最终成片仍是图片加解说,不是人物真实动态视频。
|
||
- 用户反馈字幕没有正常显示,画面上出现两排小方框。
|
||
- 用户反馈播放时没有声音,并观察到 OpenAI 消费约 0.8 美金。
|
||
|
||
核查结论:
|
||
|
||
- 第 25 集最新视频任务 `184` 为 FFmpeg 本地合成成功,输出视频资产 `180`,没有调用 Sora。
|
||
- 当前产物确实是“分镜图 + TTS + 字幕”的剪辑成片,不是 Sora 这类 AI 动态视频。
|
||
- 视频文件内存在 AAC 音轨,时长 40 秒;`ffmpeg volumedetect` 检测到正常音量,文件层面不是无音轨/静音。
|
||
- 字幕小方框根因是服务器缺少中文字体,且代码强制 `FontName=Arial`,Arial 不覆盖中文。
|
||
- 第 25 集本地 provider_logs 里项目成功日志包含 13 次 `openai-image` 和 1 次 `openai-tts`,系统内部成本字段仍为 0;用户在 OpenAI Dashboard 看到的约 0.8 美金应来自真实图片生成和 TTS,而不是 FFmpeg 合成或 Sora。
|
||
|
||
完成内容:
|
||
|
||
- 服务器安装 `google-noto-sans-cjk-ttc-fonts`,并刷新字体缓存。
|
||
- FFmpeg 字幕样式改为 `Noto Sans CJK SC`,字号从 24 提升到 52,底部边距和描边同步优化。
|
||
- FFmpeg 音频合成增加 `loudnorm` 标准响度处理,并把 AAC 码率提升到 128k。
|
||
- 用户端点击“合成”改为传 `force:true`,便于重新生成已存在的 FFmpeg 成片;该动作复用已存在图片/音频/字幕,不额外调用 OpenAI。
|
||
- 用现有 SRT 做 1 秒 FFmpeg dry-run,确认新字体字幕过滤器可运行。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- user-app/src/api/client.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- dnf install -y google-noto-sans-cjk-ttc-fonts
|
||
- fc-cache -fv
|
||
- fc-list :lang=zh
|
||
- ffprobe 检查第 25 集视频和音频文件
|
||
- ffmpeg volumedetect 检测最终 MP4 音轨
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5174
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- 后端构建通过。
|
||
- 用户端类型检查通过。
|
||
- 用户端构建通过。
|
||
- 后端已重启,新进程 PID `1643780`,health 返回 `status=ok`。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
|
||
|
||
下一步建议:
|
||
|
||
- 让用户重新点击“合成”,拿到新字体字幕版本。
|
||
- 若要人物真实运动,需要新增“AI 动态视频 / Sora 分镜视频”独立流程:按 4-20 秒短镜头生成动态视频,再做最终剪辑合成。
|
||
- 上线前需要在后台清楚区分“低成本剪辑成片”和“高成本动态视频”,并在每一步显示预计费用。
|
||
|
||
### 视频字幕字号回调
|
||
|
||
完成时间:2026-06-02 17:11 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户反馈新字体字幕过大,已经超出视频画面。
|
||
|
||
完成内容:
|
||
|
||
- FFmpeg 字幕 `FontSize` 从 52 回调到 36。
|
||
- 字幕描边从 3 回调到 2。
|
||
- 字幕增加 `MarginL=90`、`MarginR=90`、`MarginV=130`,减少横向溢出和底部贴边。
|
||
- 重新执行 FFmpeg 字幕 dry-run,确认过滤器可正常运行。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- ffmpeg 字幕 dry-run
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- 后端构建通过。
|
||
- FFmpeg 字幕 dry-run 通过。
|
||
- 后端已重启,新进程 PID `1654039`,health 返回 `status=ok`。
|
||
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
|
||
|
||
### 视频字幕手机屏幕尺寸二次回调
|
||
|
||
完成时间:2026-06-02 17:17 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户反馈字幕仍然偏大,需要按手机竖屏观看尺寸处理。
|
||
|
||
完成内容:
|
||
|
||
- FFmpeg 字幕 `FontSize` 从 36 继续下调到 24。
|
||
- 去掉字幕阴影,保留 2px 描边,减少大字压迫感。
|
||
- 字幕边距调整为 `MarginL=80`、`MarginR=80`、`MarginV=120`,适配 1080x1920 手机竖屏底部字幕。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- ffmpeg 字幕 dry-run
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- 后端构建通过。
|
||
- FFmpeg 字幕 dry-run 通过。
|
||
- 后端已重启,新进程 PID `1666467`,health 返回 `status=ok`。
|
||
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
|
||
|
||
### 视频字幕手机屏幕尺寸三次回调
|
||
|
||
完成时间:2026-06-02 17:20 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户反馈字幕仍需再小一点,并希望左右两边留出更多空隙。
|
||
|
||
完成内容:
|
||
|
||
- FFmpeg 字幕 `FontSize` 从 24 继续下调到 20。
|
||
- 字幕左右边距从 80 提升到 150,增加手机竖屏两侧留白。
|
||
- 保留中文字体 `Noto Sans CJK SC`、2px 描边和底部 `MarginV=120`。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- ffmpeg 字幕 dry-run
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- 后端构建通过。
|
||
- FFmpeg 字幕 dry-run 通过。
|
||
- 后端已重启,新进程 PID `1672854`,health 返回 `status=ok`。
|
||
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
|
||
|
||
### 视频字幕字号 12 与分镜文字伪影修复
|
||
|
||
完成时间:2026-06-02 17:27 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户反馈字幕仍很大并超出边框,希望字号改成 12。
|
||
- 本地预览发现画面中的大方框并非 FFmpeg 字幕,而是原始分镜图本身生成了漫画气泡/乱码文字。
|
||
|
||
完成内容:
|
||
|
||
- 视频合成时不再直接把 SRT 交给 FFmpeg `subtitles` 样式缩放。
|
||
- 新增 SRT -> ASS 转换,写入 `PlayResX=1080`、`PlayResY=1920`,保证字幕字号按手机竖屏固定生效。
|
||
- ASS 字幕样式固定为 `Noto Sans CJK SC`、`Fontsize=12`、左右边距 180、底部边距 120。
|
||
- 未来角色图和分镜图 prompt 增加强约束:禁止画面内可见文字、字幕、漫画气泡、对话框、乱码方块;台词只通过表情和动作表达。
|
||
- 明确:旧分镜图中的方框已经在图片像素里,重新合成不能移除;需要重新生成分镜图才会消失。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/images/images.service.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- npm test -w backend -- media.service.spec.ts images.service.spec.ts
|
||
- ffmpeg 生成 ASS 字幕预览帧
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- 后端构建通过。
|
||
- 图片/媒体相关单测通过:2 files / 17 tests passed。
|
||
- ASS 字幕字号 12 预览帧生成成功。
|
||
- 后端已重启,新进程 PID `1687323`,health 返回 `status=ok`。
|
||
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
|
||
|
||
下一步建议:
|
||
|
||
- 重新点“合成”可获得真正字号 12 的底部字幕。
|
||
- 若要去掉画面里的大方框,需要在新 prompt 规则生效后重新生成分镜图;这会产生新的图片生成成本,应由用户确认后再执行。
|
||
|
||
### 视频无声兼容性修复
|
||
|
||
完成时间:2026-06-02 17:34 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户反馈最新成片前端预览没有声音。
|
||
- 检测旧成片资产 `185`:文件内存在 AAC 音轨,平均音量正常,但音频参数为 `96000 Hz / mono`,存在 H5/手机播放器兼容风险。
|
||
|
||
完成内容:
|
||
|
||
- FFmpeg 成片合成音频输出固定为更通用的 `AAC 48kHz stereo`。
|
||
- 保留 `loudnorm` 音量标准化,避免 TTS 音量过低。
|
||
- 已用现有图片、音频、字幕重新合成第 25 集成片,未调用 OpenAI。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- POST /api/episodes/25/video/render
|
||
- ffprobe 音视频流检测
|
||
- ffmpeg volumedetect 音量检测
|
||
- curl http://127.0.0.1:3000/api/health
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- 后端构建通过。
|
||
- 后端已重启,新进程 PID `1699032`,health 返回 `status=ok`。
|
||
- 新成片资产 `186` 生成成功,`ffmpeg_used=true`。
|
||
- 新成片音轨检测通过:`aac`、`48000 Hz`、`stereo`、时长 40 秒。
|
||
- 新成片音量检测通过:平均音量约 `-20.1 dB`,不是静音。
|
||
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
|
||
|
||
下一步建议:
|
||
|
||
- 前端点“同步/预览”刷新到最新成片资产 `186` 后再试听。
|
||
- 若旧预览 Blob 仍停留在浏览器缓存里,关闭预览后重新点最新 MP4 的“预览”。
|
||
|
||
### 视频无声二次兼容与自动预览
|
||
|
||
完成时间:2026-06-02 17:41 CST
|
||
|
||
问题现象:
|
||
|
||
- 用户反馈资产 `186` 在电脑播放仍然没有声音。
|
||
- 复核 `186` 的磁盘文件和接口下载文件:均存在 AAC 音轨,音量非静音,但用户实际播放仍无声。
|
||
|
||
完成内容:
|
||
|
||
- FFmpeg 成片音频进一步改为更保守的 `AAC 44.1kHz stereo`。
|
||
- 音轨显式标记为默认音轨,并写入中文语言标记 `chi`。
|
||
- 音频响度从 `I=-16` 调整为 `I=-15` 并叠加 `volume=3dB`,提升电脑播放可感知音量。
|
||
- 用户端“合成视频”完成后会清空旧预览,并自动预览本次接口返回的新视频资产,避免继续播放旧 Blob。
|
||
- 用现有素材重新合成第 25 集,生成新成片资产 `187`,未调用 OpenAI。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- npm run typecheck -w backend
|
||
- npm run build -w backend
|
||
- npm run typecheck -w user-app
|
||
- npm run build -w user-app
|
||
- POST /api/episodes/25/video/render
|
||
- GET /api/assets/187/download
|
||
- ffprobe 音视频流检测
|
||
- ffmpeg volumedetect 音量检测
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- curl -I http://127.0.0.1:5174
|
||
|
||
测试结果:
|
||
|
||
- 后端类型检查通过。
|
||
- 后端构建通过。
|
||
- 用户端类型检查通过。
|
||
- 用户端构建通过。
|
||
- 后端已重启,新进程 PID `1714706`,health 返回 `status=ok`。
|
||
- 用户端 H5 返回 `200 OK`。
|
||
- 新成片资产 `187` 生成成功,`ffmpeg_used=true`。
|
||
- `187` 接口下载文件检测通过:`aac`、`44100 Hz`、`stereo`、默认音轨、时长 40 秒。
|
||
- `187` 音量检测通过:平均音量约 `-16.2 dB`,最大音量约 `-0.8 dB`,不是静音。
|
||
- 本阶段未调用任何真实 OpenAI 生成接口,没有新增 AI 消耗。
|
||
|
||
下一步建议:
|
||
|
||
- 前端重新点最新成片 `187` 的“预览”或“下载”试听;合成按钮后续会自动打开新成片。
|
||
- 如果电脑本地播放器仍无声,请优先用浏览器或 VLC 打开 `video-187.mp4` 交叉验证,因为文件层面已确认音轨存在且可解码。
|
||
|
||
### AI 真人短剧 mock 模式
|
||
|
||
完成时间:2026-06-02 18:26 CST
|
||
|
||
背景:
|
||
|
||
- 用户明确当前图片漫剧链路不是抖音真人短剧效果,需要新增 `live_action_ai` 输出模式。
|
||
- 本阶段只实现 mock 数据流,不接真实 Runway/Kling/Sora/OpenAI 视频模型,不产生真实 AI 成本。
|
||
|
||
完成内容:
|
||
|
||
- `projects` 新增 `output_mode`、`visual_mode`、`video_generation_level`。
|
||
- `storyboard_shots` 新增真人短剧字段:`live_action_desc`、`actor_action`、`camera_instruction`、`performance_instruction`、`video_prompt`、`keyframe_asset_id`、`video_clip_asset_id`、`video_status`。
|
||
- 新增 `actor_profiles` 表,保存真人演员定妆设定。
|
||
- 新增 `video_clips` 表,记录每个分镜的视频片段、Provider、输入关键帧、输出素材、状态和成本。
|
||
- 后端新增 LiveAction 模块:
|
||
- `GET/POST /projects/:projectId/live-action/actor-profiles`
|
||
- `GET/POST /episodes/:episodeId/live-action/shots`
|
||
- `POST /episodes/:episodeId/live-action/keyframes/generate`
|
||
- `GET/POST /episodes/:episodeId/live-action/video-clips`
|
||
- `POST /episodes/:episodeId/live-action/render`
|
||
- 关键帧生成显式使用 `mock-image` Provider。
|
||
- 视频片段生成显式使用 `mock-video` Provider,并生成可预览的 1080x1920 H.264 MP4 mock 片段。
|
||
- 真人短剧合成使用 FFmpeg concat,把视频片段合成为最终 mock MP4。
|
||
- 用户端新建项目增加生成类型选择:图片漫剧版、动态漫画版、AI 真人短剧版。
|
||
- 用户端真人短剧项目新增“AI 真人短剧”面板:演员定妆、真人分镜、关键帧、视频片段、合成。
|
||
- 后台项目详情展示生成类型、演员定妆数量、视频片段数量,并列出 actor profiles / video clips。
|
||
- 操作文档新增“生成类型要先选清楚”和真人短剧 mock 流程说明。
|
||
|
||
新增文件:
|
||
|
||
- backend/prisma/migrations/20260602095000_live_action_ai_mode/migration.sql
|
||
- backend/src/live-action/live-action.controller.ts
|
||
- backend/src/live-action/live-action.dto.ts
|
||
- backend/src/live-action/live-action.module.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/live-action/live-action.types.ts
|
||
|
||
修改文件:
|
||
|
||
- backend/prisma/schema.prisma
|
||
- backend/src/app.module.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/projects/project.dto.ts
|
||
- backend/src/projects/project.types.ts
|
||
- backend/src/projects/projects.service.ts
|
||
- backend/src/*/*.spec.ts 相关 Project/StoryboardShot 测试工厂
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/workflow.ts
|
||
- admin/src/App.vue
|
||
- OPERATION_GUIDE.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- DATABASE_URL=... npm run db:validate
|
||
- npm run db:generate
|
||
- DATABASE_URL=... npm run db:deploy
|
||
- npm run typecheck -w backend
|
||
- npm run typecheck -w user-app
|
||
- npm run typecheck -w admin
|
||
- npm run build -w backend
|
||
- npm run build -w user-app
|
||
- npm run build -w admin
|
||
- curl http://127.0.0.1:3000/api/health
|
||
- live_action_ai 最小项目 API 烟测
|
||
- ffprobe mock video clip / final live-action mock MP4
|
||
|
||
测试结果:
|
||
|
||
- Prisma schema validate 通过。
|
||
- Prisma migration deploy 通过,已应用 `20260602095000_live_action_ai_mode`。
|
||
- 后端类型检查通过。
|
||
- 用户端类型检查通过。
|
||
- 后台类型检查通过。
|
||
- 后端构建通过。
|
||
- 用户端构建通过。
|
||
- 后台构建通过。
|
||
- 后端已重启,新进程 PID `1797918`,health 返回 `status=ok`。
|
||
- API 烟测创建 `live_action_ai` 项目 `36`,插入最小角色/分集/分镜数据后跑通:
|
||
- actor profile 1 条
|
||
- live action shot 1 条
|
||
- keyframe asset `188`
|
||
- video clip asset `189`
|
||
- final mock video asset `190`
|
||
- `ffprobe` 确认 `189` / `190` 均为 1080x1920、4 秒 H.264 MP4。
|
||
- Provider 日志确认仅调用 `ImageProvider/mock-image` 与 `VideoProvider/mock-video`,`cost_actual=0`。
|
||
- 本阶段未调用任何真实 OpenAI/视频生成接口,没有新增 AI 消耗。
|
||
|
||
遗留问题:
|
||
|
||
- `live_action_ai` 当前仍是 mock 视频片段,不是真人会动的真实 AI 视频。
|
||
- 动态漫画版 `motion_comic` 仅预留入口,尚未实现局部动效链路。
|
||
- 真人短剧最终音频/口型/BGM/字幕还未并入 live-action render,本阶段只拼接视频片段。
|
||
- 真实视频 Provider 已完成可替换驱动和受控入口;真实生成仍需配置并显式确认后才会调用。
|
||
|
||
下一步建议:
|
||
|
||
- 先用用户端新建 `AI 真人短剧版` 项目熟悉 mock 流程。
|
||
- mock 流程确认后,可在后台启用 Runway/Kling 等真实视频 Provider 做受控小样。
|
||
|
||
### 真实可替换 VideoProvider / 成本预估 / 重试 / 片段质检
|
||
|
||
完成时间:2026-06-02
|
||
|
||
完成内容:
|
||
|
||
- 新增可替换 `VideoProvider` 预设:`runway-image-to-video`、`kling-image-to-video`。
|
||
- 两个真实视频 Provider 默认 `is_enabled=false`,不会因为配置 Key 或初始化而自动扣费。
|
||
- 后台新增“初始化视频接入”按钮,可写入 Runway/Kling 配置;真实视频 Provider 后台测试仍禁用。
|
||
- Provider 服务新增 `runway_image_to_video` / `kling_image_to_video` 驱动:
|
||
- 创建 image-to-video 任务。
|
||
- 轮询任务状态。
|
||
- 提取视频下载 URL。
|
||
- 下载 MP4/WebM/MOV 二进制并交给业务层落库。
|
||
- Provider 日志会打码 data URI/base64 大字段,避免图片原文写入日志。
|
||
- `VideoProvider` 成本规则支持 `unit=video_seconds`,可按 `price_per_second`、`price_per_clip` 做估算和成本阈值拦截。
|
||
- 真人短剧用户端新增:
|
||
- 视频 Provider 选择。
|
||
- 成本估算。
|
||
- 单片段成本上限。
|
||
- 真实视频生成确认勾选。
|
||
- 强制重生成。
|
||
- 片段重试。
|
||
- 片段质检。
|
||
- 真人短剧后端新增接口:
|
||
- `GET /api/live-action/video-providers`
|
||
- `GET /api/episodes/:episodeId/live-action/video-clips/cost-estimate`
|
||
- `POST /api/live-action/video-clips/:clipId/retry`
|
||
- `POST /api/live-action/video-clips/:clipId/quality-check`
|
||
- `video_clips` 新增质检字段:`quality_status`、`quality_score`、`quality_issues`。
|
||
- 真实视频 Provider 未带 `confirm_real_video=true` 时直接返回 `REAL_VIDEO_GENERATION_CONFIRMATION_REQUIRED`,不会发起外部 API 调用。
|
||
- 后台项目详情展示视频片段成本和质检结果。
|
||
|
||
修改文件:
|
||
|
||
- backend/prisma/schema.prisma
|
||
- backend/src/providers/provider.types.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.controller.ts
|
||
- backend/src/live-action/live-action.dto.ts
|
||
- backend/src/live-action/live-action.controller.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/live-action/live-action.types.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- admin/src/App.vue
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/prisma/migrations/20260602112000_real_video_provider_qc/migration.sql
|
||
|
||
运行命令:
|
||
|
||
- `set -a; source .env; set +a; npm run db:validate`
|
||
- `set -a; source .env; set +a; npm run db:deploy`
|
||
- `set -a; source .env; set +a; npm run db:generate`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w user-app`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run build -w backend`
|
||
- `npm run build -w user-app`
|
||
- `npm run build -w admin`
|
||
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
|
||
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
|
||
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
|
||
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- live-action mock-only API 烟测
|
||
- `ffprobe` 检查 mock MP4
|
||
|
||
测试结果:
|
||
|
||
- Prisma schema validate 通过。
|
||
- Prisma migration deploy 通过,已应用 `20260602112000_real_video_provider_qc`。
|
||
- 后端、用户端、后台 typecheck 全部通过。
|
||
- 后端、用户端、后台 build 全部通过。
|
||
- 后端已重启,新进程 PID `1949213`,health 返回 `status=ok`。
|
||
- 安全烟测结果:
|
||
- `GET /live-action/video-providers` 返回启用的 `mock-video`。
|
||
- `GET /episodes/28/live-action/video-clips/cost-estimate?provider_code=mock-video` 返回 `estimated_cost=0`。
|
||
- 未确认真实 Runway 生成返回 `400 REAL_VIDEO_GENERATION_CONFIRMATION_REQUIRED`。
|
||
- mock 片段生成成功,新增 video_clip `2`、asset `191`,`cost_actual=0`。
|
||
- mock 质检成功,`quality_status=passed`,`quality_score=94`。
|
||
- Provider 日志仅新增 `VideoProvider/mock-video` 与 `QualityCheckProvider/mock-qc`,未调用 Runway/Kling/OpenAI 真实视频接口。
|
||
- `ffprobe` 确认 asset `191` 为 H.264、1080x1920、4 秒 MP4。
|
||
|
||
遗留问题:
|
||
|
||
- Runway/Kling 真实付费小样尚未开启验证;需要你确认 Provider、填写 Key、设置价格和成本阈值后再跑。
|
||
- 真实视频要求关键帧为 PNG/JPG/WebP;当前真人关键帧 mock 是 SVG,真实视频小样前需要用真实图片 Provider 产出栅格关键帧或提供外部参考图。
|
||
- 真人短剧最终合成仍是拼接视频片段,音频、口型、字幕、BGM 和音效还未并入 live-action 成片。
|
||
|
||
下一步建议:
|
||
|
||
- 后台 AI 接入页初始化视频接入后,只启用一个视频 Provider,先填 `price_per_second` 和每日成本上限。
|
||
- 用 1 个镜头做真实 image-to-video 小样;确认质量、耗时和账单后再扩大到整集。
|
||
|
||
### 国内可替换 VideoProvider:Hailuo / Wan / Vidu / Seedance
|
||
|
||
完成时间:2026-06-02
|
||
|
||
完成内容:
|
||
|
||
- 新增通用 `configurable_image_to_video` 驱动,支持可配置异步图生视频流程:
|
||
- 创建视频任务。
|
||
- 轮询任务状态。
|
||
- 从任务结果提取视频 URL。
|
||
- 供应商只返回 `file_id` 时,可通过 `output_url_endpoint_template` 再取下载链接。
|
||
- 下载真实视频二进制后交给业务层落私有资产。
|
||
- 新增国内/短剧向视频 Provider 预设,全部默认禁用:
|
||
- `minimax_hailuo_23_fast`
|
||
- `minimax_hailuo_23`
|
||
- `alibaba_wan26_i2v_flash`
|
||
- `alibaba_wan26_i2v`
|
||
- `vidu_q3_turbo_reference`
|
||
- `vidu_q3_pro`
|
||
- `jimeng_seedance`
|
||
- `bootstrap-video` 现在会写入 9 个视频 Provider:上述 7 个国内/短剧向 Provider,加 Runway、Kling。
|
||
- 重复初始化视频 Provider 时会继续保留已配置的 API Key、Base URL、超时、endpoint、body_style、headers、成本阈值等运行字段,避免覆盖运营配置。
|
||
- 后台 AI 接入页补充“可配置图生视频”中文驱动名和 Hailuo/Wan/Vidu/Seedance 说明。
|
||
- 用户端真人短剧生成保护增强:
|
||
- 指定真实 Provider 但 Provider 未启用时返回 `LIVE_ACTION_VIDEO_PROVIDER_DISABLED`。
|
||
- 指定真实 Provider 且未确认时返回 `REAL_VIDEO_GENERATION_CONFIRMATION_REQUIRED`。
|
||
- 不再因为已有旧 mock 片段就绕过真实 Provider 守卫。
|
||
- 小白手册补充真实视频小样建议:先测 MiniMax Hailuo 2.3 Fast,再对比 Wan、Vidu、Seedance、Kling/Runway。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/provider.types.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- admin/src/App.vue
|
||
- README.md
|
||
- OPERATION_GUIDE.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/prisma/migrations/20260602130000_domestic_video_providers/migration.sql
|
||
|
||
运行命令:
|
||
|
||
- `set -a; source .env; set +a; npm run db:validate`
|
||
- `set -a; source .env; set +a; npm run db:deploy`
|
||
- `set -a; source .env; set +a; npm run db:generate`
|
||
- `npm run typecheck`
|
||
- `npm test`
|
||
- `npm run build`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- admin 登录后接口烟测:`bootstrap-video`、Provider 列表、用户端 Provider 列表、成本估算、禁用真实 Provider 保护、Provider 日志查询
|
||
|
||
测试结果:
|
||
|
||
- Prisma schema validate 通过。
|
||
- Prisma migration deploy 通过,已应用 `20260602130000_domestic_video_providers`。
|
||
- Prisma Client generate 通过。
|
||
- 全量 typecheck 通过:backend、admin、user-app、workers。
|
||
- 全量 test 通过:backend 22 个测试文件 145 个测试通过;workers 1 个测试通过;admin/user-app 暂无测试文件并以 passWithNoTests 通过。
|
||
- 全量 build 通过:backend、admin、user-app、workers。
|
||
- 后端已重启,新进程 PID `1989678`,health 返回 `status=ok`。
|
||
- `bootstrap-video` 返回 9 个视频 Provider。
|
||
- 后台 VideoProvider 总数为 11,国内 7 个 Provider 均存在,`is_enabled=false`,driver 均为 `configurable_image_to_video`。
|
||
- 用户端 `/live-action/video-providers` 仍只返回启用的 `mock-video`,不会把未启用真实 Provider 暴露给用户。
|
||
- MiniMax Hailuo 2.3 Fast 成本估算接口可返回预估:第 28 集当前 1 个片段、4 秒、估算 0.1268 USD;Provider 仍为 disabled。
|
||
- 使用禁用的 `minimax_hailuo_23_fast` 强制生成会返回 `400 LIVE_ACTION_VIDEO_PROVIDER_DISABLED`,不会回落 mock,也不会调用外部接口。
|
||
- Provider 日志确认本次无新增真实国内视频调用;最近视频日志只有 mock 和旧的 OpenAI 视频失败记录,成本为 0。
|
||
|
||
遗留问题:
|
||
|
||
- 国内 Provider 的真实付费小样尚未执行;需要你确认使用哪家、填 Key、启用 Provider、设置价格和成本阈值后,先跑 1 个镜头。
|
||
- 阿里 Wan、Seedance/即梦不同开通渠道和网关字段差异较大,当前作为可配置模板;正式启用前必须用 1 个镜头核对请求字段、返回 URL、耗时和账单。
|
||
- 真实视频仍要求关键帧为 PNG/JPG/WebP 或外部可访问 URL;mock SVG 关键帧不能直接作为真实图生视频输入。
|
||
|
||
下一步建议:
|
||
|
||
- 后台只启用 `minimax_hailuo_23_fast`,填 Key、Base URL、单次/每日成本上限和真实单价,用 1 个镜头做真实小样。
|
||
- 小样验收维度:人物一致性、面部表情、动作自然度、镜头语言、中文短剧感、生成耗时、失败率、实际扣费。
|
||
|
||
### 系统 B 文档升级:V3 真人动态视频版
|
||
|
||
完成时间:2026-06-02
|
||
|
||
完成内容:
|
||
|
||
- 系统 B 文档从 V2「真人照片 -> 写真图集 / 图片纪念视频」升级为 V3「真人动态视频版」。
|
||
- 新增 V3 升级说明,明确系统 B 不推翻旧设计,而是在原照片、主题、世界、场景、视频合成、隐私授权基础上新增真人动态视频链路。
|
||
- 新增 V3 主需求文档,明确 4 档输出模式:
|
||
- 高清写真图集。
|
||
- 图片纪念视频。
|
||
- 动态写真视频。
|
||
- AI 真人动态视频。
|
||
- 高端真人纪念片作为人工报价和多轮精修套餐。
|
||
- 明确系统 B 和系统 A 的核心差异:
|
||
- 系统 A 是虚构小说角色转真人短剧。
|
||
- 系统 B 是真实用户照片转真人动态纪念视频,更强调本人相似度、肖像权、隐私、未成年人和公开授权。
|
||
- 主需求、功能清单、技术架构、数据库、API、用户端、后台、AI 流水线、Prompt、成本、队列、合规、测试和 Codex 拆解均补充 V3 增量。
|
||
- 新增或强化设计对象:
|
||
- `IdentityAnchor`
|
||
- `MotionTemplate`
|
||
- `VideoClip`
|
||
- `LipSyncTask`
|
||
- `FaceIdentityProvider`
|
||
- `FaceConsistencyProvider`
|
||
- `MotionPortraitProvider`
|
||
- `LipSyncProvider`
|
||
- 明确国内短剧向 VideoProvider 策略:MiniMax Hailuo、阿里 Wan、Vidu、Seedance/即梦、Kling、Runway、MockVideoProvider。
|
||
- 明确真实视频 Provider 默认禁用,必须成本预估、用户确认、后台启用、阈值保护后才能调用;失败不能回落 mock 假成功。
|
||
- README 和 manifest 已更新为 V3 文档包入口。
|
||
|
||
修改文件:
|
||
|
||
- docs/system_b/02_需求文档修改v2.md
|
||
- docs/system_b/03_功能清单_页面清单_状态流转设计.md
|
||
- docs/system_b/04_技术架构设计_模块拆分.md
|
||
- docs/system_b/05_数据库表结构设计.md
|
||
- docs/system_b/06_API接口设计文档.md
|
||
- docs/system_b/07_uniapp用户端页面交互文档.md
|
||
- docs/system_b/08_GeekerAdmin后台管理设计.md
|
||
- docs/system_b/09_AI生成流水线_Provider抽象设计.md
|
||
- docs/system_b/10_Prompt模板_世界观模板规范.md
|
||
- docs/system_b/11_订单支付_额度_成本控制设计.md
|
||
- docs/system_b/12_任务队列_错误重试_稳定性设计.md
|
||
- docs/system_b/13_隐私授权_内容审核_合规设计.md
|
||
- docs/system_b/15_测试用例_验收标准.md
|
||
- docs/system_b/16_Codex开发任务拆解文档.md
|
||
- docs/system_b/README.md
|
||
- docs/system_b/manifest.json
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- docs/system_b/00_系统B升级说明_真人动态视频.md
|
||
- docs/system_b/01_系统B总需求文档_v3_真人动态视频版.md
|
||
|
||
运行命令:
|
||
|
||
- 读取用户粘贴的系统 B 升级建议。
|
||
- `find docs -maxdepth 3 -type f`
|
||
- `rg` 检索系统 B、VideoProvider、真人动态视频相关文档。
|
||
- `sed` 检查系统 B README、主需求、AI 流水线、数据库、合规、测试、拆解等文档。
|
||
|
||
测试结果:
|
||
|
||
- 文档更新完成,无代码改动。
|
||
- 未运行构建和单测。
|
||
|
||
下一步建议:
|
||
|
||
- 按 V3 文档先做系统 B 独立开发计划,优先落地:输出模式、照片上传要求、身份锚点、本人相似度质检、动态写真 mock、真实视频单镜头小样。
|
||
|
||
### 后台新增 AI 平台入口页
|
||
|
||
完成时间:2026-06-02
|
||
|
||
完成内容:
|
||
|
||
- 后台新增“AI 平台入口”菜单页,方便运营集中查看和开户注册各大 AI 平台。
|
||
- 页面整理了已接入或预留接入的平台:
|
||
- OpenAI
|
||
- MiniMax / Hailuo
|
||
- 阿里云百炼 / DashScope
|
||
- Vidu
|
||
- 火山方舟 / Seedance
|
||
- Runway
|
||
- Kling
|
||
- 内部 Mock / 本地 FFmpeg
|
||
- 每个平台展示:
|
||
- 官网。
|
||
- 控制台/注册入口。
|
||
- 文档入口。
|
||
- 对应 Provider 编码。
|
||
- 后台应填写的 Key 名称。
|
||
- 接入状态。
|
||
- 费用提醒。
|
||
- 运营备注。
|
||
- 页面提示运营顺序:先注册/主体认证/充值,再回“AI 接入”页保存 Key;真实视频先做单镜头小样,避免误扣费。
|
||
- Kling 标注为“渠道待核”,避免运营误以为接口已完全确认。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- 官方入口检索:OpenAI、MiniMax、阿里百炼/DashScope、Vidu、Runway、火山方舟/Seedance、Kling。
|
||
- `npm run typecheck -w admin`
|
||
- `npm run build -w admin`
|
||
- `curl -I http://127.0.0.1:5175`
|
||
|
||
测试结果:
|
||
|
||
- 后台 typecheck 通过。
|
||
- 后台 build 通过。
|
||
- 后台 dev 服务仍在 5175 运行,HTTP 200。
|
||
- 本次未调用任何真实 AI Provider,没有产生 AI 成本。
|
||
|
||
### 后台 AI 平台入口接入配置跳转
|
||
|
||
完成时间:2026-06-02
|
||
|
||
完成内容:
|
||
|
||
- “AI 平台入口”页新增 Hailuo 快速配置卡片,直接说明 MiniMax / Hailuo 的注册、Key 获取、后台配置路径和推荐默认值。
|
||
- 平台入口清单新增“后台配置”列,展示每个平台对应 Provider 的配置状态:
|
||
- 未初始化。
|
||
- 待配置 Key,未启用。
|
||
- 已保存 Key,未启用。
|
||
- 已配置并启用。
|
||
- 点击“去配置”会自动进入“AI 接入”页并展开高级配置。
|
||
- 如果视频 Provider 还没初始化,点击“去配置”会先初始化视频 Provider,再打开对应配置表单。
|
||
- Hailuo 默认打开 `minimax_hailuo_23_fast`,便于运营先做低成本单镜头小样。
|
||
- 初始化视频 Provider 的提示文案改为“视频 Provider 已初始化,真实接入默认未启用”,避免误解只支持 Runway/Kling。
|
||
- 本次只做配置入口和后台 UI 优化,不调用真实 AI,不产生 AI 成本。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- `npm run typecheck -w admin`
|
||
- `npm run build -w admin`
|
||
- `curl -I --max-time 5 http://127.0.0.1:5175`
|
||
- `git status --short`
|
||
|
||
测试结果:
|
||
|
||
- 后台 typecheck 通过。
|
||
- 后台 build 通过。
|
||
- 后台 dev 服务仍在 5175 运行,HTTP 200。
|
||
- 当前目录不是 git 仓库,`git status --short` 返回 `fatal: not a git repository`。
|
||
|
||
### 全局角色资产库 / 跨项目角色复用
|
||
|
||
完成时间:2026-06-03
|
||
|
||
完成内容:
|
||
|
||
- 新增全局角色资产库,用于沉淀可跨项目复用的主角、配角、反派和声音/服装配置。
|
||
- 新增数据库表:
|
||
- `global_characters`
|
||
- `global_character_assets`
|
||
- `characters` 表新增复用字段:
|
||
- `global_character_id`
|
||
- `wardrobe_variant`
|
||
- `voice_provider_code`
|
||
- `voice_model`
|
||
- `voice_id`
|
||
- `voice_style`
|
||
- `performance_style`
|
||
- 后端新增后台接口:
|
||
- `GET /api/admin/global-characters`
|
||
- `POST /api/admin/global-characters`
|
||
- `PATCH /api/admin/global-characters/:globalCharacterId`
|
||
- `POST /api/admin/characters/:characterId/bind-global`
|
||
- 后台新增“角色资产库”菜单页:
|
||
- 可创建/编辑全局角色。
|
||
- 可配置锚点素材 ID、固定外观、默认服装、声音 Provider、Voice ID、声音风格、表演风格和授权范围。
|
||
- 可查看全局角色被多少项目角色绑定。
|
||
- 后台“角色资源”页新增:
|
||
- 全局角色绑定显示。
|
||
- 下拉选择全局角色并绑定/解绑。
|
||
- 角色详情预览展示全局角色、声音、服装变体和表演风格。
|
||
- 项目角色创建/更新支持绑定 `global_character_id`。
|
||
- 绑定全局角色时,如果项目角色缺少锚点、声音或默认服装,会自动带入全局角色资产;项目角色已有差异化设置不强行覆盖。
|
||
- 图片 Prompt、分镜 Prompt、真人演员定妆 Prompt 增加全局角色 ID、服装变体、角色声音/表演风格提示,给后续真实图片/视频 Provider 做一致性约束。
|
||
- 用户端 `SafeCharacter` 类型同步新增全局角色、服装和声音字段。
|
||
- `OPERATION_GUIDE.md` 新增“全局角色资产库”小白说明。
|
||
- 已创建一个内部测试全局角色资产:`内部测试女主模板`,用于后台页面联调,不调用 AI、不产生 AI 成本。
|
||
|
||
修改文件:
|
||
|
||
- backend/prisma/schema.prisma
|
||
- backend/prisma/migrations/20260603093000_global_character_library/migration.sql
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/characters/character.dto.ts
|
||
- backend/src/characters/character.types.ts
|
||
- backend/src/characters/characters.service.ts
|
||
- backend/src/images/images.service.ts
|
||
- backend/src/scripts/scripts.service.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/*/*.spec.ts 相关测试夹具
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- user-app/src/api/client.ts
|
||
- OPERATION_GUIDE.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- `set -a; . ./.env; set +a; npm run prisma:validate -w backend`
|
||
- `set -a; . ./.env; set +a; npm run prisma:generate -w backend`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run typecheck -w user-app`
|
||
- `set -a; . ./.env; set +a; npm run prisma:deploy -w backend`
|
||
- `npm test -w backend`
|
||
- `npm run build -w admin`
|
||
- `npm run build -w backend`
|
||
- `npm run build -w user-app`
|
||
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
|
||
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
|
||
- Node 脚本真实联调后台登录、创建/更新/读取全局角色资产。
|
||
|
||
测试结果:
|
||
|
||
- Prisma schema validate 通过。
|
||
- Prisma Client generate 通过。
|
||
- 数据库迁移已成功应用。
|
||
- 后端 typecheck 通过。
|
||
- 后台 typecheck 通过。
|
||
- 用户端 typecheck 通过。
|
||
- 后端测试 22 个测试文件、145 个测试全部通过。
|
||
- 后台 build 通过。
|
||
- 后端 build 通过。
|
||
- 用户端 build 通过。
|
||
- 后端已重启,新 PID:4072726。
|
||
- 后端健康接口正常。
|
||
- 后台 dev 服务仍在 5175 运行,HTTP 200。
|
||
- 本次未调用任何真实 AI Provider,没有产生 AI 成本。
|
||
|
||
遗留问题:
|
||
|
||
- TTS 当前仍是单集音频生成接口为主,已经有角色级声音数据基础;下一步需要把脚本对白拆成按角色声线合成,再混音成最终音轨。
|
||
- 全局角色资产的图片/声音上传和预览目前依赖素材 ID;后续应加“从素材库选择/上传”的弹窗。
|
||
- 全局角色版本管理、角色授权到期提醒、批量换装/换声线还未做。
|
||
|
||
下一步建议:
|
||
|
||
- 进入“角色级 TTS / 多角色对白混音”阶段:按角色 voice_id 生成对白,旁白独立声线,最后混音并与字幕时间轴对齐。
|
||
|
||
### 角色级 TTS / 多角色对白混音
|
||
|
||
完成时间:2026-06-03
|
||
|
||
完成内容:
|
||
|
||
- `POST /api/episodes/:episodeId/audio/generate` 默认升级为 `dialogue_mode: mixed` 多角色音频模式。
|
||
- 音频生成会按已确认分镜顺序拆分:
|
||
- 分镜旁白片段。
|
||
- 分镜对白片段。
|
||
- 支持识别 `角色名:台词` 格式。
|
||
- 无角色名前缀时,从分镜 `characters_json` 推断角色;再兜底到主角/领衔角色。
|
||
- 角色对白优先使用项目角色/全局角色里的声音字段:
|
||
- `voice_provider_code`
|
||
- `voice_model`
|
||
- `voice_id`
|
||
- `voice_style`
|
||
- 旁白使用 `narration_voice` 或默认 `coral`。
|
||
- 每个片段独立调用 `VoiceProvider`,真实 TTS 会产生多次调用成本;任务 input_json 会记录片段摘要、角色、voice 和 speaker。
|
||
- 多个 TTS 片段会用 FFmpeg 转码并 concat 成整集 `dialogue-mix.wav`。
|
||
- FFmpeg 不可用且全是 mock 片段时,会兜底生成静音 mock wav;真实片段混音必须有 FFmpeg。
|
||
- 保留旧单段旁白模式:请求体传 `{ "dialogue_mode": "narration" }`。
|
||
- 用户端“音频字幕”按钮改为“多角色音频”,并显式传 `dialogue_mode: mixed`。
|
||
- `OPERATION_GUIDE.md` 增加多角色音频说明和真实 TTS 成本提醒。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.dto.ts
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- OPERATION_GUIDE.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w user-app`
|
||
- `npm run typecheck -w admin`
|
||
- `npm test -w backend -- src/media/media.service.spec.ts`
|
||
- `npm test -w backend`
|
||
- `npm run build -w backend`
|
||
- `npm run build -w user-app`
|
||
- `npm run build -w admin`
|
||
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
|
||
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- 媒体服务单测 10 个全部通过,覆盖默认多角色混音路径。
|
||
- 后端测试 22 个测试文件、145 个测试全部通过。
|
||
- 后端 typecheck 通过。
|
||
- 用户端 typecheck 通过。
|
||
- 后台 typecheck 通过。
|
||
- 后端 build 通过。
|
||
- 用户端 build 通过。
|
||
- 后台 build 通过。
|
||
- 后端已重启,新 PID:4090999。
|
||
- 3000、5174、5175 端口均在监听,健康接口正常。
|
||
- 本次未调用任何真实 AI Provider,没有产生 AI 成本。
|
||
|
||
遗留问题:
|
||
|
||
- 当前混音是按片段顺序 concat,尚未按镜头时间轴精确对齐到每个分镜起止时间。
|
||
- 字幕仍按镜头生成,还未拆到每句对白级时间码。
|
||
- 后台还需要增加角色声音试听、voice_id 校验、真实 TTS 成本预估和片段级失败重试 UI。
|
||
|
||
下一步建议:
|
||
|
||
- 继续做“对白级字幕 / 音频时间轴对齐”:生成每句台词的 SRT cue,并让音频片段按分镜时间轴铺到对应位置。
|
||
|
||
### 对白级字幕 / 音频时间轴对齐
|
||
|
||
完成时间:2026-06-03
|
||
|
||
完成内容:
|
||
|
||
- `POST /api/episodes/:episodeId/audio/generate` 的多角色音频片段新增时间轴字段:
|
||
- `start_seconds`
|
||
- `end_seconds`
|
||
- `target_duration`
|
||
- 多角色 TTS 不再只按顺序 concat;现在会用 FFmpeg 按每段 `start_seconds` 延迟铺轨,输出一条与分镜时间轴对齐的整集 WAV。
|
||
- 音频接口返回 `timeline_warnings`,真实 TTS 超出分配时长时会标出超长片段,方便运营缩短台词、加长镜头或调语速。
|
||
- `POST /api/episodes/:episodeId/subtitle/generate` 默认升级为 `subtitle_mode: dialogue`。
|
||
- 对白级字幕会把每句旁白/台词生成独立 SRT cue,并与多角色音频共用同一套分镜时间轴。
|
||
- 保留旧版分镜级字幕:请求体传 `{ "subtitle_mode": "shot" }`。
|
||
- 用户端“图片、音频和视频”区域文案更新为“多角色音频 / 对白级字幕”。
|
||
- `OPERATION_GUIDE.md` 更新小白说明:解释多角色音频、对白级字幕、时间轴告警和旧版字幕参数。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.dto.ts
|
||
- backend/src/media/media.types.ts
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- OPERATION_GUIDE.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w user-app`
|
||
- `npm run typecheck -w admin`
|
||
- `npm test -w backend -- src/media/media.service.spec.ts`
|
||
- `npm test -w backend`
|
||
- `npm run build -w backend`
|
||
- `npm run build -w user-app`
|
||
- `npm run build -w admin`
|
||
- 后端重启:`setsid node /www/wwwroot/ai/backend/dist/main.js ...`
|
||
- `curl -sS --max-time 5 http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- 后端 typecheck 通过。
|
||
- 用户端 typecheck 通过。
|
||
- 后台 typecheck 通过。
|
||
- 媒体服务单测 11 个全部通过,覆盖默认多角色音频时间轴和默认对白级字幕。
|
||
- 后端测试 22 个测试文件、146 个测试全部通过。
|
||
- 后端 build 通过。
|
||
- 用户端 build 通过。
|
||
- 后台 build 通过。
|
||
- 后端已重启,新 PID:4109378。
|
||
- 3000、5174、5175 端口均在监听,健康接口正常。
|
||
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
|
||
|
||
遗留问题:
|
||
|
||
- 尚未做前端逐句字幕/音频片段预览和单句重试 UI。
|
||
- 真实 TTS 语速控制仍依赖 Provider 能力;后续需要把“超时长台词”在前端明显提示出来。
|
||
- 视频最终仍是分镜图 + 音频 + 字幕的 FFmpeg 合成,不是人物真实动态视频。
|
||
|
||
下一步建议:
|
||
|
||
- 继续补片段级运营闭环:逐句音频试听、逐句字幕预览、单句重试、超时长台词红色提示,以及真实 TTS 成本预估。
|
||
|
||
### 片段级音频字幕预览 / 超时提示 / TTS 成本提示
|
||
|
||
完成时间:2026-06-03
|
||
|
||
完成内容:
|
||
|
||
- `GET /api/episodes/:episodeId/media-assets` 保留旧字段:
|
||
- `task_type`
|
||
- `task_id`
|
||
- `asset`
|
||
- 同时新增任务详情和媒体摘要:
|
||
- `task`
|
||
- `timeline`
|
||
- `stats`
|
||
- 音频资产行会返回:
|
||
- 多角色音频 `segments`
|
||
- `timeline_warnings`
|
||
- 片段数、声音数、总字符数、总时长、告警数量
|
||
- TTS 成本提示:按字符/Provider usage 估算,最终以 Provider 日志和平台账单为准
|
||
- 字幕资产行会读取私有 SRT 文件并返回 `cues`,用于前端展开预览。
|
||
- 多角色音频任务成功后会把实际片段时长、mock 标记、超时告警写回 `render_tasks.input_json`,刷新页面后仍可查看。
|
||
- 用户端“图片、音频和视频”新增“音频字幕时间轴”面板:
|
||
- 展示每句旁白/对白。
|
||
- 展示镜头号、说话人、起止秒、目标时长、实际 TTS 时长、voice。
|
||
- 超时句子红色边框提示。
|
||
- 支持试听整集音频、下载字幕。
|
||
- 支持展开查看前 20 条字幕 cue。
|
||
- 工作流任务中文标签从“旁白音频”改为“多角色音频”。
|
||
- `OPERATION_GUIDE.md` 补充时间轴面板、超时处理和成本提示说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- user-app/src/workflow.ts
|
||
- OPERATION_GUIDE.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w user-app`
|
||
- `npm run typecheck -w admin`
|
||
- `npm test -w backend -- src/media/media.service.spec.ts`
|
||
- `npm test -w backend`
|
||
- `npm run build -w backend`
|
||
- `npm run build -w user-app`
|
||
- `npm run build -w admin`
|
||
|
||
测试结果:
|
||
|
||
- 后端 typecheck 通过。
|
||
- 用户端 typecheck 通过。
|
||
- 后台 typecheck 通过。
|
||
- 媒体服务单测 12 个全部通过,覆盖 media-assets 时间轴返回。
|
||
- 后端测试 22 个测试文件、147 个测试全部通过。
|
||
- 后端 build 通过。
|
||
- 用户端 build 通过。
|
||
- 后台 build 通过。
|
||
- 后端已重启,新 PID:4144718。
|
||
- 3000、5174、5175 端口均在监听,健康接口正常。
|
||
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
|
||
|
||
遗留问题:
|
||
|
||
- 逐句“只重试这一句 TTS”还未做,当前是先展示和定位问题。
|
||
- 逐句音频裁切试听还未做,当前试听的是整集音频。
|
||
- 成本提示是字符级/Provider usage 提醒,还不是根据具体 Provider 价格换算成美元。
|
||
|
||
下一步建议:
|
||
|
||
- 继续做单句 TTS 重试:选择某句、指定 voice/语速、重新合成该句并重新铺轨;同时把真实 Provider 价格规则接入前端美元预估。
|
||
|
||
### 单句 TTS 重试 / 片段文件保存
|
||
|
||
完成时间:2026-06-03
|
||
|
||
完成内容:
|
||
|
||
- 新增接口 `POST /api/episodes/:episodeId/audio/segments/:segmentIndex/retry`。
|
||
- 单句重试支持参数:
|
||
- `voice`
|
||
- `voice_style`
|
||
- `speech_speed`,范围 0.6 到 1.4
|
||
- 多角色音频生成时会把每句 TTS 的原始音频片段单独保存到私有存储 `generated-audio-segments`。
|
||
- `render_tasks.input_json.segment_results` 会记录每句片段的:
|
||
- 实际时长
|
||
- mock 标记
|
||
- MIME
|
||
- 私有片段路径
|
||
- hash/size
|
||
- 单句重试时,后端只调用一次 `VoiceProvider` 生成目标句;其它句从私有片段文件读取,然后重新按时间轴混成整集音频。
|
||
- 单句重试会创建新的整集音频资产,旧音频资产保留;后续合成视频会使用最新音频。
|
||
- 老版本音频缺少片段文件时,不会偷偷整集重跑;接口会提示先重生成整集多角色音频一次。
|
||
- 用户端时间轴每句新增“重试此句”按钮。
|
||
- 点开后可填写声音 ID、语速、语气说明。
|
||
- 如果当前音频不支持单句重试,用户端会显示“重生成音频”按钮和费用提醒。
|
||
- 错误文案补充中文提示,避免运营看到英文异常。
|
||
- `OPERATION_GUIDE.md` 补充单句重试说明。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.dto.ts
|
||
- backend/src/media/media.controller.ts
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- OPERATION_GUIDE.md
|
||
- CODEX_PROGRESS.md
|
||
|
||
运行命令:
|
||
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w user-app`
|
||
- `npm run typecheck -w admin`
|
||
- `npm test -w backend -- src/media/media.service.spec.ts`
|
||
- `npm test -w backend`
|
||
- `npm run build -w backend`
|
||
- `npm run build -w user-app`
|
||
- `npm run build -w admin`
|
||
|
||
测试结果:
|
||
|
||
- 后端 typecheck 通过。
|
||
- 用户端 typecheck 通过。
|
||
- 后台 typecheck 通过。
|
||
- 媒体服务单测 13 个全部通过,覆盖单句 TTS 重试只调用一次 VoiceProvider。
|
||
- 后端测试 22 个测试文件、148 个测试全部通过。
|
||
- 后端 build 通过。
|
||
- 用户端 build 通过。
|
||
- 后台 build 通过。
|
||
- 后端已重启,新 PID:4174180。
|
||
- 3000、5174、5175 端口均在监听,健康接口正常。
|
||
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
|
||
|
||
遗留问题:
|
||
|
||
- 单句重试后字幕文本未改动;如果要改台词内容,需要后续做“改句文本 + 重写 SRT cue”。
|
||
- 逐句音频裁切试听还未做,当前仍试听整集音频。
|
||
- 真实 Provider 价格规则还未换算成前端美元预估。
|
||
|
||
下一步建议:
|
||
|
||
- 继续做“单句文本编辑 + 字幕 cue 更新 + 单句音频试听裁切”,让运营能在一个抽屉里完成台词、字幕、声音的一句级修正。
|
||
|
||
### 单句 TTS 连续重试片段元数据保留
|
||
|
||
完成时间:2026-06-03 16:40:34 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复深度验收发现的问题:单句 TTS 重试后,新音频任务只保留被重试片段的 `segment_file_path`,其它复用片段的文件路径丢失,导致无法稳定继续做第二次单句重试。
|
||
- `loadStoredAudioSegmentFiles` 读取旧片段时,现在会带回原始 `filePath`、`size` 和 `hash`。
|
||
- `readTaskAudioSegmentResults` 新增读取 `segment_size` 和 `segment_hash`。
|
||
- 单句重试后写回新的 `render_tasks.input_json.segment_results` 时,所有片段都会保留私有片段文件路径。
|
||
- 媒体服务单测补充断言:重试后的 `segment_results` 每个片段都必须有 `segment_file_path`,并保留旧片段 size/hash。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -w backend -- src/media/media.service.spec.ts`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 媒体服务单测 13 个全部通过。
|
||
- `npm run lint` 通过。
|
||
- `npm run typecheck` 通过。
|
||
- `npm test` 通过:后端 22 个测试文件、148 个测试通过;workers 1 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- `npm run build` 通过:backend、admin、user-app、workers 均构建成功。
|
||
- 后端已重启,新 PID:47233。
|
||
- `GET /api/health` 健康检查通过。
|
||
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
|
||
|
||
遗留问题:
|
||
|
||
- 还未重新跑一次完整端到端连续两次单句重试实机验收;当前已有单测覆盖元数据保留。
|
||
- 单句重试后字幕文本未改动;如果要改台词内容,需要后续做“改句文本 + 重写 SRT cue”。
|
||
- 逐句音频裁切试听还未做,当前仍试听整集音频。
|
||
|
||
下一步建议:
|
||
|
||
- 补一次真实 API E2E:生成多角色音频后连续重试两次不同句子,确认 `media-assets` 始终返回 `segment_retry_ready=true`。
|
||
- 继续做“单句文本编辑 + 字幕 cue 更新 + 单句音频试听裁切”。
|
||
|
||
### 后台视频预览本地存储路径稳定化
|
||
|
||
完成时间:2026-06-03 16:52:23 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复后台预览视频时报错:`ENOENT: no such file or directory, open '../storage/private/rendered-videos/2026-06-03/e86eb917-111d-4969-b505-585319fd5e23.mp4'`。
|
||
- 根因:`.env` 中 `LOCAL_STORAGE_ROOT=../storage` 是相对路径,后端从 `/www/wwwroot/ai` 启动时会写入 `/www/wwwroot/storage`,从 `/www/wwwroot/ai/backend` 启动时会读取 `/www/wwwroot/ai/storage`,导致同一条 `local://...` 资产路径在不同启动目录下指向不同磁盘位置。
|
||
- `StorageService` 现在会把相对 `LOCAL_STORAGE_ROOT` 固定按 backend 包目录解析,避免启动目录不同导致文件分裂。
|
||
- 已将历史目录 `/www/wwwroot/storage/private` 下的本地私有文件按不覆盖方式复制到规范目录 `/www/wwwroot/ai/storage/private`。
|
||
- 已确认报错资产 `asset_id=221` 对应文件存在于规范目录,并可通过 `GET /api/assets/221/download` 正常返回。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/assets/storage.service.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `find /www/wwwroot -path '*e86eb917-111d-4969-b505-585319fd5e23.mp4'`
|
||
- `cp -an /www/wwwroot/storage/private/. /www/wwwroot/ai/storage/private/`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend`
|
||
- `npm run build -w backend`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm test`
|
||
- `npm run build`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- 管理员登录后请求 `GET /api/assets/221/download`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端 typecheck 通过。
|
||
- 后端测试 22 个测试文件、148 个测试通过。
|
||
- 后端 build 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm test` 通过:后端 148 个测试通过;workers 1 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- 后端已重启,新 PID:65044。
|
||
- `GET /api/health` 健康检查通过。
|
||
- `GET /api/assets/221/download` 返回 HTTP 200,`content-type=video/mp4`,大小 `210697` 字节,MP4 header 为 `ftyp`。
|
||
- 本阶段未调用真实 AI Provider,没有产生 AI 成本。
|
||
|
||
遗留问题:
|
||
|
||
- 服务器上仍保留旧目录 `/www/wwwroot/storage/private` 作为历史文件来源,暂未删除,避免误删仍被其它进程引用的文件。
|
||
- 当前修复覆盖 local 存储;MinIO 模式不受此相对路径问题影响。
|
||
|
||
下一步建议:
|
||
|
||
- 后续部署脚本中建议显式配置绝对路径 `LOCAL_STORAGE_ROOT=/www/wwwroot/ai/storage`,进一步减少运维误启动风险。
|
||
|
||
### 扩展 AI 平台接入骨架
|
||
|
||
完成时间:2026-06-09 17:22:49 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增“扩展 AI Provider”默认预设,后续开通账号后可在后台填写 Key、Base URL、模型名、成本阈值并启用。
|
||
- 扩展预设全部默认 `is_enabled=false`,不会自动调用真实外部接口,不会自动扣费。
|
||
- 已预置 Google Gemini/Imagen/Veo、Anthropic Claude、DeepSeek、Qwen、Kimi、智谱 GLM、百度千帆、腾讯混元、讯飞星火、豆包/火山方舟文本、MiniMax 文本/TTS、Baichuan、StepFun、SenseNova、360、Mistral、Cohere、xAI、OpenRouter、Together、Fireworks、Perplexity、Azure OpenAI、AWS Bedrock 兼容网关、Stability、Replicate、fal.ai、Ideogram、Leonardo、ElevenLabs、Luma、Pika 等 Provider 配置位。
|
||
- 新增真实 driver:
|
||
- `openai_compatible_chat`
|
||
- `anthropic_messages`
|
||
- `google_gemini_generate_content`
|
||
- `cohere_chat`
|
||
- `configurable_image_generation`
|
||
- `configurable_text_to_speech`
|
||
- `configurable_async_asset_generation`
|
||
- `google_veo_video_generation`
|
||
- 后台新增 `POST /api/admin/providers/bootstrap-extended-ai`,用于初始化扩展 AI 接入。
|
||
- 后台“AI 平台入口”补充扩展平台开户注册/控制台/文档/Key 名称/运营备注。
|
||
- 后台“AI 接入”高级工具栏新增“初始化扩展 AI 接入”按钮。
|
||
- 已将当前数据库写入 45 个扩展 Provider 预设,全部保持 disabled。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/providers/provider.types.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.controller.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- admin/src/App.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -w backend -- providers.service.spec.ts`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
- 使用 Prisma Client 初始化当前数据库扩展 Provider 预设
|
||
- 使用 Prisma Client 抽样核验扩展 Provider 列表
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Provider 单测通过:`27` 个测试通过。
|
||
- 后端 typecheck 通过。
|
||
- 后台 typecheck 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- 当前数据库扩展 Provider 初始化结果:`extended_ai_providers_upserted=45`。
|
||
- 抽样核验 Google、Claude、DeepSeek、Qwen、Kimi、GLM、ElevenLabs、Stability、Replicate、Luma、Pika 等 Provider 均存在且为 `disabled`。
|
||
- 后端已重启到新版本,新 PID:`3474791`;`GET /api/health` 健康检查通过。
|
||
- 本阶段未配置真实 API Key,未调用真实 AI Provider,没有产生 AI 成本。
|
||
|
||
遗留问题:
|
||
|
||
- 部分平台接口、模型名和鉴权方式会随账号渠道变化,当前按可配置模板或 OpenAI-compatible 通道预置;正式启用前仍必须用 1 次小样验证 endpoint、返回字段、耗时和实际账单。
|
||
- AWS Bedrock 原生 SigV4、部分国内平台 HMAC 签名通道未在本阶段实现,当前预设优先服务兼容网关/可配置接入。
|
||
- 视频类扩展 Provider 成本较高,仍应保持默认禁用并设置单次/每日成本阈值。
|
||
|
||
下一步建议:
|
||
|
||
- 先挑 3 条低风险链路做真实 Key 联调:DeepSeek/Qwen 文本、ElevenLabs TTS、Google Gemini 文本。
|
||
- 视频真实小样仍建议从 Hailuo Fast 或 Seedance 单镜头开始,不要一次性启用多个真实视频 Provider。
|
||
|
||
### 后台生产驾驶舱 UI 兼容融合
|
||
|
||
完成时间:2026-06-09 18:28:16 CST
|
||
|
||
完成内容:
|
||
|
||
- 已查看参考图 `/www/wwwroot/dc16513b-fdaf-4721-8091-7fde3a523492.png`,确认可与当前后台兼容融合。
|
||
- 后台“仪表盘”改为深色 AI 生产驾驶舱风格,融合参考图中的 KPI 顶栏、系统模块、漫剧生成工作流、AI 平台选择策略、平台对比和成本分析。
|
||
- 新仪表盘继续使用现有 `/admin/dashboard`、`/admin/queues`、`/admin/providers` 数据,不新增后端接口,不改变 Provider、任务队列、成本控制和权限逻辑。
|
||
- 首页加载时同步读取 Provider 列表,用于展示平台预置/启用/Key 配置状态。
|
||
- 保留任务状态、项目状态、队列状态等原始运营信息,并增加移动端单列兼容布局。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run build -w admin`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后台 typecheck 通过。
|
||
- 后台单独 build 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响构建产物。
|
||
- 后台预览服务已确认可访问:`http://127.0.0.1:5175/`。
|
||
- 后端已用 `setsid node backend/dist/main.js` 守护式启动,PID:`3603810`;`GET /api/health` 健康检查通过。
|
||
|
||
遗留问题:
|
||
|
||
- 本阶段是后台仪表盘 UI 融合,没有做真实浏览器截图验收;如需像素级贴近参考图,可继续启动后台预览并按实际窗口微调间距、字号和色彩。
|
||
- 平台质量评分仍按真实配置状态展示,没有引入虚假的模型评分。
|
||
|
||
下一步建议:
|
||
|
||
- 后台启动预览后人工看一眼仪表盘首屏,确认是否继续把同一视觉风格扩展到“AI 平台入口”和“AI 接入”两个页面。
|
||
|
||
### AI 平台入口 / AI 接入深色运营台风格接入
|
||
|
||
完成时间:2026-06-09 20:28:58 CST
|
||
|
||
完成内容:
|
||
|
||
- 已将后台深色生产驾驶舱风格继续扩展到“AI 平台入口”和“AI 接入”两个页面。
|
||
- `dashboard / aiPlatforms / providers` 三个 section 共享 cockpit 深色外壳、侧边栏和工作区视觉。
|
||
- “AI 平台入口”保留开户注册入口、Hailuo 快速配置、平台清单、开户注册顺序,同时统一为深色面板、深色表格、亮色链接按钮和状态 Badge。
|
||
- “AI 接入”保留 OpenAI 统一配置、高级 Provider 配置、初始化按钮、Provider 列表、测试结果,同时统一为深色表单、深色输入框、深色工具栏和 Provider 配置面板。
|
||
- 本阶段只改后台展示层,不新增接口,不修改真实 Provider 调用逻辑,不写入 API Key。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run build -w admin`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后台 typecheck 通过。
|
||
- 后台单独 build 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 本阶段未做浏览器截图级微调;实际观感还需人工打开后台确认列表密度、表格宽度、色彩对比是否满意。
|
||
|
||
下一步建议:
|
||
|
||
- 打开后台 `http://127.0.0.1:5175/`,依次查看“仪表盘 / AI 平台入口 / AI 接入”三页,确认是否继续把“成本日志 / 任务管理”也统一到这套运营台风格。
|
||
|
||
### 任务管理 / 成本日志深色运营台风格接入
|
||
|
||
完成时间:2026-06-09 20:36:49 CST
|
||
|
||
完成内容:
|
||
|
||
- 已将后台“任务管理”和“成本日志”继续接入深色运营台风格。
|
||
- 任务管理页新增任务运行概览卡片,展示当前列表任务数、执行中、失败、人工处理和累计重试信息。
|
||
- 任务管理页筛选栏、任务表格、刷新任务按钮统一为深色运营台视觉。
|
||
- 成本日志页新增 Provider 成本概览卡片,展示总成本、日志数、成功调用、异常调用。
|
||
- 成本日志页 Provider 日志表格、刷新成本按钮统一为深色运营台视觉。
|
||
- 本阶段只改后台展示层,不修改任务队列、成本统计、Provider 调用和后端接口。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run build -w admin`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后台 typecheck 通过。
|
||
- 后台单独 build 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 未做浏览器截图级细调,任务/成本页表格列宽和首屏信息密度仍建议人工预览确认。
|
||
|
||
下一步建议:
|
||
|
||
- 人工打开后台依次查看“任务管理 / 成本日志”两页;若整体满意,可继续把“内容审核 / 项目管理 / 成品漫剧”统一成同一套后台风格。
|
||
|
||
### 全项目 UI 深色运营台风格统一
|
||
|
||
完成时间:2026-06-09 20:41:36 CST
|
||
|
||
完成内容:
|
||
|
||
- 已将后台端所有 section 扩展为统一深色运营台外壳,不再只限制在仪表盘、AI 接入、任务和成本页面。
|
||
- 后台补充全局深色覆盖:面板、表格、表单、按钮、状态 Badge、额度卡片、操作区、预览抽屉、JSON 预览、提示消息等统一风格。
|
||
- 用户端 `user-app` 增加全局深色生产主题:登录页、底部/侧边导航、项目创建、项目列表、工作台、进度、结果、额度、审核、教程、个人中心、素材预览弹窗等常用组件统一为深色运营台风格。
|
||
- 本阶段只改 UI 展示层,不修改后端接口、任务队列、Provider、成本统计、登录鉴权和业务流程。
|
||
|
||
修改文件:
|
||
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run typecheck -w user-app`
|
||
- `npm run build -w admin`
|
||
- `npm run build -w user-app`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后台 typecheck 通过。
|
||
- 用户端 typecheck 通过。
|
||
- 后台单独 build 通过。
|
||
- 用户端单独 build 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`153` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 本阶段为全局风格统一,未做逐页浏览器截图级微调;个别长表格、移动端密集表单和预览弹窗仍建议人工打开确认视觉密度。
|
||
|
||
下一步建议:
|
||
|
||
- 人工打开后台和用户端各跑一遍主流程,重点看移动端按钮换行、表格横向滚动、弹窗预览和长文本卡片是否需要精修。
|
||
|
||
### 成本优化策略硬落地
|
||
|
||
完成时间:2026-06-09 21:51:16 CST
|
||
|
||
完成内容:
|
||
|
||
- 真人动态视频镜头生成增加 Provider 子片段限制:真实/Provider 单次镜头按最多 10 秒拆分,超长镜头自动拆成多个 10 秒以内子片段后用 FFmpeg 拼接回一个镜头资产。
|
||
- 真人动态视频成本预估改为按 Provider 子片段计算,任务输入记录 `provider_clip_count` 和 `provider_clip_durations`,镜头任务完成后记录预估成本和实际成本。
|
||
- TTS 增加同用户私有缓存复用:同文本、同 voice、同 Provider code、同模型、同声音风格、同语速、同片段类型命中时,直接读取历史 `generated-audio-segments` 私有文件,不再调用 TTS Provider。
|
||
- 多角色/分段 TTS 已接入缓存与批量适配入口;普通旁白单段 TTS 也已接入同一套缓存元数据。
|
||
- ProviderService 新增 `executeProviderBatch` 批量适配层,当前支持统一批量入口和不支持原生批量时的逐条 fallback。
|
||
- 音频任务元数据新增 `audio_cache_key`、`cache_hit`、`cached_segments`、`generated_segments`,方便后台后续展示缓存命中和成本节省。
|
||
- 本阶段未调用任何真实 AI Provider,没有产生真实 AI 成本;未修改 `docs/` 目录。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- backend/src/providers/providers.service.ts
|
||
- backend/src/providers/providers.service.spec.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- media.service.spec.ts providers.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- 目标单测通过:`media.service.spec.ts` 和 `providers.service.spec.ts` 共 `42` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `22` 个测试文件、`155` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- `executeProviderBatch` 当前已实现批量入口和顺序 fallback;具体真实 Provider 的原生合并请求能力还需要按平台 API 单独接驱动,不能默认把所有模型强行合并。
|
||
- TTS 缓存按同用户项目范围复用,暂不做全局跨用户缓存,避免私有内容和声音素材串用。
|
||
- 真人视频镜头拆分依赖 FFmpeg 拼接;生产机需要保证 FFmpeg 可用。
|
||
|
||
下一步建议:
|
||
|
||
- 把后台任务/成本页面补一个“缓存命中 / 拆分片段 / 预估节省”展示,让运营能直观看到哪些镜头或 TTS 片段省了钱。
|
||
- 选择一个真实 TTS Provider 和一个真实视频 Provider 做小样,把平台原生批量/异步批量能力接到 `executeProviderBatch` 的 native 分支。
|
||
|
||
### AI Router V1 / 镜头评分 / 自动选模型
|
||
|
||
完成时间:2026-06-09 22:21:32 CST
|
||
|
||
完成内容:
|
||
|
||
- `storyboard_shots` 新增镜头路由字段:`scene_type`、`importance_score`、`emotion_score`、`action_score`、`route_tier`。
|
||
- 新增 `AiRouterModule` / `AiRouterService`,支持按语言、任务类型、镜头评分、Provider 可用状态、预算和降级链自动选择视频 Provider。
|
||
- 新增默认 `ai.router.v1` 系统配置:中文普通真人视频镜头优先 `minimax_hailuo_23_fast`,高价值镜头优先 `kling-image-to-video`,降级链为 `kling -> hailuo -> jimeng -> mock`。
|
||
- Router 会自动给镜头打标签和评分:普通对话、情绪戏、动作戏、远景转场等会得到不同 `scene_type` 与分数。
|
||
- 真人短剧分镜准备阶段会写入镜头评分和 `route_tier`;历史镜头缺字段时也会在准备或生成时补齐。
|
||
- 真人视频片段生成在未传 `provider_code` 时自动走 Router,不再默认固定 mock;人工 `provider_code` override 仅允许 admin 角色用于测试。
|
||
- 视频片段任务 `input_json` 记录完整 `router_decision`,包含候选 Provider、降级原因、评分、route tier、预估成本和最终 provider。
|
||
- 用户端真人视频 Provider 默认改为“自动路由”,生成/估算时不再强制传 `mock-video`;仍保留下拉供后续管理员/调试场景使用。
|
||
- 本阶段未调用任何真实 AI Provider,没有产生真实 AI 成本;未修改 `docs/` 目录。
|
||
|
||
修改文件:
|
||
|
||
- backend/prisma/schema.prisma
|
||
- backend/prisma/migrations/20260609220500_ai_router_v1_shot_scores/migration.sql
|
||
- backend/prisma/seed.ts
|
||
- backend/src/ai-router/ai-router.module.ts
|
||
- backend/src/ai-router/ai-router.service.ts
|
||
- backend/src/ai-router/ai-router.service.spec.ts
|
||
- backend/src/ai-router/ai-router.types.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/live-action/live-action.module.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/live-action/live-action.service.spec.ts
|
||
- backend/src/live-action/live-action.types.ts
|
||
- backend/src/images/images.service.spec.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- backend/src/scripts/scripts.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/prisma/migrations/20260609220500_ai_router_v1_shot_scores/migration.sql
|
||
- backend/src/ai-router/ai-router.module.ts
|
||
- backend/src/ai-router/ai-router.service.ts
|
||
- backend/src/ai-router/ai-router.service.spec.ts
|
||
- backend/src/ai-router/ai-router.types.ts
|
||
- backend/src/live-action/live-action.service.spec.ts
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run prisma:generate -w backend`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- ai-router.service.spec.ts media.service.spec.ts images.service.spec.ts scripts.service.spec.ts`
|
||
- `npm test -w backend -- ai-router.service.spec.ts live-action.service.spec.ts`
|
||
- `npm run prisma:deploy -w backend`
|
||
- `set -a; . ./.env; set +a; npm run prisma:deploy -w backend`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Prisma Client 生成通过。
|
||
- 首次 `npm run prisma:deploy -w backend` 失败:Prisma CLI 未读取到 `DATABASE_URL`。
|
||
- 加载根目录 `.env` 后 `prisma migrate deploy` 成功,已应用 `20260609220500_ai_router_v1_shot_scores`。
|
||
- 后端单独 typecheck 通过。
|
||
- Router / media / images / scripts 目标单测通过:`33` 个测试通过。
|
||
- Router / live-action 集成目标单测通过:`5` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `24` 个测试文件、`160` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- Router V1 当前只接入真人视频片段 Provider 自动选择;文本、图片、TTS 的自动路由还未统一接入。
|
||
- Router 规则目前用 `SystemConfig` JSON 管理,后台还没有专门的可视化规则编辑器。
|
||
- 质量评分低于阈值后的“自动重试一次、再切换 Provider、再进人工”闭环还未做。
|
||
- 多语言仅预留 `language` 输入,尚未建立 story/episode/shot translation 表和多语言生产线。
|
||
|
||
下一步建议:
|
||
|
||
- 做“Router 质检闭环 V1”:`score < 80` 自动原 Provider 重试一次,再按 fallback 切换 Provider,第三次失败进入人工处理。
|
||
- 后台任务/成本页展示 `router_decision`:镜头评分、route tier、候选 Provider、降级原因和预估节省。
|
||
|
||
### Router 质检闭环 V1
|
||
|
||
完成时间:2026-06-09 23:15 CST
|
||
|
||
完成内容:
|
||
|
||
- 真人视频片段质检入口支持 `auto_repair`、`min_quality_score`、`confirm_real_video`、`max_cost_per_clip`。
|
||
- 默认质检阈值为 `80` 分;低于阈值时进入自动修复闭环。
|
||
- 首次低分:自动沿用当前 Provider 重新生成一次。
|
||
- 已重试仍低分:按 Router `fallback_chain` 切换下一个可用 Provider。
|
||
- 自动修复超过上限、无可用 fallback、或真实/非 mock Provider 未确认费用时,自动标记为 `manual_required`。
|
||
- 关闭自动修复时,只标记 `needs_retry`,不误进人工处理。
|
||
- 自动修复生成任务会把 `repair_context` 写入 `render_tasks.input_json`,包含源片段、修复动作、Provider、fallback chain、阈值和上一轮质检分数。
|
||
- 用户端点击“质检”默认开启自动修复,并根据返回结果提示“通过 / 同 Provider 重试 / 切换 Provider / 人工处理”。
|
||
- 单测覆盖:
|
||
- `score < 80` 后同 Provider 自动重试并通过。
|
||
- 已重试片段再次低分后切换到 fallback Provider 并通过。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/live-action/live-action.dto.ts
|
||
- backend/src/live-action/live-action.controller.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/live-action/live-action.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- live-action.service.spec.ts ai-router.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- Router / live-action 目标单测通过:`7` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `24` 个测试文件、`162` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- Router 质检闭环 V1 只覆盖真人视频片段;图片、TTS、字幕、整集成片质检还未纳入同一闭环。
|
||
- 人工处理队列目前通过 `quality_status=manual_required` 和 `video_status=quality_manual_required` 标记,后台尚未做专门的人工处理工作台。
|
||
- `repair_context` 已记录在任务输入里,但后台还未可视化展示每次修复链路和节省/新增成本。
|
||
|
||
下一步建议:
|
||
|
||
- 做“后台 Router/质检审计视图”:展示镜头评分、Provider 决策、fallback 链、修复次数、质检分数、人工处理原因和成本变化。
|
||
|
||
### 后台 Router / 质检审计视图
|
||
|
||
完成时间:2026-06-09 23:35 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增后台审计 API:`GET /api/admin/router-audits`。
|
||
- 审计 API 汇总真人视频片段、分镜评分、Provider 配置、生成任务 `router_decision`、`repair_context` 和质检结果。
|
||
- 支持筛选:
|
||
- `project_id`
|
||
- `episode_id`
|
||
- `provider_code`
|
||
- `quality_status`
|
||
- `route_tier`
|
||
- `limit`
|
||
- API 返回统计摘要:
|
||
- 当前片段数
|
||
- 质检通过数
|
||
- 建议重试数
|
||
- 人工处理数
|
||
- 未质检数
|
||
- 低分数
|
||
- 自动修复数
|
||
- 切换 Provider 数
|
||
- 预估成本、实际成本、修复新增成本
|
||
- 平均质检分
|
||
- API 返回明细:
|
||
- 项目 / 分集 / 镜头信息
|
||
- `scene_type`、`importance_score`、`emotion_score`、`action_score`、`route_tier`
|
||
- 选中 Provider、Provider 模式、模型名
|
||
- Router 决策原因、候选 Provider 数、fallback chain、是否人工 override
|
||
- 质检状态、分数、人工处理原因
|
||
- 自动修复动作、来源片段、上一轮质检状态和分数
|
||
- 预估成本、实际成本、成本差额、修复新增成本
|
||
- 对应生成任务状态
|
||
- 后台新增导航页:“Router 审计”。
|
||
- 后台审计页新增统计卡、筛选工具条和明细表格。
|
||
- 后台审计页沿用深色运营台风格,并对大表格做横向滚动。
|
||
- 单测覆盖 Router 审计 API 能正确解析路由、fallback、修复动作、人工原因和成本差额。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- admin.service.spec.ts live-action.service.spec.ts ai-router.service.spec.ts`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- 后台单独 typecheck 通过。
|
||
- Admin / live-action / router 目标单测通过:`20` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `24` 个测试文件、`163` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- Router 审计当前是只读视图,还没有从审计页直接触发“重新质检 / 进入人工处理 / 指定 Provider 重试”等操作。
|
||
- 审计汇总基于当前查询列表,不是全库长期统计报表;后续如果要做日报/周报,需要单独做聚合表或分析接口。
|
||
- 当前只覆盖真人视频片段,图片、TTS、整集视频的 Router/质检审计还未纳入。
|
||
|
||
下一步建议:
|
||
|
||
- 做“Router 审计操作闭环”:在审计页对 `manual_required`、`needs_retry`、低分片段提供重新质检、指定 Provider 重试、确认人工通过/驳回等后台操作。
|
||
|
||
### Router 审计操作闭环
|
||
|
||
完成时间:2026-06-09 23:51 CST
|
||
|
||
完成内容:
|
||
|
||
- 后台 Router 审计页新增“审计操作参数”面板:
|
||
- 指定 Provider Code
|
||
- 单片段成本上限
|
||
- 是否允许真实/非 Mock Provider 付费修复或重试
|
||
- 人工原因
|
||
- 人工分数
|
||
- 审计明细每行新增操作:
|
||
- 重新质检
|
||
- 指定 Provider 重试
|
||
- 人工通过
|
||
- 人工驳回
|
||
- “重新质检”复用现有 `POST /api/live-action/video-clips/:clipId/quality-check`:
|
||
- 默认 `auto_repair=true`
|
||
- 默认阈值 `80`
|
||
- 只有勾选确认后才允许真实/非 Mock Provider 自动修复。
|
||
- “指定 Provider 重试”复用现有 `POST /api/live-action/video-clips/:clipId/retry`:
|
||
- 使用后台填写的 Provider Code。
|
||
- 支持单片段成本上限。
|
||
- 真实/非 Mock Provider 会二次确认,并仍受后端确认和成本阈值保护。
|
||
- 新增后台人工质检接口:`PATCH /api/admin/router-audits/video-clips/:clipId/quality`。
|
||
- 人工质检接口支持:
|
||
- `passed`
|
||
- `rejected`
|
||
- `manual_required`
|
||
- `needs_retry`
|
||
- 人工通过会把低分片段提升到至少 `80` 分,避免仍被统计为低分。
|
||
- 人工通过/驳回会同步更新 `storyboard_shots.video_status`:
|
||
- `quality_passed`
|
||
- `quality_rejected`
|
||
- `quality_needs_retry`
|
||
- `quality_manual_required`
|
||
- 人工通过/驳回会写入 `operation_logs`:
|
||
- 操作人
|
||
- 原质检状态
|
||
- 新质检状态
|
||
- 原分数
|
||
- 新分数
|
||
- 项目、分集、镜头、片段 ID
|
||
- 人工原因
|
||
- 权限策略:
|
||
- 重新质检 / 指定重试:`tasks:write`
|
||
- 人工通过 / 人工驳回:`reviews:write`
|
||
- 审计员和财务角色保持只读。
|
||
- 单测覆盖人工通过写入 video_clip、storyboardShot 和 operation_log。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w admin`
|
||
- `npm test -w backend -- admin.service.spec.ts live-action.service.spec.ts ai-router.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- 后台单独 typecheck 通过。
|
||
- Admin / live-action / router 目标单测通过:`21` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:后端 `24` 个测试文件、`164` 个测试通过;workers `1` 个测试通过;admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 重新质检和指定重试目前是同步接口;如果未来真实视频生成耗时很长,需要把这两个动作改成后台队列任务。
|
||
- 人工通过/驳回只覆盖真人视频片段;图片、TTS、整集视频还没有统一人工质量操作入口。
|
||
- Router 审计页还没有展示操作日志时间线;目前操作日志已写入,可在审计日志页查。
|
||
|
||
下一步建议:
|
||
|
||
- 做“Router 审计时间线 / 操作历史”:在审计页展开单个片段,显示每次质检、重试、Provider 切换、人工处理、成本变化的完整时间线。
|
||
|
||
### Router 审计时间线 / 操作历史
|
||
|
||
完成时间:2026-06-10 00:07 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增后台 Router 片段时间线接口:`GET /api/admin/router-audits/video-clips/:clipId/timeline`。
|
||
- 时间线接口聚合现有数据,不新增表、不改 Prisma schema:
|
||
- 当前片段审计行
|
||
- 同镜头相关 `video_clips`
|
||
- 相关 `render_tasks`
|
||
- 相关 `provider_logs`
|
||
- 相关 `operation_logs`
|
||
- 时间线事件覆盖:
|
||
- Router 自动选模型
|
||
- 视频生成任务创建 / 完成
|
||
- Provider 生成调用
|
||
- 质检 Provider 调用
|
||
- 自动修复策略
|
||
- 片段生成记录
|
||
- 片段质检状态
|
||
- 后台人工质检处理
|
||
- 时间线摘要展示:
|
||
- 事件数量
|
||
- 相关片段数量
|
||
- 任务数量
|
||
- Provider 调用数量
|
||
- 人工操作数量
|
||
- Provider 成本
|
||
- 最新质检状态和分数
|
||
- 后台 Router 审计表每行新增“时间线”按钮。
|
||
- 新增右侧 Router 时间线抽屉:
|
||
- 顶部摘要卡片
|
||
- 事件链路
|
||
- 关联任务
|
||
- 人工操作
|
||
- 时间线节点显示:
|
||
- 事件类型
|
||
- 状态
|
||
- 时间
|
||
- Provider Code
|
||
- 任务 ID
|
||
- 片段 ID
|
||
- 成本
|
||
- 结构化详情 JSON
|
||
- 权限策略:沿用 Router 审计只读权限,仍要求 `admin:read`。
|
||
- 单测覆盖 Router 时间线聚合,验证路由、修复、Provider、质检、人工操作事件进入同一时间线。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- admin.service.spec.ts`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- 后台单独 typecheck 通过。
|
||
- `admin.service.spec.ts` 通过:`15` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`165` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 时间线目前按已有数据库记录聚合;重新质检 / 指定重试这类 live-action 操作本身还没有单独写 `operation_logs`,所以时间线主要通过任务、Provider 日志和片段状态体现。
|
||
- 质检 Provider 调用没有 `task_id`,当前通过 `purpose` / `clip_id` 文本匹配归属片段;后续可把质检也任务化,让链路更精确。
|
||
- 时间线目前是只读复盘;操作仍在表格行内完成。
|
||
|
||
下一步建议:
|
||
|
||
- 做“Router 操作日志增强”:给重新质检、指定 Provider 重试、自动修复触发点补充 `operation_logs`,让时间线能完整区分是谁、什么时候、为什么触发了每一次动作。
|
||
|
||
### Router 操作日志增强
|
||
|
||
完成时间:2026-06-10 00:40 CST
|
||
|
||
完成内容:
|
||
|
||
- 给后台重新质检入口补充 `operation_logs`:
|
||
- action:`router_audit_quality_recheck`
|
||
- target:`video_clip`
|
||
- metadata 记录项目、分集、镜头、片段、是否自动修复、最低质检分、成本上限、是否确认真实 Provider、原质检状态、原质检分。
|
||
- 给指定 Provider 重试入口补充 `operation_logs`:
|
||
- action:`router_audit_manual_provider_retry`
|
||
- target:`video_clip`
|
||
- metadata 记录 Provider Code、成本上限、是否确认真实 Provider、原质检状态、原质检分、重试次数。
|
||
- 给低分后的自动修复触发点补充 `operation_logs`:
|
||
- action:`router_audit_auto_repair_triggered`
|
||
- target:源 `video_clip`
|
||
- metadata 记录修复动作、目标 Provider、触发原因、fallback 链、上一轮质检状态/分数、最低质检分、成本上限。
|
||
- 自动修复动作支持进入时间线:
|
||
- `retry_same_provider`
|
||
- `switch_provider`
|
||
- Admin 时间线标题增强:
|
||
- `router_audit_quality_recheck` 显示为“后台重新质检”
|
||
- `router_audit_manual_provider_retry` 显示为“后台指定 Provider 重试”
|
||
- `router_audit_auto_repair_triggered` 显示为“Router 自动修复触发”
|
||
- 后台中文标签同步补充上述三个 action。
|
||
- 现在 Router 时间线能完整看到:
|
||
- 谁触发了重新质检
|
||
- 谁指定 Provider 重试
|
||
- 系统为什么自动重试或切 Provider
|
||
- 每次动作对应的片段、Provider、成本阈值和质检阈值
|
||
- 单测补充:
|
||
- 指定 Provider 重试会写操作日志。
|
||
- 重新质检会写操作日志。
|
||
- 自动同平台重试会写操作日志。
|
||
- 自动切 Provider 会写操作日志。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/live-action/live-action.service.spec.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- admin/src/App.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- live-action.service.spec.ts admin.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- 目标单测通过:`live-action.service.spec.ts` + `admin.service.spec.ts` 共 `19` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`166` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 质检 Provider 调用仍然没有独立 `task_id`,时间线目前通过 `purpose` / `clip_id` 文本匹配归属片段。
|
||
- 重新质检、指定重试目前仍是同步接口;真实视频 Provider 耗时较长时,后续应改成队列任务。
|
||
- 自动修复日志记录的是触发点和原因;如果需要“修复完成/失败”的独立人工可读节点,后续可以在生成完成后再写一条结果日志。
|
||
|
||
下一步建议:
|
||
|
||
- 做“质检任务化 / Router 队列化”:把重新质检、自动修复、指定 Provider 重试改成后台任务,给每个质检和修复动作分配 `task_id`,让时间线从“可复盘”升级成“可恢复、可重跑、可追踪队列状态”。
|
||
|
||
### 质检任务化 / Router 队列化 V1
|
||
|
||
完成时间:2026-06-10 01:08 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增真人 Router 队列任务类型:
|
||
- `live_action_keyframe_generate`
|
||
- `live_action_video_clip_generate`
|
||
- `live_action_video_clip_retry`
|
||
- `live_action_video_clip_quality_check`
|
||
- `live_action_video_render`
|
||
- 队列映射补齐:
|
||
- 关键帧进入 `image_queue`
|
||
- 视频片段生成、指定重试、成片合成进入 `video_queue`
|
||
- 片段质检进入 `qc_queue`
|
||
- `QueuesService` 新增内部任务创建入口,支持业务服务创建 `render_tasks` 后直接进入队列。
|
||
- worker 执行链路支持分发真人 Router 业务任务:
|
||
- `live_action_video_clip_retry`
|
||
- `live_action_video_clip_quality_check`
|
||
- 后台“重新质检”改为创建质检队列任务,返回 `task_id` 与队列信息。
|
||
- 后台“指定 Provider 重试”改为创建视频队列任务,返回 `task_id` 与队列信息。
|
||
- 保留无队列注入时的同步 fallback,便于单测和极端场景兜底。
|
||
- 质检 Provider 调用补充 `task_id`,时间线可以更准确串联到对应质检任务。
|
||
- 自动修复触发日志补充父级质检 `task_id`,修复来源可以追溯。
|
||
- Router 审计 / 时间线任务查询补充新的真人队列任务类型。
|
||
- 后台提示文案更新为“任务已创建”,显示任务 ID 和队列名。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/queues/task.types.ts
|
||
- backend/src/queues/queues.module.ts
|
||
- backend/src/queues/queues.service.ts
|
||
- backend/src/queues/queues.service.spec.ts
|
||
- backend/src/live-action/live-action.module.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/live-action/live-action.service.spec.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- admin/src/App.vue
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- live-action.service.spec.ts queues.service.spec.ts admin.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- 目标单测通过:`live-action.service.spec.ts`、`queues.service.spec.ts`、`admin.service.spec.ts` 共 `29` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`167` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 自动修复目前仍在质检任务内部闭环执行;子级修复生成已记录 `repair_context` 和父级质检任务,但还没有拆成独立子任务树。
|
||
- `live_action_keyframe_generate`、`live_action_video_clip_generate`、`live_action_video_render` 已预置任务类型和队列映射,但本阶段只先把重新质检和指定 Provider 重试任务化。
|
||
- Redis 不可用时队列适配器会返回 `enqueued=false`,任务仍会落库;后续可在任务详情页提供重新入队操作。
|
||
|
||
下一步建议:
|
||
|
||
- 做“爆款诊断 / 拉片分析 V1”:把创作型产品里有价值的拆片、套路、角色关系、反转节奏沉淀成可复用数据,用来反哺 Story Bible、Prompt Library 和后续自动生成质量。
|
||
|
||
### 爆款诊断 / 拉片分析 V1
|
||
|
||
完成时间:2026-06-10 13:29 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增爆款拉片数据模型:
|
||
- `hit_analysis_cases`:爆款样本、来源平台、题材、指标、拉片文本、诊断结果。
|
||
- `hit_analysis_segments`:分段拆解,记录钩子、冲突、情绪、反转、视觉策略、Prompt 种子和镜头评分。
|
||
- `creative_patterns`:可复用题材套路 / 角色套路 / 视觉 Prompt / 集节奏模式库。
|
||
- 新增后台 API:
|
||
- `GET /api/admin/hit-analyses`
|
||
- `POST /api/admin/hit-analyses`
|
||
- `POST /api/admin/hit-analyses/:caseId/analyze`
|
||
- `POST /api/admin/hit-analyses/:caseId/patterns`
|
||
- `GET /api/admin/creative-patterns`
|
||
- 新增规则化诊断 V1:
|
||
- 按拉片文本自动切分 5-10 秒生产友好的段落。
|
||
- 基于本地关键词规则给出钩子、冲突、反转、情绪、视觉、生产复用评分。
|
||
- 输出 `key_takeaways`、`story_bible_seeds`、`character_archetypes`、`prompt_keywords`、`route_hints`。
|
||
- 不接真实 AI,不消耗 Provider 成本,后续可替换为 TextProvider/Router 驱动分析。
|
||
- 新增“沉淀模式”能力:
|
||
- 从已诊断样本生成 `opening_hook`、`reversal_loop`、`character_archetype`、`visual_prompt`、`episode_rhythm` 五类模式。
|
||
- 模式记录结构 JSON、Prompt 模板、负面 Prompt、标签和有效性评分。
|
||
- 后台新增“爆款诊断”菜单页:
|
||
- 录入拉片样本。
|
||
- 查看诊断分、核心维度分、拉片结论、分段拆解。
|
||
- 对样本重新诊断。
|
||
- 一键沉淀模式库。
|
||
- 查看可复用模式库。
|
||
- 操作日志补充:
|
||
- `admin_create_hit_analysis_case`
|
||
- `admin_analyze_hit_case`
|
||
- `admin_promote_hit_analysis_patterns`
|
||
- 已应用本地数据库 migration:`20260610011500_hit_analysis_v1`。
|
||
|
||
修改文件:
|
||
|
||
- backend/prisma/schema.prisma
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- backend/src/admin/admin.types.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/prisma/migrations/20260610011500_hit_analysis_v1/migration.sql
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run prisma:generate -w backend`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- admin.service.spec.ts`
|
||
- `npm run typecheck -w admin`
|
||
- `set -a; . ./.env; set +a; npm run prisma:deploy -w backend`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Prisma Client generate:通过。
|
||
- 本地数据库 migration deploy:通过,已应用 `20260610011500_hit_analysis_v1`。
|
||
- 后端单独 typecheck 通过。
|
||
- 后台单独 typecheck 通过。
|
||
- 目标单测通过:`admin.service.spec.ts` 共 `17` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`169` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 诊断 V1 是本地规则化分析,不调用真实 TextProvider;优点是稳定、零成本,缺点是语义理解不如真实模型。
|
||
- 模式库目前已入库并后台可见,但还没有自动接入 Story Bible / 分镜生成 / Prompt Library 的生成上下文。
|
||
- 目前不做竞品视频下载或自动转写,拉片文本需要人工粘贴;后续可接素材上传、ASR 或外部数据导入。
|
||
|
||
下一步建议:
|
||
|
||
- 做“Prompt Library / 题材套路库 / IP 设定宇宙前台化 V1”:把 `creative_patterns`、Story Bible、角色资产库串起来,让新项目创建和脚本/分镜生成能直接选择并复用这些生产资产。
|
||
|
||
### Prompt Library / 题材套路库 / IP 设定宇宙前台化 V1
|
||
|
||
完成时间:2026-06-10 13:45:05 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增项目与题材套路绑定表 `project_creative_patterns`,支持一个项目绑定多个 `creative_patterns`,并保留创建时的套路快照。
|
||
- 新增用户端 API:
|
||
- `GET /api/projects/creative-patterns/library`
|
||
- `GET /api/projects/:id/creative-patterns`
|
||
- `PATCH /api/projects/:id/creative-patterns`
|
||
- 新项目创建支持传入 `creative_pattern_ids`,创建后自动绑定已启用的模式库条目,并增加对应 `usage_count`。
|
||
- Story Bible 生成已接入项目绑定的题材套路:
|
||
- `selling_points` 增加题材套路库摘要。
|
||
- `tone` 增加已选套路风格。
|
||
- `world_summary` 增加套路 / Prompt 规则。
|
||
- `taboo_rules` 增加模式库负向禁区。
|
||
- 单集脚本生成已接入题材套路,脚本文本新增 `【题材套路库】` 区块,旁白也会吸收套路描述。
|
||
- 分镜生成与单镜头 Prompt 重生成已接入题材套路:
|
||
- 正向 Prompt 增加 `题材套路/视觉Prompt参考`。
|
||
- 负向 Prompt 增加 `题材套路禁区`。
|
||
- 开场镜头吸收 `opening_hook`,结尾镜头吸收 `episode_rhythm`。
|
||
- 用户端新建项目页新增“题材套路 / IP 设定宇宙”选择器,可从爆款诊断沉淀的模式库选择生产资产。
|
||
- 用户端项目工作台新增已绑定套路摘要,方便人工确认当前项目使用了哪些生产模式。
|
||
- 已应用本地数据库 migration:`20260610133500_project_creative_patterns_v1`。
|
||
|
||
修改文件:
|
||
|
||
- backend/prisma/schema.prisma
|
||
- backend/src/projects/project.dto.ts
|
||
- backend/src/projects/project.types.ts
|
||
- backend/src/projects/projects.controller.ts
|
||
- backend/src/projects/projects.service.ts
|
||
- backend/src/projects/projects.service.spec.ts
|
||
- backend/src/story-bibles/story-bibles.service.ts
|
||
- backend/src/story-bibles/story-bibles.service.spec.ts
|
||
- backend/src/scripts/scripts.service.ts
|
||
- backend/src/scripts/scripts.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/prisma/migrations/20260610133500_project_creative_patterns_v1/migration.sql
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run prisma:generate -w backend`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w user-app`
|
||
- `npm test -w backend -- projects.service.spec.ts story-bibles.service.spec.ts scripts.service.spec.ts`
|
||
- `bash -lc 'set -a; source .env; set +a; npm run prisma:deploy -w backend'`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Prisma Client generate:通过。
|
||
- 本地数据库 migration deploy:通过,已应用 `20260610133500_project_creative_patterns_v1`。
|
||
- 后端单独 typecheck 通过。
|
||
- 用户端单独 typecheck 通过。
|
||
- 目标单测通过:`projects.service.spec.ts`、`story-bibles.service.spec.ts`、`scripts.service.spec.ts` 共 `22` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`173` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 现有项目可以通过 API 更新绑定,但用户端当前只在“新建项目”阶段提供选择器;已有项目的可视化编辑入口建议下一阶段补。
|
||
- 模式库来源仍依赖后台“爆款诊断 / 沉淀模式”,用户端暂不创建新模式,避免普通用户污染生产资产库。
|
||
- 当前是本地规则化生成链路吸收题材套路;后续接真实 TextProvider 时,需要把这些模式作为 Provider Prompt 上下文继续传递。
|
||
|
||
下一步建议:
|
||
|
||
- 做“模式库运营闭环 V1”:后台支持模式编辑、上架/停用、项目效果回流、使用次数和 ROI 统计;用户端补已有项目的模式调整入口,但要限制普通用户只能选择已审核上架的模式。
|
||
|
||
### 模式库运营闭环 V1
|
||
|
||
完成时间:2026-06-10 14:05:33 CST
|
||
|
||
完成内容:
|
||
|
||
- 后台模式库从“只读列表”升级为“可运营资产”:
|
||
- 支持编辑模式类型、标题、题材、语言、描述、Prompt 模板、负向 Prompt、标签、结构 JSON、效果分和状态。
|
||
- 支持模式上架、停用、归档。
|
||
- 支持从项目效果数据回流并重算 `effectiveness_score`。
|
||
- 新增后台 API:
|
||
- `PATCH /api/admin/creative-patterns/:patternId`
|
||
- `PATCH /api/admin/creative-patterns/:patternId/status`
|
||
- `POST /api/admin/creative-patterns/:patternId/refresh-metrics`
|
||
- `GET /api/admin/creative-patterns` 现在返回每条模式的运营指标:
|
||
- 绑定项目数、完成项目数、活跃项目数。
|
||
- 视频产物数、Provider 日志数、任务数、analytics 事件数。
|
||
- 成本、收入估算、ROI 估算。
|
||
- 平均质检分、平均完播率、播放数、点赞数。
|
||
- ROI / 效果回流 V1 统计口径:
|
||
- 成本优先取成功 `provider_logs.cost_actual`,没有 Provider 成本时用 `render_tasks` / `video_clips` 兜底。
|
||
- 收入估算取项目已支付订单金额,加上 `analytics_events.metric_json` 里的 `revenue` / `income` / `amount` / `gmv`。
|
||
- 播放、点赞、完播率从 `analytics_events.metric_json` 读取。
|
||
- 质量分从 `video_clips.quality_score` 读取。
|
||
- 效果分回流会按使用项目数、完成项目数、质量分、完播率、ROI、播放和点赞综合折算,不再只靠人工主观分。
|
||
- 新增操作日志:
|
||
- `admin_update_creative_pattern`
|
||
- `admin_update_creative_pattern_status`
|
||
- `admin_refresh_creative_pattern_metrics`
|
||
- 后台“爆款诊断 / 拉片分析”页的模式库区域新增:
|
||
- 模式库汇总指标卡。
|
||
- 模式编辑表单。
|
||
- 选中模式指标侧栏。
|
||
- 表格 ROI / 成本 / 播放 / 完播展示。
|
||
- 每行“编辑”“回流”操作。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/admin/admin.controller.ts
|
||
- backend/src/admin/admin.dto.ts
|
||
- backend/src/admin/admin.service.ts
|
||
- backend/src/admin/admin.service.spec.ts
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm test -w backend -- admin.service.spec.ts`
|
||
- `npm run typecheck -w admin`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- 后台单独 typecheck 通过。
|
||
- 目标单测通过:`admin.service.spec.ts` 共 `20` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`176` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 本阶段没有新增长期效果快照表,模式 ROI 是按当前项目绑定和现有日志动态计算;后续如果 analytics 事件量很大,应单独做日级汇总表。
|
||
- 收入估算依赖订单和 `analytics_events.metric_json`,真实发布平台数据未接入前,ROI 仍是内部估算口径。
|
||
- 用户端已有项目的模式可视化调整入口仍未做,本阶段优先补后台运营闭环。
|
||
|
||
下一步建议:
|
||
|
||
- 做“已有项目模式调整 / 生成上下文重跑 V1”:用户端和后台都能给已有项目调整模式绑定,并选择是否重新生成 Story Bible、脚本或分镜,使模式库运营结果真正反哺存量项目。
|
||
|
||
### 真人视频小样预检 / 验收闭环 V1
|
||
|
||
完成时间:2026-06-10 17:06:26 CST
|
||
|
||
完成内容:
|
||
|
||
- 开发重心切回仿真人视频测试验收,模式库后续再验证。
|
||
- 新增真人视频生成前预检接口:
|
||
- `GET /api/episodes/:episodeId/live-action/video-clips/preflight`
|
||
- 预检报告不会生成视频、不消耗 Provider 成本,只读取项目、分镜、关键帧、Provider、Router 和成本配置。
|
||
- 预检报告输出:
|
||
- `ready`
|
||
- `next_step`
|
||
- `blockers`
|
||
- `warnings`
|
||
- `summary`
|
||
- `breakdown`
|
||
- 预检可提前发现:
|
||
- 未确认分镜。
|
||
- 未执行真人分镜改写。
|
||
- 缺关键帧。
|
||
- 真实视频 Provider 需要 PNG/JPG/WebP 关键帧,但当前仍是 mock SVG。
|
||
- 真实视频生成未勾选确认。
|
||
- Provider 不存在或未启用。
|
||
- 预估费用超过单片段上限。
|
||
- 超过 10 秒镜头会自动拆分成多个 5-10 秒子片段。
|
||
- 用户端 AI 真人短剧区域接入预检:
|
||
- 工作台刷新时自动加载预检报告。
|
||
- 原“估算”按钮升级为“预检”,同时刷新成本和预检。
|
||
- 生成视频片段前强制再跑一次预检,不通过则阻断生成并显示第一条原因。
|
||
- 页面展示预检状态、下一步、阻断/警告、Router 决策 Provider、拆片数量和预估成本。
|
||
- 预检保持和实际生成一致的判断口径:
|
||
- 非 `mock-video` Provider 或 real mode Provider 需要真实视频确认。
|
||
- 真实视频 Provider 必须使用 raster 关键帧。
|
||
- 普通用户选择 Provider 不会强制 override,预检会提示最终仍走 Router;管理员保留 override 用于测试。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/live-action/live-action.controller.ts
|
||
- backend/src/live-action/live-action.dto.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/live-action/live-action.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -w backend -- live-action.service.spec.ts`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w user-app`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- 用户端单独 typecheck 通过。
|
||
- 目标单测通过:`live-action.service.spec.ts` 共 `8` 个测试通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`179` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 当前预检已经覆盖真实视频开跑前的关键安全阀,但还没有做完整“一键跑 1 个镜头小样”的独立测试台。
|
||
- 用户端真实关键帧目前仍主要来自 mock SVG;要测试真实 Hailuo/Kling 等图生视频,需要先接入真实图片关键帧或上传 raster 关键帧。
|
||
- 后台 Router 审计已有质检/重试操作,但还没有把“预检报告”并入后台审计时间线。
|
||
|
||
下一步建议:
|
||
|
||
- 继续围绕仿真人视频做“小样测试台 V1”:后台或用户端选择 1 个镜头,执行预检 -> 生成关键帧/上传关键帧 -> 生成单片段 -> 质检 -> 预览 -> 人工通过/驳回,形成上线前真实 Provider 验收标准流程。
|
||
|
||
### 真人小样测试台 V1
|
||
|
||
完成时间:2026-06-10 17:26:53 CST
|
||
|
||
完成内容:
|
||
|
||
- 继续聚焦仿真人视频测试优化验收,暂不推进模式库后续验证。
|
||
- 后端新增按单个 shot 执行小样验收的能力:
|
||
- 预检接口支持 `shot_id`,可只返回当前测试镜头的 Router 决策、阻断原因、关键帧状态和成本。
|
||
- 新增绑定上传 raster 关键帧接口:`POST /api/episodes/:episodeId/live-action/shots/:shotId/keyframe`。
|
||
- 新增单镜头视频片段生成接口:`POST /api/episodes/:episodeId/live-action/shots/:shotId/video-clip/generate`。
|
||
- 新增人工验收接口:`POST /api/live-action/video-clips/:clipId/manual-review`。
|
||
- 单镜头生成复用现有 `generateSingleVideoClip`,不会产生一套和批量生成不同的逻辑。
|
||
- 单镜头生成前强制执行该 shot 的预检,不通过则按阻断码直接拒绝。
|
||
- 上传关键帧复用现有加密资产上传,再绑定到 shot:
|
||
- 只接受当前用户/管理员可访问资产。
|
||
- 只接受当前项目资产。
|
||
- 只接受 `image/png`、`image/jpeg`、`image/webp`。
|
||
- 绑定后清空该 shot 旧的 `video_clip_asset_id`,避免旧片段被误认为当前关键帧产物。
|
||
- 人工验收会写回:
|
||
- `video_clips.quality_status`
|
||
- `video_clips.quality_score`
|
||
- `video_clips.quality_issues`
|
||
- `storyboard_shots.video_status`
|
||
- `operation_logs`
|
||
- 用户端 AI 真人短剧区域新增“真人小样测试台”:
|
||
- 可选择一个真人镜头。
|
||
- 可单镜头预检。
|
||
- 可上传 PNG/JPG/WebP 关键帧并绑定到该镜头。
|
||
- 可只生成该镜头的小样视频。
|
||
- 可预览关键帧和小样视频。
|
||
- 可对当前小样执行质检。
|
||
- 可人工通过或驳回当前小样。
|
||
- 显示当前 shot 的重要度、情绪、动作评分、route tier、Provider、拆片数量和预计成本。
|
||
- 分集切换时同步刷新真人资源,避免小样测试台仍显示上一集的 shot/clip。
|
||
- 补充小样测试台样式,适配现有深色运营台风格和移动端单列布局。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/live-action/live-action.controller.ts
|
||
- backend/src/live-action/live-action.dto.ts
|
||
- backend/src/live-action/live-action.service.ts
|
||
- backend/src/live-action/live-action.service.spec.ts
|
||
- user-app/src/api/client.ts
|
||
- user-app/src/pages/index/index.vue
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -w backend -- live-action.service.spec.ts`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run typecheck -w user-app`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 目标单测通过:`live-action.service.spec.ts` 共 `12` 个测试通过。
|
||
- 后端单独 typecheck 通过。
|
||
- 用户端单独 typecheck 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`183` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 真实 Hailuo/Kling 等 Provider 的账号、Key 和真实返回体还未接入,本阶段仍保持 mock-first 和可替换 Provider 架构。
|
||
- 上传关键帧目前通过用户端通用资产上传完成,后台端暂未新增独立小样测试页。
|
||
- 人工验收备注为当前小样级备注,后续可扩展为结构化问题标签:脸漂、手崩、口型、动作跳切、画质、违规等。
|
||
|
||
下一步建议:
|
||
|
||
- 继续做“真人视频真实 Provider 小样验收脚本 V1”:用 1 个固定项目、1 个固定镜头、1 张真实 PNG/JPG 关键帧,按 Provider 分别跑 Hailuo/Kling/mock,记录首帧、片段、质检分、成本和失败原因,形成上线前 Provider 准入标准。
|
||
|
||
### 真人视频真实 Provider 小样验收脚本 V1
|
||
|
||
完成时间:2026-06-10 17:52:03 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增可重复执行的真人视频 Provider 小样验收脚本:
|
||
- `npm run live-action:acceptance -w backend`
|
||
- 根目录别名:`npm run live-action:acceptance`
|
||
- 脚本通过 Nest application context 调用现有服务,不绕过业务链路:
|
||
- `AssetsService`
|
||
- `LiveActionService`
|
||
- `ProvidersService`
|
||
- `PrismaService`
|
||
- 脚本输入固定项目、固定分集、固定镜头和真实 PNG/JPG/WebP 关键帧。
|
||
- 脚本会按 Provider 矩阵逐个执行:
|
||
- 单镜头预检。
|
||
- 可选上传并绑定 raster 关键帧。
|
||
- 单镜头视频片段生成。
|
||
- 即时质检。
|
||
- 成本、质量分、失败原因、输出资产记录。
|
||
- 默认 Provider 矩阵:
|
||
- `hailuo` -> `minimax_hailuo_23_fast`
|
||
- `kling` -> `kling-image-to-video`
|
||
- `mock` -> `mock-video`
|
||
- 脚本默认安全:
|
||
- 没有 `LIVE_ACTION_ACCEPTANCE_CONFIRM_REAL_VIDEO=true` 时,真实 Provider 只做预检并跳过生成。
|
||
- 真实 Provider 默认不自动启用,除非显式设置 `LIVE_ACTION_ACCEPTANCE_FORCE_ENABLE_PROVIDERS=true`。
|
||
- 真实生成仍会走现有 `confirm_real_video`、Provider enabled、raster keyframe、成本上限等保护。
|
||
- 关键帧上传细节:
|
||
- 上传使用项目 owner 身份,避免管理员上传后用户端无法预览私有素材。
|
||
- Provider override、验收和日志仍使用管理员身份。
|
||
- 脚本输出验收报告:
|
||
- JSON 报告。
|
||
- Markdown 报告。
|
||
- 默认路径:`storage/private/live-action-acceptance/YYYY-MM-DD/`
|
||
- 报告字段包含:
|
||
- Provider code / label。
|
||
- preflight ready / next step。
|
||
- blockers / warnings。
|
||
- clip id。
|
||
- output asset id。
|
||
- `/api/assets/:assetId/download` 预览下载路径。
|
||
- actual cost。
|
||
- quality status / score。
|
||
- repair action。
|
||
- error message。
|
||
- passed / failed / skipped 汇总。
|
||
- 支持失败门禁:
|
||
- `LIVE_ACTION_ACCEPTANCE_FAIL_ON_REJECT=true` 时,只要有 Provider 未通过,脚本退出码为 1,后续可接 CI 或上线前检查。
|
||
|
||
示例命令:
|
||
|
||
```bash
|
||
LIVE_ACTION_ACCEPTANCE_PROJECT_ID=123 \
|
||
LIVE_ACTION_ACCEPTANCE_EPISODE_ID=456 \
|
||
LIVE_ACTION_ACCEPTANCE_SHOT_ID=789 \
|
||
LIVE_ACTION_ACCEPTANCE_KEYFRAME_PATH=/www/wwwroot/ai/storage/test-keyframe.png \
|
||
LIVE_ACTION_ACCEPTANCE_PROVIDERS=hailuo,kling,mock \
|
||
LIVE_ACTION_ACCEPTANCE_CONFIRM_REAL_VIDEO=true \
|
||
LIVE_ACTION_ACCEPTANCE_MAX_COST_PER_CLIP=1 \
|
||
npm run live-action:acceptance -w backend
|
||
```
|
||
|
||
修改文件:
|
||
|
||
- package.json
|
||
- backend/package.json
|
||
- backend/src/live-action/live-action-provider-acceptance.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- backend/src/live-action/live-action-provider-acceptance.ts
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run live-action:acceptance -w backend`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单独 typecheck 通过。
|
||
- `npm run live-action:acceptance -w backend` 可正常拉起脚本,并在未传必填环境变量时安全失败:`LIVE_ACTION_ACCEPTANCE_PROJECT_ID is required`。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- 后端 `24` 个测试文件、`183` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 本阶段只实现验收脚本,不实际调用 Hailuo/Kling 付费接口;真实调用需要先在后台配置真实 Key、启用 Provider,并显式设置确认环境变量。
|
||
- 报告为文件型报告,后台端暂未做 Provider 准入报告列表页。
|
||
- 当前质量检查仍走 mock-qc;后续可接真实视觉 QA Provider,对脸部漂移、手部异常、动作跳切、口型等做更细评分。
|
||
|
||
下一步建议:
|
||
|
||
- 做“真人 Provider 准入报告后台化 V1”:后台读取 `storage/private/live-action-acceptance` 报告,按 Provider 展示质量分、成本、失败原因、输出视频预览,并标记“准入/禁用/待复测”。
|
||
|
||
### 前端 H5/PC 流程视觉验收与重叠修复 V1
|
||
|
||
完成时间:2026-06-10 18:34:37 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增 Playwright 视觉巡检脚本,覆盖用户端 PC/H5 与后台 PC/H5 的关键登录态页面。
|
||
- 用户端覆盖:新建、项目、制作、额度、审核、进度、成品、教程、我的。
|
||
- 后台覆盖:仪表盘、项目管理、任务管理、Router 审计、爆款诊断、AI 平台入口、AI 接入、成本日志、审计日志。
|
||
- 修复用户端 H5 NEXT 浮动提示遮挡/重叠问题:
|
||
- H5 端不再显示浮动 NEXT 提示,避免压住输入框、按钮和底部导航。
|
||
- PC 端保留浮动提示,并限制高度、字号和长文本省略。
|
||
- H5 顶部长项目标题字号下调,降低长标题换行造成的视觉压迫。
|
||
- 修复后台 AI 平台入口 PC 表格右侧状态列被裁切问题:
|
||
- 平台入口清单增加专用表格类。
|
||
- 宽屏下使用固定表格布局和列宽,内容允许换行。
|
||
- 巡检脚本支持识别合法的 line-clamp/ellipsis 省略,避免把正常省略号误报为 UI 溢出。
|
||
- 最终视觉报告生成在 `storage/private/frontend-visual-audit/report.json`,截图生成在 `storage/private/frontend-visual-audit/*.png`。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/styles.css
|
||
- admin/src/App.vue
|
||
- admin/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- tools/frontend-visual-audit.mjs
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npx -y playwright@1.49.1 --version`
|
||
- `npx -y playwright@1.49.1 install chromium`
|
||
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-visual-audit.mjs`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Playwright Chromium 安装成功,视觉巡检脚本可执行。
|
||
- 最终视觉巡检共覆盖 `36` 个页面步骤,汇总结果:
|
||
- 横向页面溢出:`0`
|
||
- 文本异常溢出:`0`
|
||
- 交互元素重叠:`0`
|
||
- console/page error:`0`
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- backend `24` 个测试文件、`183` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 本次是自动化视觉巡检 + 关键截图人工抽查,不等同于全部业务动作真实提交验收;真实流程仍建议按“创建项目 -> 生成 -> 任务队列 -> 预览/下载”逐条人工点一遍。
|
||
- Playwright 目前通过 `npx` 缓存路径配合 `NODE_PATH` 运行,尚未写入项目依赖或 npm script。
|
||
- H5 端关闭了浮动 NEXT 提示,后续如果要恢复,需要改成非固定布局或页面内提示,不能再用固定浮层压操作区。
|
||
|
||
下一步建议:
|
||
|
||
- 做“前端真实业务动作 E2E V1”:用 Playwright 不只截图,而是实际走创建项目、版权确认、生成 mock、查看任务、预览成品、后台审计的完整点击链路,并把失败点输出成报告。
|
||
|
||
### 前端真实业务动作 E2E V1
|
||
|
||
完成时间:2026-06-10 18:48:50 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增真实业务动作 E2E 脚本,覆盖“上传小说改编 -> mock 生成 -> 成品预览 -> 后台核查”的完整主链路。
|
||
- E2E 使用 Playwright 打开真实用户端和后台端页面,关键业务动作通过 UI 点击执行,API 仅用于登录、额度准备和结果断言。
|
||
- 用户端真实点击链路:
|
||
- 打开制作台。
|
||
- 新建“上传小说改编 / 图片漫剧版”项目。
|
||
- 准备 mock 支付额度。
|
||
- 粘贴小说正文。
|
||
- 版权确认。
|
||
- 解析小说。
|
||
- 生成并确认故事圣经。
|
||
- 抽取并确认角色库。
|
||
- 生成长篇记忆。
|
||
- 生成并确认分集计划。
|
||
- 生成并确认脚本。
|
||
- 生成并确认分镜。
|
||
- 生成分镜图。
|
||
- 生成多角色音频和字幕。
|
||
- 合成 MP4。
|
||
- 自动预览合成结果。
|
||
- 文本审核、视频审核。
|
||
- 成品页再次预览。
|
||
- 后台真实点击链路:
|
||
- 打开任务管理。
|
||
- 打开内容审核。
|
||
- 打开审计日志。
|
||
- E2E 产出 JSON 与 Markdown 报告,并保存关键截图。
|
||
- 最终通过样本:
|
||
- project_id:`48`
|
||
- episode_id:`34`
|
||
- video_asset_id:`272`
|
||
- 任务数:`13`
|
||
- 后台内容审核记录:`2`
|
||
- 失败任务:`0`
|
||
|
||
修改文件:
|
||
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- tools/frontend-business-e2e.mjs
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-business-e2e.mjs`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 最终 E2E 报告:
|
||
- `storage/private/frontend-business-e2e/report-20260610104646.json`
|
||
- `storage/private/frontend-business-e2e/report-20260610104646.md`
|
||
- `storage/private/frontend-business-e2e/latest-report.json`
|
||
- `storage/private/frontend-business-e2e/latest-report.md`
|
||
- 最终 E2E 汇总:
|
||
- 总步骤:`9`
|
||
- 通过步骤:`9`
|
||
- 失败步骤:`0`
|
||
- 失败数:`0`
|
||
- 截图数:`11`
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- backend `24` 个测试文件、`183` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- E2E 记录了一个非阻断 UI warning:`有 8 句 TTS 超出分配时长`。音频、字幕、视频仍生成成功,但说明当前 mock 剧本台词时长与镜头时长存在节奏不匹配,后续应优化脚本/分镜时长分配或 TTS 语速策略。
|
||
- 后台 `operation_logs` 对普通用户生成动作没有 project 维度日志,E2E 标记为 warning;当前后台仍能通过任务管理和内容审核查到本项目生成与审核结果。
|
||
- Playwright 仍通过 `npx` 缓存路径配合 `NODE_PATH` 运行,尚未写入项目依赖或 npm script。
|
||
|
||
下一步建议:
|
||
|
||
- 做“E2E 问题闭环 V1”:针对 TTS 超时 warning,优化脚本分镜生成约束,让每句台词预估时长不超过镜头时长;同时评估是否需要为普通用户关键生成动作补充 operation_logs 或生成流水线审计日志。
|
||
|
||
### PC 制作页额度余额遮挡修复 V1
|
||
|
||
完成时间:2026-06-10 18:53:40 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复用户端 PC 制作页额度余额卡片在双列布局下宽度不足导致的标题、额度信息和按钮挤压遮挡问题。
|
||
- 将 `.quota-inline` 在桌面制作页中设置为横跨整行,让“额度余额 / 可用 / 冻结 / 预估 / 状态 / 查看额度 / 冻结额度”有稳定展示空间。
|
||
- 为额度卡片单独补充标题换行、按钮对齐、720px 以上三列布局、1080px 以上桌面整行布局,保留 H5 纵向堆叠。
|
||
- 重新运行前端视觉巡检,PC/H5 用户端和后台端共 36 个页面状态均无页面溢出、文本溢出、交互元素重叠、控制台错误。
|
||
|
||
修改文件:
|
||
|
||
- user-app/src/styles.css
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-visual-audit.mjs`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 前端视觉巡检通过:
|
||
- 报告:`storage/private/frontend-visual-audit/report.json`
|
||
- PC 制作页截图:`storage/private/frontend-visual-audit/user-pc-studio.png`
|
||
- 36 个页面状态全部 `pageOverflow=0`、`textOverflow=0`、`overlaps=0`、`consoleErrors=0`
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- backend `24` 个测试文件、`183` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 本次只修复 PC 制作页额度卡片遮挡;此前 E2E 记录的 TTS 超时 warning 和普通用户生成动作缺少 project 维度 operation_logs 仍待后续阶段处理。
|
||
|
||
下一步建议:
|
||
|
||
- 继续围绕“仿真人视频完美落地”,优先处理真实业务 E2E 报告中的 TTS 节奏分配和生成流水线日志可追踪性。
|
||
|
||
### E2E 非阻断问题闭环 V1
|
||
|
||
完成时间:2026-06-10 20:27:28 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复真实业务 E2E 中的两个非阻断 warning:
|
||
- `8` 句 TTS 超出分配时长。
|
||
- 普通用户生成动作缺少 project 维度 `operation_logs`。
|
||
- TTS 节奏优化:
|
||
- mock VoiceProvider 生成的单句音频按当前片段 `target_duration` 参与时间轴,避免 mock Provider 粗略时长导致假阳性超时 warning。
|
||
- 真实 VoiceProvider 请求增加 `target_duration` 输入。
|
||
- 台词预估时长超过镜头分配时,自动写入建议 `speech_speed`,后续真实 Provider 可按语速约束生成。
|
||
- 保留原有 TTS 缓存策略:同文本 + 同音色 + 同 voice 配置复用;mock 缓存命中时按当前片段目标时长参与验收。
|
||
- 生成流水线日志补强:
|
||
- `audio_generate`、`subtitle_generate`、`video_render` 创建任务时写入 `target_type=project` 的 `operation_logs`。
|
||
- 日志 metadata 记录 `task_id`、`episode_id`、`shot_id`、`task_type`、`input_hash`,后台审计页可按项目查到普通用户生成动作。
|
||
- 新增/更新 MediaService 单元测试,覆盖 mock TTS 不再产生时间轴 warning、媒体任务创建写 project 维度操作日志。
|
||
- 重新 build 后端并重启 `127.0.0.1:3000` 后台服务,确保 E2E 跑到最新代码。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/media/media.service.ts
|
||
- backend/src/media/media.service.spec.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm --workspace backend run test -- src/media/media.service.spec.ts`
|
||
- `npm --workspace backend run build`
|
||
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-business-e2e.mjs`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
- `curl -fsS http://127.0.0.1:3000/api/client-config`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- `backend/src/media/media.service.spec.ts` 单测通过:`14` 个测试通过。
|
||
- 真实业务动作 E2E 通过:
|
||
- 报告:`storage/private/frontend-business-e2e/report-20260610122518.json`
|
||
- Markdown:`storage/private/frontend-business-e2e/report-20260610122518.md`
|
||
- project_id:`50`
|
||
- episode_id:`36`
|
||
- video_asset_id:`298`
|
||
- 总步骤:`9`
|
||
- 通过步骤:`9`
|
||
- 失败步骤:`0`
|
||
- warning:`0`
|
||
- user_task_count:`13`
|
||
- admin_task_count:`13`
|
||
- admin_review_count:`2`
|
||
- operation_log_count:`3`
|
||
- failed_tasks:`0`
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- backend `24` 个测试文件、`183` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- 后端服务已重启,`/api/client-config` 健康检查通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 当前闭环验证仍基于 mock Provider 和 FFmpeg 合成,真实 Hailuo / Kling / MiniMax 等 Provider 还需要小样准入验收。
|
||
- E2E 只验证主链路,不代表所有异常分支、任务恢复分支、真实 Provider 失败回退分支已经完全覆盖。
|
||
|
||
下一步建议:
|
||
|
||
- 回到“仿真人视频完美落地”主线,做真实 Provider 小样准入验收:固定项目、固定镜头、真实 PNG/JPG 关键帧,分别跑 Mock / Hailuo / Kling,记录画面、成本、质检分和失败原因,形成 Provider 准入标准。
|
||
|
||
### 真实 Provider 小样准入验收 V1
|
||
|
||
完成时间:2026-06-10 20:36:42 CST
|
||
|
||
完成内容:
|
||
|
||
- 进入“固定项目 / 固定镜头 / 真实 raster 关键帧 / Provider 矩阵”验收阶段。
|
||
- 选定固定样本:
|
||
- project_id:`36`
|
||
- episode_id:`28`
|
||
- shot_id:`134`
|
||
- 镜头:`雨夜病房惊醒`
|
||
- 时长:`4` 秒
|
||
- 原镜头关键帧是 mock SVG,不满足真实 Provider PNG/JPG/WebP 要求;本阶段上传并绑定真实 PNG 关键帧:
|
||
- keyframe_asset_id:`301`
|
||
- mime_type:`image/png`
|
||
- 来源文件:`storage/private/generated-images/2026-06-02/557d05bf-2b86-48d0-a427-f0171d7038ce.png`
|
||
- 执行 Provider 准入矩阵:
|
||
- `mock-video`
|
||
- `minimax_hailuo_23_fast`
|
||
- `kling-image-to-video`
|
||
- Mock Provider 实际生成单镜头小样:
|
||
- clip_id:`4`
|
||
- output_asset_id:`302`
|
||
- 视频:H.264 / 1080x1920 / 4 秒
|
||
- cost_actual:`0`
|
||
- quality_status:`passed`
|
||
- quality_score:`94`
|
||
- Hailuo / Kling 未调用外部接口,未产生真实成本;准入报告标记为 `skipped`:
|
||
- Hailuo:Provider 未启用、未显式确认真实视频费用、`MINIMAX_API_KEY` 未配置。
|
||
- Kling:Provider 未启用、未显式确认真实视频费用、`KLING_API_KEY` 未配置。
|
||
- 增强 `live-action-provider-acceptance` 验收脚本:
|
||
- 增加 Provider 准入预检字段:enabled、mode、api_key_env、api_key_configured。
|
||
- 未启用 / 缺 Key / 未确认真实费用时标记 `skipped`,避免和真实生成失败混淆。
|
||
- Markdown 表格增加 Enabled / Key 列。
|
||
- 默认报告目录改为项目根目录 `storage/private/live-action-acceptance`,从 backend workspace 执行时不再落到 `backend/storage`。
|
||
- 控制台摘要增加 enabled/key 状态。
|
||
|
||
修改文件:
|
||
|
||
- backend/src/live-action/live-action-provider-acceptance.ts
|
||
- CODEX_PROGRESS.md
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run live-action:acceptance`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
- `ffprobe -v error -show_entries stream=codec_type,codec_name,width,height,duration -show_entries format=duration,size -of json /www/wwwroot/ai/storage/private/live-action-video-clips/2026-06-10/33fcb7ed-75ac-4306-9735-89ca58d62b44.mp4`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Provider 准入报告:
|
||
- JSON:`storage/private/live-action-acceptance/2026-06-10/live-action-acceptance-project-36-episode-28-shot-134-20260610123444.json`
|
||
- Markdown:`storage/private/live-action-acceptance/2026-06-10/live-action-acceptance-project-36-episode-28-shot-134-20260610123444.md`
|
||
- 报告汇总:
|
||
- passed:`1`
|
||
- failed:`0`
|
||
- skipped:`2`
|
||
- Provider 结果:
|
||
- `mock-video`:passed,clip_id=`4`,output_asset_id=`302`,quality_score=`94`,cost_actual=`0`。
|
||
- `minimax_hailuo_23_fast`:skipped,未启用,`MINIMAX_API_KEY` 未配置,未确认真实费用。
|
||
- `kling-image-to-video`:skipped,未启用,`KLING_API_KEY` 未配置,未确认真实费用。
|
||
- 视频资产验证:
|
||
- asset_id:`302`
|
||
- mime_type:`video/mp4`
|
||
- codec:`h264`
|
||
- 分辨率:`1080x1920`
|
||
- duration:`4.000000`
|
||
- size:`11704`
|
||
- 提取首帧用于画面记录:
|
||
- `storage/private/live-action-acceptance/2026-06-10/frames/mock-clip-4-first-frame.png`
|
||
- 该首帧为 mock 占位画面,只验证流水线,不代表真实 Provider 画质。
|
||
- 后端单独 typecheck 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- backend `24` 个测试文件、`183` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- Hailuo / Kling 尚未真实生成,因为后台 Provider 仍是 disabled,且 `.env` 未配置 `MINIMAX_API_KEY` / `KLING_API_KEY`。
|
||
- 本轮 Mock 小样首帧是占位色块,只能证明“任务、关键帧、片段、质检、成本、报告”链路打通,不能作为真实画质判断。
|
||
- 当前质量检查仍是 mock-qc;真实 Provider 准入后,还需要引入真实视觉 QA 或人工小样评分标准。
|
||
|
||
下一步建议:
|
||
|
||
- 开通并配置 MiniMax Hailuo 账号后,只启用 `minimax_hailuo_23_fast`,设置 `MINIMAX_API_KEY`、单次成本上限和每日成本上限,再用同一个 `project_id=36 / episode_id=28 / shot_id=134 / keyframe_asset_id=301` 跑一次真实 Hailuo 小样;Kling 放在 Hailuo 通过后再对比。
|
||
|
||
### Live Action 白底风格修复 V1
|
||
|
||
完成时间:2026-06-10 20:50:15 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复用户端制作页 `Live Action / AI 真人短剧` 区块内部白底不匹配问题。
|
||
- 给真人短剧区域增加 `live-action-panel` 专属 class,避免依赖不存在的 `.app-dark` 选择器。
|
||
- 为真人视频预检框、小样测试台、小样卡片、预检 breakdown 增加深色运营台风格兜底。
|
||
- 修复 `强制重生成` checkbox 原生白色方块问题,统一成深色小控件,并覆盖通用 input padding 导致的尺寸撑大。
|
||
|
||
修改文件:
|
||
|
||
- `user-app/src/pages/index/index.vue`
|
||
- `user-app/src/styles.css`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `NODE_PATH=/root/.npm/_npx/f0a362733743bae2/node_modules node tools/frontend-visual-audit.mjs`
|
||
- 定点 Playwright 截图检查 Live Action 区块 PC/H5 背景色与 checkbox 尺寸
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 完整前端视觉巡检通过:
|
||
- 报告:`storage/private/frontend-visual-audit/report.json`
|
||
- 用户端 PC/H5 与后台 PC/H5 共 `36` 个页面状态全部为 `pageOverflow=0 / textOverflow=0 / overlaps=0 / consoleErrors=0`。
|
||
- Live Action 定点截图:
|
||
- PC:`storage/private/frontend-visual-audit/live-action-panel-pc.png`
|
||
- H5:`storage/private/frontend-visual-audit/live-action-panel-h5.png`
|
||
- 定点样式读取结果:
|
||
- `.live-action-panel .sample-panel` 背景为 `rgba(10, 19, 33, 0.78)`。
|
||
- `.live-action-panel input[type="checkbox"]` 背景为 `rgb(7, 20, 38)`,尺寸为 `18x18`,`padding=0px`。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- backend `24` 个测试文件、`183` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- Vite 仍输出 CJS Node API deprecation 提醒,不影响测试或构建产物。
|
||
|
||
遗留问题:
|
||
|
||
- 本轮只修复 Live Action 制作区白底/checkbox 风格问题,没有改动真人视频生成业务逻辑。
|
||
- Hailuo / Kling 真实 Provider 仍未启用,真实画质验收待 API Key 和费用确认后继续。
|
||
|
||
下一步建议:
|
||
|
||
- 继续围绕真人视频真实 Provider 小样验收,先启用 Hailuo 单 Provider 跑固定镜头,再和 Mock/Kling 做成本、画质、失败原因对比。
|
||
|
||
### MiniMax Hailuo 超时保存修复 V1
|
||
|
||
完成时间:2026-06-10 22:02:39 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复后台保存 MiniMax/Hailuo Provider 配置时报 `timeout_ms must be an integer between 1000 and 180000` 的问题。
|
||
- 原因是 Hailuo/Wan/Vidu/Seedance 等异步视频 Provider 默认需要 `300000ms` 级别长轮询超时,但通用 Provider 保存接口只允许到 `180000ms`。
|
||
- 将通用 Provider 运行配置保存上限放宽到 `600000ms`,OpenAI 统一配置的独立上限暂不改变。
|
||
- 新增单元测试覆盖 `minimax_hailuo_23_fast` 保存 `timeout_ms=300000` 的场景。
|
||
- 重新构建并用 systemd 临时服务 `ai-backend.service` 启动后端,使修复立即生效。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/providers/providers.service.ts`
|
||
- `backend/src/providers/providers.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run test -w backend -- src/providers/providers.service.spec.ts`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
- `systemd-run --unit=ai-backend ... node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- 后台 API 验证 `minimax_hailuo_23_fast` 保存 `timeout_ms=300000`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Provider 单测通过:`src/providers/providers.service.spec.ts`,`29` 个测试通过。
|
||
- 后端 `npm run typecheck -w backend` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- backend `24` 个测试文件、`184` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- 后端 `ai-backend.service` 状态为 `active`,`/api/health` 返回 `status=ok`。
|
||
- 实际接口验证通过:
|
||
- Provider:`minimax_hailuo_23_fast`
|
||
- 保存后 `timeout_ms=300000`
|
||
- `enabled=false`
|
||
- `key_status=none`
|
||
|
||
遗留问题:
|
||
|
||
- 本轮没有替用户保存 MiniMax API Key,也没有启用真实 Hailuo,避免误触发真实扣费。
|
||
- 用户需要重新在后台保存 MiniMax Key;保存成功后再手动启用 `minimax_hailuo_23_fast`。
|
||
|
||
下一步建议:
|
||
|
||
- 重新保存 MiniMax API Key,超时填 `300000`;第一轮只启用 `minimax_hailuo_23_fast`,单次成本上限 `1 USD`,当日上限 `10 USD`,先跑 1 个固定镜头小样。
|
||
|
||
### AI Provider 同公司 Key 同步与列表筛选 V1
|
||
|
||
完成时间:2026-06-10 22:20:56 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复 AI 接入体验问题:同一家公司同一个 API Key 不再需要在 Text / Novel / Image / Video / TTS 中反复保存。
|
||
- 后端 `updateProviderRuntimeConfig` 在保存新 `api_key` 时,默认按相同 `config_json.api_key_env` 同步密钥到其它真实 Provider。
|
||
- 同步只写入密钥,不自动启用其它 Provider,不修改优先级和成本阈值,避免误触发真实扣费。
|
||
- 后台单 Provider 配置表单新增“保存新 Key 时同步同公司接入”开关,并显示当前 Key 分组。
|
||
- 后台 AI 接入列表新增关键词、类型、密钥状态、启用状态筛选,增加 Key 分组列,减少长列表翻找成本。
|
||
- 新增单元测试覆盖保存 `deepseek-text` 时同步到 `deepseek-novel`,但不影响其它公司 Provider 的场景。
|
||
- 对当前数据库做了一次安全回填:复用已加密保存的 `minimax_hailuo_23_fast` Key,同步到 `minimax_hailuo_23`、`minimax-text`、`minimax-tts`;未启用这些 Provider。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/providers/provider.dto.ts`
|
||
- `backend/src/providers/providers.service.ts`
|
||
- `backend/src/providers/providers.service.spec.ts`
|
||
- `admin/src/App.vue`
|
||
- `admin/src/styles.css`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run test -w backend -- src/providers/providers.service.spec.ts`
|
||
- `npm run typecheck -w backend`
|
||
- `npm run lint`
|
||
- `npm run typecheck`
|
||
- `npm run test`
|
||
- `npm run build`
|
||
- `systemctl restart ai-backend.service`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- DeepSeek `/models` 轻量连接检查
|
||
- 当前 MiniMax 同分组加密 Key 回填检查
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Provider 单测通过:`src/providers/providers.service.spec.ts`,`30` 个测试通过。
|
||
- 后端 `npm run typecheck -w backend` 通过。
|
||
- 全项目 `npm run lint` 通过。
|
||
- 全项目 `npm run typecheck` 通过。
|
||
- 全项目 `npm run test` 通过:
|
||
- backend `24` 个测试文件、`185` 个测试通过。
|
||
- workers `1` 个测试通过。
|
||
- admin/user-app 当前无测试文件并以 `passWithNoTests` 通过。
|
||
- 全项目 `npm run build` 通过。
|
||
- 后端 `ai-backend.service` 重启成功,`/api/health` 返回 `status=ok`。
|
||
- DeepSeek 轻量连接检查通过:
|
||
- `deepseek-text`:Key 已保存,已启用,`/models=200`。
|
||
- `deepseek-novel`:Key 已保存,已启用,`/models=200`。
|
||
- MiniMax 当前 Key 状态:
|
||
- `minimax_hailuo_23_fast`:Key 已保存,已启用。
|
||
- `minimax_hailuo_23`:Key 已保存,未启用。
|
||
- `minimax-text`:Key 已保存,未启用。
|
||
- `minimax-tts`:Key 已保存,未启用。
|
||
|
||
遗留问题:
|
||
|
||
- MiniMax TTS/Text 和标准 Hailuo 只是补齐 Key,仍需按真实测试计划单独启用和限制成本阈值。
|
||
- 本轮没有触发任何真实生成任务,没有进行 Hailuo 视频扣费测试。
|
||
|
||
下一步建议:
|
||
|
||
- 后台人工刷新 AI 接入页,确认筛选、Key 分组和同步开关显示正常;然后进入真人视频固定镜头小样,只启用 `minimax_hailuo_23_fast` 先跑 1 条。
|
||
|
||
### AI 接入后受控验收测试 V1
|
||
|
||
完成时间:2026-06-10 23:06:00 CST
|
||
|
||
完成内容:
|
||
|
||
- 执行 DeepSeek 真实文本/小说小样测试,未触发真实视频生成。
|
||
- 执行一轮用户端 Mock 漫剧生产 API E2E:
|
||
- 注册测试用户。
|
||
- 创建 AI 原创项目。
|
||
- mock 支付标准包并冻结额度。
|
||
- 生成原创创意、大纲、章节、自检。
|
||
- 生成并确认故事圣经。
|
||
- 抽取并确认角色。
|
||
- 生成剧情记忆。
|
||
- 生成并确认分集计划。
|
||
- 生成并确认单集脚本。
|
||
- 生成并确认分镜。
|
||
- 生成角色锚点图与 10 张分镜图。
|
||
- 生成混合 TTS、字幕。
|
||
- 使用 FFmpeg 合成 1080x1920 MP4。
|
||
- 检查后台任务、Provider 日志、成本日志、项目详情、磁盘文件和 `ffprobe` 元数据。
|
||
- 本轮没有触发 Hailuo / Kling / Sora 等真实视频扣费。
|
||
|
||
测试对象:
|
||
|
||
- 测试用户:`codex-e2e-20260610150239@example.com`
|
||
- 项目 ID:`51`
|
||
- Episode ID:`37`
|
||
- Audio Asset ID:`314`
|
||
- Subtitle Asset ID:`315`
|
||
- Video Asset ID:`316`
|
||
- 视频文件:`local://rendered-videos/2026-06-10/c04807a9-99eb-4a9e-a847-e8f7ba3a6ad0.mp4`
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 本轮生成业务测试资产和私有存储文件,无新增代码文件。
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- 后台 Provider 状态检查脚本。
|
||
- DeepSeek Provider 小样测试脚本。
|
||
- 用户端 Mock 漫剧生产 E2E 脚本。
|
||
- 续跑音频/字幕/FFmpeg 视频合成脚本。
|
||
- Prisma 数据核验脚本。
|
||
- `ffprobe` 检查音频和视频文件。
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- `/api/health` 正常。
|
||
- DeepSeek Provider 小样通过:
|
||
- `deepseek-text` 真实调用成功。
|
||
- `deepseek-novel` 真实调用成功。
|
||
- Mock 生产流程最终通过:
|
||
- 项目状态:`video_rendered`
|
||
- 支付状态:`paid`
|
||
- 小说章节:`3`
|
||
- 角色:`3`
|
||
- 分镜:`10`
|
||
- 项目资产:`14`
|
||
- RenderTask:`14`,成功 `14`,失败 `0`
|
||
- ProviderLog:`23`
|
||
- Provider 成本:mock 图像和 mock 语音为 `0`
|
||
- FFmpeg 合成通过:
|
||
- 视频编码:`h264`
|
||
- 音频编码:`aac`
|
||
- 分辨率:`1080x1920`
|
||
- 时长:`40s`
|
||
- 文件大小:`239746 bytes`
|
||
- 文件存在性检查通过:
|
||
- 音频 WAV 存在。
|
||
- 字幕 SRT 存在。
|
||
- MP4 成片存在且可被 `ffprobe` 读取。
|
||
- Operation Logs:
|
||
- 已记录 `user_audio_generate`
|
||
- 已记录 `user_subtitle_generate`
|
||
- 已记录 `user_video_render`
|
||
|
||
发现问题:
|
||
|
||
- 第一次音频生成测试脚本使用 `max_segments=8` 时失败:实际混合 TTS 段数为 `12`,错误为 `audio segment count 12 exceeds max_segments 8`。
|
||
- 续跑时改为 `max_segments=20` 后音频生成通过,且 timeline warnings 为 `0`。
|
||
- 用户端当前没有传 `max_segments`,后端默认上限是 `80`,所以这不是现有用户端默认阻断问题;但测试台/高级参数不要再默认填 `8`。
|
||
- 普通用户早期流程如项目创建、故事圣经、角色、分镜生成的 operation_logs 还不是全量覆盖;当前关键生成动作已有日志,但审计完整性仍可增强。
|
||
|
||
遗留问题:
|
||
|
||
- 真实 Hailuo 小样尚未触发,仍需用户明确确认后单独跑 1 条固定镜头。
|
||
- 前端人工点击路径尚未在浏览器里逐屏复测;本轮是 API E2E 和文件级验收。
|
||
- TTS 测试脚本/高级配置中的 `max_segments=8` 对 10 镜头短剧偏低,后续测试建议不传或设置 `20` 以上。
|
||
|
||
下一步建议:
|
||
|
||
- 先把真实 Provider 小样脚本里的 TTS 参数规范化:混合配音不要写死 `max_segments=8`。
|
||
- 再做前端 PC/H5 人工点击复测,确认制作页、任务页、预览页展示不重叠。
|
||
- 最后进入真实 Hailuo 固定镜头小样准入测试。
|
||
|
||
## 每阶段记录模板
|
||
|
||
### 公版经典小说仿真人视频完整流程验收 V1
|
||
|
||
完成时间:2026-06-10 23:43 CST
|
||
|
||
完成内容:
|
||
|
||
- 选择公版经典《聊斋志异·画皮》作为测试题材,避开现代版权作品和受保护改编版本。
|
||
- 使用 imagegen 生成 photorealistic 竖屏关键帧,内容为雨夜旧宅、王生持灯、神秘女子立于门内。
|
||
- 通过系统正式服务跑通一条完整链路:
|
||
- 创建真人短剧项目
|
||
- 版权确认:`public_domain`
|
||
- 粘贴并解析公版测试片段
|
||
- 创建 Story Bible
|
||
- 创建角色:王生、神秘女子
|
||
- 创建 Actor Profile
|
||
- 创建分集、脚本、分镜
|
||
- 上传 photorealistic PNG 关键帧
|
||
- 绑定关键帧到分镜
|
||
- Hailuo Fast 真实图生视频
|
||
- 质检任务化
|
||
- 真人短剧最终合成
|
||
- 生成结果:
|
||
- project:`52`
|
||
- novel_source:`33`
|
||
- story_bible:`25`
|
||
- episode:`38`
|
||
- shot:`225`
|
||
- keyframe_asset:`318`
|
||
- video_clip:`8`
|
||
- Hailuo clip asset:`319`
|
||
- final rendered asset:`320`
|
||
- Hailuo provider log:`374`
|
||
- video task:`323`
|
||
- quality task:`324`
|
||
- render task:`325`
|
||
- 成本:
|
||
- Hailuo Fast 真实视频成本:`0.1902 USD`
|
||
- 质检 mock 成本:`0`
|
||
- 质量结果:
|
||
- clip `8`:`generated`
|
||
- quality_status:`passed`
|
||
- quality_score:`94`
|
||
- 文件级验收:
|
||
- 片段资产 `319`:`local://live-action-video-clips/2026-06-10/282b13ae-a03a-4063-ab13-da0b256417fc.mp4`
|
||
- 最终成片 `320`:`local://rendered-videos/2026-06-10/99244ee5-fc01-424e-850c-9620ef222302.mp4`
|
||
- 编码:`h264`
|
||
- 分辨率:`768x1364`
|
||
- 帧率:`24fps`
|
||
- 时长:`5.875s`
|
||
- 片段大小:`920552 bytes`
|
||
- 成片大小:`920592 bytes`
|
||
- 抽帧预览:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-10/classic-liaozhai-final-midframe.jpg`
|
||
- 画面可见真人古风雨夜场景,无黑屏、无水印、无明显跑题。
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增测试文件:
|
||
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-10/classic-liaozhai-keyframe.png`
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-10/classic-liaozhai-final-midframe.jpg`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- imagegen 生成关键帧
|
||
- Nest 服务脚本执行经典小说真人短剧流程
|
||
- `ffprobe` 检查 clip asset `319`
|
||
- `ffprobe` 检查 final asset `320`
|
||
- Prisma 数据核验脚本
|
||
- `ffmpeg` 抽取最终成片中帧
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端健康检查正常。
|
||
- 公版版权记录创建成功。
|
||
- 小说粘贴和解析成功,章节数 `1`。
|
||
- Hailuo Fast 真实视频生成成功。
|
||
- 质检任务化路径成功。
|
||
- 最终合成成功。
|
||
- 后台可通过素材 ID 观看:
|
||
- 关键帧:`318`
|
||
- Hailuo 片段:`319`
|
||
- 最终成片:`320`
|
||
|
||
遗留问题:
|
||
|
||
- 最终成片 asset `320` 的 `status` 当前为 `mock`,原因是 `renderLiveActionEpisode` 旧逻辑统一把合成资产写成 `mock`;实际源片段 `319` 是 Hailuo 真实输出。后续应根据源 clip 是否真实 Provider 输出,把最终资产状态写为 `active` 或增加 `source_mode` 字段。
|
||
- 最终成片没有音轨;本次测试重点是仿真人画面生成链路,不包含 TTS/对白/配乐合成。
|
||
- Hailuo 输出分辨率是 `768x1364`,不是系统元数据里常用的 `1080x1920`;后续正式合成阶段需要统一转码/补边/缩放到目标竖屏规格。
|
||
- 质检仍使用 `mock-qc`,真实画面质量最终仍需要视觉质检 Provider 或人工准入标准。
|
||
|
||
下一步建议:
|
||
|
||
- 修复真人合成资产状态:真实 Provider 片段合成出的最终 asset 不应标记为 `mock`。
|
||
- 增加真人成片转码规格化:统一输出 `1080x1920`、H.264、可选 AAC 音轨。
|
||
- 增加真人视频小样测试台:直接展示 keyframe、clip、final、Provider、真实成本、质检分和预览入口。
|
||
|
||
### Hailuo Fast 真人视频真实小样验收 V1
|
||
|
||
完成时间:2026-06-10 23:25 CST
|
||
|
||
完成内容:
|
||
|
||
- 按固定样本 `project_id=36 / episode_id=28 / shot_id=134 / keyframe_asset_id=301` 运行 MiniMax Hailuo 2.3 Fast 单镜头真实小样。
|
||
- 第一次真实调用失败原因已定位并可审计:MiniMax 返回 `base_resp_status_code=2013`,原因是 `MiniMax-Hailuo-2.3-Fast` 不支持 `4s`,只支持 `6s / 10s`。
|
||
- Provider 执行层新增外部 Provider 返回摘要:失败日志现在记录 `base_resp_status_code`、`base_resp_status_msg`、`task_id`、`file_id`、顶层字段列表等,不再只有泛化的 `TASK_ID_MISSING`。
|
||
- Hailuo Fast/标准 Provider 新增 `allowed_durations` 配置;通用图生视频驱动会把业务镜头时长自动归一到 Provider 支持档位。当前 4 秒镜头会按 Hailuo Fast 6 秒请求生成,后续合成阶段再裁切/对齐。
|
||
- 真人 Provider 验收脚本修复:现在能识别后台保存的加密 API Key,不再只检查 `.env` 环境变量。
|
||
- 真实 Hailuo Fast 第二次复测通过:
|
||
- clip:`7`
|
||
- output_asset:`317`
|
||
- 文件:`local://live-action-video-clips/2026-06-10/ddb89e25-4b51-4450-975f-9b5cf1ae2221.mp4`
|
||
- 真实成本记录:`0.1902 USD`
|
||
- 验收报告:`storage/private/live-action-acceptance/2026-06-10/live-action-acceptance-project-36-episode-28-shot-134-20260610152252.md`
|
||
- MP4 文件级检查通过:
|
||
- 编码:`h264`
|
||
- 分辨率:`768x1152`
|
||
- 帧率:`24fps`
|
||
- 时长:`5.875s`
|
||
- 文件大小:`1363391 bytes`
|
||
- 质检任务化路径跑通:
|
||
- quality task:`322`
|
||
- QualityCheckProvider:`mock-qc`
|
||
- clip `7` 质检结果:`passed`
|
||
- 质检分:`94`
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/providers/providers.service.ts`
|
||
- `backend/src/providers/provider.types.ts`
|
||
- `backend/src/providers/providers.service.spec.ts`
|
||
- `backend/src/live-action/live-action-provider-acceptance.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -- providers.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm test`
|
||
- `npm run lint`
|
||
- `npm run build`
|
||
- `systemctl restart ai-backend.service`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- `npm run live-action:acceptance`,仅跑 `minimax_hailuo_23_fast`
|
||
- `ffprobe` 检查 Hailuo 输出 MP4
|
||
- `ffmpeg` 抽取中帧预览图
|
||
- 质检队列任务脚本执行 clip `7`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端单测:`187 passed`
|
||
- 后端 lint/typecheck:通过。
|
||
- 后端 build:通过。
|
||
- 后端服务重启后 `/api/health` 正常。
|
||
- MiniMax Hailuo Fast 真实单镜头:通过,生成真实 MP4 并落库。
|
||
- 成本阈值生效:单片段成本 `0.1902 USD`,低于 `0.5 USD` 上限。
|
||
- Provider 失败审计增强有效:真实失败原因可以在 provider log 看到 `base_resp_status_msg`。
|
||
|
||
遗留问题:
|
||
|
||
- 当前关键帧 `301` 视觉上偏韩漫/插画,不是真人照片质感;本轮证明真实 Hailuo Provider 接入、任务、成本、落库、预览文件和质检路径跑通,但不能代表最终“仿真人照片级”画质验收。
|
||
- 业务镜头时长仍是 `4s`,Hailuo 实际输出 `~6s`;后续合成真人短剧时需要在 FFmpeg 拼接阶段裁切到业务时长,或在分镜层把真实视频镜头统一约束到 `6/10s` 档位。
|
||
- 质检仍使用 `mock-qc`,真实画面质量判断还需要后续接入视觉质检 Provider 或人工验收标准。
|
||
|
||
下一步建议:
|
||
|
||
- 上传或生成真正 photorealistic PNG/JPG 关键帧,再用同一套 Hailuo Fast 小样验收一次,重点看真人质感、脸部一致性、手部和动作。
|
||
- 在真人视频合成阶段补“Provider 输出时长 > 业务镜头时长时自动裁切”的 FFmpeg 规则。
|
||
- 后台小样测试台展示 Provider 支持时长档位、实际请求时长、业务裁切时长和真实成本,避免运营误以为 4 秒直接送给 Hailuo。
|
||
|
||
### 阶段名称
|
||
|
||
真人最终成片资产状态修复 V1
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-10 23:48:34 CST
|
||
|
||
完成内容:
|
||
|
||
- 修复真人短剧最终合成 MP4 资产状态写死为 `mock` 的问题。
|
||
- 新规则:合成前读取所有源片段资产;只要任一源片段资产为 `active`,最终成片资产状态就标记为 `active`,文件名使用 `live-action-real.mp4`;全部源片段都是 `mock` 时才保留 `mock`。
|
||
- `renderTask.input_json` 新增 `rendered_asset_status` 和 `rendered_asset_mode`,方便后续后台审计。
|
||
- 已将本次公版经典小样的最终成片 `asset 320` 从 `mock` 校正为 `active`;源片段 `asset 319` 保持 `active`。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -- live-action.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm test`
|
||
- `npm run lint`
|
||
- `npm run build`
|
||
- Prisma 脚本检查并更新 `asset 320`
|
||
- `systemctl restart ai-backend.service`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 真人模块单测:`14 passed`
|
||
- 后端全量测试:`189 passed`
|
||
- 后端 lint/typecheck:通过。
|
||
- 后端 build:通过。
|
||
- 后端健康检查:通过,`/api/health` 返回 `status: ok`。
|
||
- 数据校正后:`asset 319` 为 `active`,`asset 320` 为 `active`。
|
||
|
||
遗留问题:
|
||
|
||
- 旧数据里如果还有其它“真实源片段合成但最终资产误标 mock”的成片,需要按同样规则批量审计;本轮只修正了已确认的 `asset 320`。
|
||
|
||
下一步建议:
|
||
|
||
- 继续真人视频验收时,重点补 FFmpeg 裁切规则:真实 Provider 输出时长大于业务镜头时长时,合成前自动裁切到分镜目标时长。
|
||
|
||
### 阶段名称
|
||
|
||
真人视频片段时长标准化 / FFmpeg 自动裁切 V1
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-11 00:02:14 CST
|
||
|
||
完成内容:
|
||
|
||
- 真人短剧最终合成前新增片段标准化流程,不再直接把 Provider 原始 MP4 丢进 concat。
|
||
- 每个源片段会先通过 `ffprobe` 读取真实时长,再按分镜 `shot.duration` 判断是否需要裁切。
|
||
- 裁切规则:
|
||
- `source_duration > target_duration + 0.3s` 时自动裁切。
|
||
- 普通对话镜头默认居中裁切。
|
||
- 动作类镜头优先从头部保留,避免切掉关键动作起始。
|
||
- 标准化输出使用临时文件,不修改原始 Hailuo / Kling / Mock 资产。
|
||
- 标准化片段统一转为竖屏 `1080x1920`、`24fps`、H.264、`yuv420p`,降低不同 Provider 输出参数导致的拼接风险。
|
||
- `renderTask.input_json` 新增 `clip_normalization`,记录每个镜头的:
|
||
- `target_duration`
|
||
- `source_duration`
|
||
- `final_duration`
|
||
- `trimmed`
|
||
- `trim_strategy`
|
||
- `trim_start`
|
||
- `trim_tolerance`
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -- live-action.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm run lint`
|
||
- `npm run build`
|
||
- `npm test`
|
||
- 临时脚本调用真实 Hailuo 源片段 `asset 319` 做 4 秒标准化测试
|
||
- `systemctl restart ai-backend.service`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 真人模块单测:`14 passed`
|
||
- 后端全量测试:`189 passed`
|
||
- 后端 typecheck/lint:通过。
|
||
- 后端 build:通过。
|
||
- 后端健康检查:通过,`/api/health` 返回 `status: ok`。
|
||
- 临时真实文件验证:
|
||
- 源片段:`asset 319`
|
||
- 源时长:`5.875s`
|
||
- 模拟业务目标时长:`4s`
|
||
- 输出时长:`4.000s`
|
||
- 输出规格:`1080x1920`、`24fps`
|
||
- 裁切策略:`center`
|
||
- 裁切起点:`0.938s`
|
||
|
||
遗留问题:
|
||
|
||
- 当前 V1 只处理“源片段过长自动裁切”;如果源片段短于分镜目标时长,暂不做冻结帧/慢放/补帧延长。
|
||
- 真实小样 `shot 225` 目前分镜时长为 `6s`,Hailuo 输出 `5.875s`,不会触发裁切;本轮用同一个真实文件模拟了 `4s` 目标时长来验证裁切路径。
|
||
|
||
下一步建议:
|
||
|
||
- 后台 Router/任务审计页展示 `clip_normalization`,让运营能看到每个镜头是否被裁切、裁切前后时长和裁切策略。
|
||
- 后续如果要更细,可以增加“AI 最佳裁切点”或“动作峰值裁切”,但现在 V1 规则已经足够支撑生产验收。
|
||
|
||
### 阶段名称
|
||
|
||
后台 Router 审计展示合成裁切 V1
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-11 00:10:28 CST
|
||
|
||
完成内容:
|
||
|
||
- 后台 Router 审计列表新增“合成裁切”展示列。
|
||
- 后端 `listRouterAudits` 新增关联最终合成任务 `live_action_video_render`,从 `input_json.clip_normalization` 中提取当前镜头的标准化/裁切记录。
|
||
- 每条审计行新增 `render_normalization`,包含:
|
||
- `task_id`
|
||
- `output_asset_id`
|
||
- `shot_id`
|
||
- `target_duration`
|
||
- `source_duration`
|
||
- `final_duration`
|
||
- `trimmed`
|
||
- `trim_strategy`
|
||
- `trim_start`
|
||
- `trim_tolerance`
|
||
- Router 审计汇总新增:
|
||
- `normalized_clip_count`
|
||
- `trimmed_clip_count`
|
||
- `trimmed_seconds_total`
|
||
- Router 时间线新增 `clip_normalization` 事件,打开片段时间线可以看到“合成片段标准化 / 合成片段自动裁切”的详细 JSON。
|
||
- 前端 Router 审计页新增中文映射:`clip_normalization`、`trimmed`、`normalized`、`center`、`head`、`none`。
|
||
- 对经典小样第 38 集执行了一次只走 FFmpeg 的强制重新合成,不重新调用 Hailuo:
|
||
- 新最终成片 asset:`321`
|
||
- 新合成任务 task:`326`
|
||
- 标准化记录:源片段 `5.875s`,目标 `6s`,最终 `5.875s`,`trimmed=false`
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/admin/admin.service.ts`
|
||
- `backend/src/admin/admin.service.spec.ts`
|
||
- `admin/src/App.vue`
|
||
- `admin/src/styles.css`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -- admin.service.spec.ts`
|
||
- `npm run typecheck`
|
||
- `npm test`
|
||
- `npm run lint`
|
||
- `npm run build`
|
||
- `cd admin && npm run build`
|
||
- 服务层强制重新合成 episode `38`
|
||
- 后台服务层查询项目 `52` Router 审计
|
||
- `systemctl restart ai-backend.service`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端 Admin 单测:`20 passed`
|
||
- 后端全量测试:`189 passed`
|
||
- 后端 typecheck/lint/build:通过。
|
||
- 后台前端 build:通过。
|
||
- 后端健康检查:通过,`/api/health` 返回 `status: ok`。
|
||
- 真实数据验证:
|
||
- 项目 `52` Router 审计 summary 返回 `normalized_clip_count=1`、`trimmed_clip_count=0`
|
||
- 片段 `8` 返回 `render_normalization.task_id=326`、`output_asset_id=321`
|
||
|
||
遗留问题:
|
||
|
||
- 目前只有新合成任务会有 `clip_normalization`;旧合成任务不会回填。需要展示旧数据时,需要重新合成或做一次历史任务回填。
|
||
- 当前真实小样目标时长为 `6s`,源片段 `5.875s`,所以展示为“未裁切”。真正的“已裁切”展示已通过后端单测和临时真实文件测试覆盖。
|
||
|
||
下一步建议:
|
||
|
||
- 后台可以继续补一个“只重新合成/刷新裁切审计”的按钮,方便不重新生成 Provider 片段的情况下刷新最终成片与裁切记录。
|
||
|
||
### 阶段名称
|
||
|
||
全海螺 30 秒仿真人数字人跨屏样片验收 V1
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-11 00:44:23 CST
|
||
|
||
完成内容:
|
||
|
||
- 按“高价值镜头 / 宣传级样片 / Router Premium 验收样片”思路,完成一条 30 秒全 Hailuo 真人视频小样。
|
||
- 题材:深夜程序员桌面,仿真人 AI 数字女性从笔记本屏幕进入现实世界,并说“你终于找到我了”。
|
||
- 使用 imagegen 生成 5 张真实 PNG 关键帧,并复制到项目私有目录:
|
||
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-01-screen-appear.png`
|
||
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-02-touch-screen.png`
|
||
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-03-hand-through.png`
|
||
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-04-step-out.png`
|
||
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-keyframes/shot-05-real-world.png`
|
||
- 新建测试项目:
|
||
- project:`53`
|
||
- episode:`39`
|
||
- keyframe assets:`322-326`
|
||
- storyboard shots:`226-230`
|
||
- 全部 5 个镜头均使用 `minimax_hailuo_23_fast` 真实 Provider 生成:
|
||
- shot 1:clip `9`,asset `327`,成本 `0.1902 USD`
|
||
- shot 2:clip `10`,asset `328`,成本 `0.1902 USD`
|
||
- shot 3:clip `11`,asset `329`,成本 `0.1902 USD`
|
||
- shot 4:clip `12`,asset `330`,成本 `0.1902 USD`
|
||
- shot 5:clip `13`,asset `331`,成本 `0.1902 USD`
|
||
- 合成最终成片:
|
||
- final asset:`332`
|
||
- render task:`332`
|
||
- 文件:`local://rendered-videos/2026-06-10/4ddc1e08-d336-4fe3-93e9-7301079f99e5.mp4`
|
||
- 跑通 Router 审计:
|
||
- `total_estimated_cost=0.9510`
|
||
- `total_actual_cost=0.9510`
|
||
- `normalized_clip_count=5`
|
||
- `trimmed_clip_count=0`
|
||
- `avg_quality_score=94`
|
||
- 跑通质检记录:
|
||
- clips `9-13` 均为 `passed`
|
||
- 质检分均为 `94`
|
||
- 当前质检 Provider 为 `mock-qc`
|
||
- 抽帧验收文件:
|
||
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-frames/final-contact-sheet.jpg`
|
||
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-frames/final-midframe.jpg`
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
生成/新增数据:
|
||
|
||
- 数据库项目、故事圣经、分集、5 个镜头、5 个关键帧资产、5 个 Hailuo 视频片段、1 个最终成片资产。
|
||
- 私有关键帧 PNG 与抽帧 JPG。
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- Provider 配置检查脚本
|
||
- imagegen 生成关键帧
|
||
- Prisma 脚本创建项目/分镜/关键帧资产
|
||
- 服务层逐镜头调用 `generateShotVideoClip`
|
||
- 服务层调用 `renderLiveActionEpisode`
|
||
- `ffprobe` 检查最终 MP4
|
||
- `ffmpeg` 抽帧和生成 contact sheet
|
||
- 服务层调用 `checkVideoClipQuality`
|
||
- 后台服务层查询 Router 审计
|
||
- `npm test -- live-action.service.spec.ts`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Hailuo 真实生成:5/5 成功。
|
||
- Hailuo 真实成本:`0.9510 USD`。
|
||
- 最终 MP4 文件级检查:
|
||
- 编码:`h264`
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`24fps`
|
||
- 实际时长:`29.375s`
|
||
- 文件大小:`10241260 bytes`
|
||
- 5 个片段标准化记录正常:源时长均 `5.875s`,目标均 `6s`,未触发裁切。
|
||
- 后端真人模块单测:`14 passed`
|
||
- 后端健康检查:通过,`/api/health` 返回 `status: ok`。
|
||
|
||
人工视觉观察:
|
||
|
||
- 第 1-4 镜整体效果成立:屏幕中出现、触屏、手穿屏、从笔记本中出来的视觉逻辑清楚。
|
||
- 第 3/4 镜“跨屏”动作可读性不错,符合全海螺先做准入测试的目标。
|
||
- 第 5 镜出现轻微服装一致性变化,从高领科技服偏成白色连衣裙;这是全海螺复杂连续镜头的可见瑕疵,后续如果做宣传片级别,建议只重跑第 5 镜或等 Kling 开通后重跑第 3-5 镜。
|
||
|
||
遗留问题:
|
||
|
||
- 当前质检仍是 `mock-qc`,分数只能证明流程闭环,不等同于真实视觉质检。
|
||
- 第 5 镜服装一致性需要人工复核,必要时单独重跑。
|
||
- 最终成片实际时长 `29.375s`,业务记录为 `30s`,这是 Hailuo 6 秒档实际输出约 `5.875s` 导致,属于可接受范围;如要求严格 30 秒,后续可做尾帧补齐或轻微延长。
|
||
|
||
下一步建议:
|
||
|
||
- 人工打开后台预览 `asset 332`,重点看第 3-5 镜人物一致性和跨屏动作。
|
||
- 如果要做更接近宣传片的一版,保留第 1-4 镜,优先重跑第 5 镜;Kling 开通后再重跑第 3/4 镜做对照。
|
||
|
||
### 阶段名称
|
||
|
||
真人视频后期音频层修复 / 30 秒样片重新验收 V1
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-11 01:10:27 CST
|
||
|
||
完成内容:
|
||
|
||
- 将上一版 `asset 332` 按发布标准判定为失败:只有视频流,没有音频流、字幕和 BGM;第 5 镜嘴型也不能证明中文台词同步。
|
||
- 真人 `renderLiveActionEpisode` 增加后期层:
|
||
- 默认准备对白音频、字幕和 BGM。
|
||
- 新增 `live_action_audio_generate`、`live_action_subtitle_generate`、`live_action_bgm_generate` 三类任务。
|
||
- 从 `storyboard_shots.dialogue_text/narration_text` 直接生成真人小样对白段,不再强依赖已确认 `episode_script`。
|
||
- 最终 `live_action_video_render` 的 `input_json.post_production` 记录 audio/subtitle/bgm asset、task、Provider、warning。
|
||
- 真人 FFmpeg 合成升级:
|
||
- 先拼接 Hailuo 视频片段。
|
||
- 再混入 TTS 人声和 BGM。
|
||
- 再烧录 ASS 字幕。
|
||
- 输出 AAC 立体声音轨。
|
||
- BGM V1:
|
||
- 支持指定 `bgm_asset_id`。
|
||
- 未指定时生成版权安全的低音量氛围底音 `system_ambient_bed_v1`,用于测试和保底,不作为最终商业音乐库。
|
||
- Provider 修复:
|
||
- 修复 MiniMax TTS 返回 `data.audio` 十六进制音频串被误当 base64 解码的问题。
|
||
- `decodeProviderAudioPayload` 自动识别 hex/base64。
|
||
- 开启已有 Key 的 `minimax-tts` Provider:
|
||
- `provider_code=minimax-tts`
|
||
- `is_enabled=true`
|
||
- `priority=180`
|
||
- 重新合成 30 秒有声样片:
|
||
- audio asset:`333`
|
||
- subtitle asset:`334`
|
||
- bgm asset:`335`
|
||
- final video asset:`336`
|
||
- final render task:`337`
|
||
- 文件:`local://rendered-videos/2026-06-10/5b300243-c635-42d3-9d13-c0f73f449b87.mp4`
|
||
- 抽帧验收:
|
||
- `storage/private/live-action-acceptance/2026-06-11/dimensional-hailuo-frames/final-asset-336-subtitle-frame-25s.jpg`
|
||
- 25 秒帧已确认字幕“你终于找到我了。”烧录成功。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.dto.ts`
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `backend/src/providers/providers.service.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无源码新增文件。
|
||
|
||
生成/新增数据:
|
||
|
||
- `render_tasks`
|
||
- `334`:`live_action_audio_generate` 成功,真实 `minimax-tts`
|
||
- `335`:`live_action_subtitle_generate` 成功
|
||
- `336`:`live_action_bgm_generate` 成功
|
||
- `337`:`live_action_video_render` 成功
|
||
- `333`:修复前失败的 TTS 任务,保留为问题追踪记录
|
||
- `assets`
|
||
- `333`:真人对白混音 WAV
|
||
- `334`:SRT 字幕
|
||
- `335`:BGM WAV
|
||
- `336`:最终有声 MP4
|
||
- `provider_logs`
|
||
- `389`:`minimax-tts` 成功,`audio_available=true`,`audio_bytes=23674`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -- live-action.service.spec.ts`
|
||
- `npm test -- providers.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- MiniMax TTS debug 脚本
|
||
- `renderLiveActionEpisode` 重合成 episode `39`
|
||
- `ffprobe` 检查 `asset 336`
|
||
- `ffmpeg volumedetect` 检查音量
|
||
- `ffmpeg` 抽字幕帧
|
||
- Prisma 查询任务、素材、Provider 日志
|
||
- 重启后端 `node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端真人单测:`14 passed`
|
||
- Provider 单测:`32 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 build:通过
|
||
- 后端 lint:通过
|
||
- 后端已重启加载新 `dist`,健康检查通过
|
||
- `asset 336` 文件级验收:
|
||
- 容器:MP4
|
||
- 视频:H.264,`1080x1920`,`24fps`
|
||
- 音频:AAC LC,`44100 Hz`,stereo,`159 kb/s`
|
||
- format duration:`30.000s`
|
||
- audio duration:`30.000s`
|
||
- video stream duration:`29.375s`
|
||
- 文件大小:`11093467 bytes`
|
||
- 音量验收:
|
||
- `mean_volume=-16.0 dB`
|
||
- `max_volume=-1.0 dB`
|
||
- 不是静音文件。
|
||
- 字幕验收:
|
||
- 25 秒抽帧可见“你终于找到我了。”
|
||
- TTS 验收:
|
||
- `minimax-tts` 真实成功。
|
||
- 修复后音频字节头为合法 MP3 `ID3`。
|
||
|
||
分项验收结论:
|
||
|
||
- 真实 Hailuo 视频片段:通过,可跑通但第 5 镜服装一致性仍有瑕疵。
|
||
- 视频合成:通过,最终 MP4 可生成。
|
||
- 对白音轨:通过,已接真实 MiniMax TTS 并混入最终 MP4。
|
||
- BGM:流程通过,但当前是系统氛围底音 V1;商业发布前建议接入可运营的 BGM 素材库/上传授权库。
|
||
- 字幕:通过,已烧录进画面。
|
||
- 音量:通过,文件层面非静音,音量在可播放范围。
|
||
- 嘴型同步:不通过。当前第 5 镜只是 Hailuo prompt 生成的说话表情,不是由真实中文音频驱动的 lip-sync。
|
||
- 视觉质检:不通过生产级。当前 `mock-qc=94` 只能证明流程,不代表真实画面质检。
|
||
- 人工审核/发布:未验收。本阶段只到成片文件和后台任务链路。
|
||
|
||
遗留问题:
|
||
|
||
- 第 5 镜嘴型仍不是生产级中文口型。适合中景/轻微开口,不适合正脸近景强台词。
|
||
- BGM 还不是正式音乐库,只是版权安全氛围底音保底。
|
||
- 真实视觉 QA 仍未接入,`mock-qc` 不能作为发布依据。
|
||
- `provider_logs.cost_actual` 对 MiniMax TTS 仍为 `0`,因为当前按 `provider_usage_metadata` 记录,后续要按字符/供应商账单补精确成本。
|
||
- 修复前失败的 `live_action_audio_generate` task `333` 保留在任务表中,后台需要能清楚显示失败原因和后续成功任务。
|
||
|
||
下一步建议:
|
||
|
||
- 做“发布验收清单 V1”:后台成片页明确显示视频流、音频流、字幕、BGM、真实 TTS Provider、mock/real QA、lip-sync 风险。
|
||
- 做“台词镜头策略 V1”:正脸近景台词默认标记 `lip_sync_required`,没有 lip-sync Provider 时自动改成旁白/字幕/轻微开口中景,避免上线露馅。
|
||
- 做 BGM 素材库/授权库 V1:不要长期依赖系统氛围底音。
|
||
|
||
### 阶段名称
|
||
|
||
台词镜头策略 V1 / Lip-Sync 风险自动降级
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-11 09:30:12 CST
|
||
|
||
完成内容:
|
||
|
||
- 针对真人视频发布级风险补了台词镜头策略:正脸、近景、带台词、说话/开口类镜头会自动判定为 `lip_sync_required`。
|
||
- 不新增数据库字段,先用 Provider 配置和任务 `input_json` 落地策略,避免当前阶段频繁迁移核心表。
|
||
- 新增 lip-sync Provider 可用性判断:检测已启用的视频 Provider 配置中是否声明 `config_json.supports_lipsync=true`。
|
||
- 没有 lip-sync Provider 时,系统保留对白给后期 TTS 和字幕,但会自动把视频生成提示词降级为:
|
||
- 中景或三分之二侧脸;
|
||
- 轻微开口/自然表情;
|
||
- 避免正脸嘴部特写;
|
||
- 禁止生成清晰中文口型;
|
||
- 通过旁白、字幕、画面反应承接台词。
|
||
- `prepareLiveActionShots` 会在生成分镜 prompt 时写入 lip-sync 风险策略。
|
||
- `generateSingleVideoClip` 会对已有旧 prompt 动态补策略,避免旧项目重跑时漏掉降级规则。
|
||
- 真人视频片段生成任务、后期合成任务都会记录 `lip_sync_policy`,方便后续后台审计和发布验收。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无。
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -- live-action.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- 重启后端 `node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端真人单测:`15 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 build:通过
|
||
- 后端 lint:通过
|
||
- 后端已重启加载新 `dist`,健康检查通过
|
||
- 本阶段未额外重跑 Hailuo 真实视频,未新增真实视频费用。
|
||
|
||
分项验收结论:
|
||
|
||
- 台词镜头风险识别:通过。单测已覆盖近景台词镜头自动判定高风险。
|
||
- 无 lip-sync Provider 降级:通过。单测已确认 prompt 会写入 `post_tts_subtitle_light_mouth`、中景、侧脸、避免清晰口型等约束。
|
||
- 旧 prompt 动态补策略:通过。片段生成时会再次计算并注入策略。
|
||
- 任务审计记录:通过。render/post-production 任务 `input_json` 会记录 `lip_sync_policy`。
|
||
- 真实画面效果:未验收。本阶段只做策略和链路,不烧真实 Provider 额度。
|
||
|
||
遗留问题:
|
||
|
||
- 目前还没有真实 lip-sync Provider Adapter,系统只能自动降级风险镜头,不能做到真实中文口型驱动。
|
||
- 旧成片 `asset 336` 的画面不会自动改变,嘴型问题仍然存在;后续重新生成相关镜头才会套用新策略。
|
||
- 后台 Router/发布验收页还没有展示 `lip_sync_policy`,运营人员暂时需要查任务 JSON。
|
||
|
||
下一步建议:
|
||
|
||
- 重跑第 5 镜台词镜头,验证 Hailuo 在“中景轻口型 + TTS/字幕后期”策略下是否明显更稳。
|
||
- 做“发布验收清单 V1”:后台成片页展示音频、字幕、BGM、真实/Mock QA、lip-sync 风险和是否已降级。
|
||
- 后续接入真实 lip-sync Provider 后,把高风险正脸台词镜头路由到 lip-sync Provider。
|
||
|
||
### 阶段名称
|
||
|
||
真人第 5 镜台词镜头重跑验收 / Hailuo + 轻口型降级策略
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-11 12:04:06 CST
|
||
|
||
完成内容:
|
||
|
||
- 按台词镜头策略 V1,重跑项目 `53`、episode `39`、第 5 镜 `shot 230`。
|
||
- 本次只重跑 1 条 6 秒 Hailuo 真实视频,前 4 镜不重跑。
|
||
- Hailuo Provider 配置确认:
|
||
- `minimax_hailuo_23_fast` 已启用;
|
||
- `mode=real`;
|
||
- `supports_lipsync=false`;
|
||
- 已配置 `MINIMAX_API_KEY`;
|
||
- 单条 6 秒预估/记录成本 `0.1902 USD`。
|
||
- 新片段生成成功:
|
||
- `video_clip.id=14`
|
||
- `asset.id=337`
|
||
- 文件:`local://live-action-video-clips/2026-06-11/9f435b34-34a4-4f56-a0e6-ef8932ecffa9.mp4`
|
||
- 质量状态:`passed`
|
||
- mock 质检分:`94`
|
||
- 新片段任务 `338` 已记录 lip-sync 策略:
|
||
- `lip_sync_required=true`
|
||
- `high_risk_dialogue=true`
|
||
- `provider_available=false`
|
||
- `strategy=post_tts_subtitle_light_mouth`
|
||
- `visual_fallback=true`
|
||
- 新片段 prompt 已注入风险规避指令:
|
||
- 后期 TTS + 字幕承接对白;
|
||
- 不生成清晰中文口型;
|
||
- 嘴部保持闭合或轻微移动;
|
||
- 避免正脸嘴部特写;
|
||
- 优先中景、三分之二侧脸或反应镜头。
|
||
- 重新合成 30 秒成片,使用新第 5 镜片段:
|
||
- `asset.id=341`
|
||
- 文件:`local://rendered-videos/2026-06-11/74a7acdd-dbdc-4774-9cd0-a59985eec25c.mp4`
|
||
- 片段列表:`327, 328, 329, 330, 337`
|
||
- TTS asset:`338`
|
||
- 字幕 asset:`339`
|
||
- BGM asset:`340`
|
||
- render task:`342`
|
||
- 抽帧验收:
|
||
- 第 5 镜联系表:`storage/private/live-action-acceptance/2026-06-11/shot-230-rerun-frames/contact-sheet.jpg`
|
||
- 成片 25 秒字幕帧:`storage/private/live-action-acceptance/2026-06-11/asset-341-frames/subtitle-frame-25s.jpg`
|
||
- 成片 27 秒字幕帧:`storage/private/live-action-acceptance/2026-06-11/asset-341-frames/subtitle-frame-27s.jpg`
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无源码新增文件。
|
||
|
||
生成/新增数据:
|
||
|
||
- `video_clips`
|
||
- `14`:第 5 镜 Hailuo 真实重跑片段
|
||
- `assets`
|
||
- `337`:第 5 镜新 Hailuo 片段
|
||
- `338`:真人对白混音 WAV
|
||
- `339`:SRT 字幕
|
||
- `340`:BGM WAV
|
||
- `341`:重新合成后的 30 秒有声 MP4
|
||
- `render_tasks`
|
||
- `338`:`live_action_video_clip_generate` 成功
|
||
- `339`:`live_action_audio_generate` 成功
|
||
- `340`:`live_action_subtitle_generate` 成功
|
||
- `341`:`live_action_bgm_generate` 成功
|
||
- `342`:`live_action_video_render` 成功
|
||
- `provider_logs`
|
||
- `390`:`minimax_hailuo_23_fast` 成功,真实视频可用,成本 `0.1902`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- Prisma 查询 episode/shot/provider/clip/task
|
||
- `npm run live-action:acceptance`
|
||
- `ffprobe` 检查第 5 镜新片段
|
||
- `ffmpeg` 抽第 5 镜联系表
|
||
- Nest application context 调用 `renderLiveActionEpisode`
|
||
- `ffprobe` 检查最终成片 `asset 341`
|
||
- `ffmpeg volumedetect` 检查最终成片音量
|
||
- `ffmpeg` 抽 25 秒、27 秒字幕帧
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Hailuo 第 5 镜真实重跑:通过。
|
||
- Provider acceptance 报告:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-11/live-action-acceptance-project-53-episode-39-shot-230-20260611040048.json`
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-11/live-action-acceptance-project-53-episode-39-shot-230-20260611040048.md`
|
||
- 新片段 `asset 337`:
|
||
- 视频:H.264
|
||
- 分辨率:`768x1364`
|
||
- 帧率:`24fps`
|
||
- 时长:`5.875s`
|
||
- 文件大小:`545522 bytes`
|
||
- 无音轨,符合单镜头视频片段设计。
|
||
- 新成片 `asset 341`:
|
||
- 容器:MP4
|
||
- 视频:H.264,`1080x1920`,`24fps`
|
||
- 视频流时长:`29.375s`
|
||
- 音频:AAC LC,`44100 Hz`,stereo,`159 kb/s`
|
||
- 音频流时长:`30.000s`
|
||
- format duration:`30.000s`
|
||
- 文件大小:`10854047 bytes`
|
||
- 音量验收:
|
||
- `mean_volume=-15.8 dB`
|
||
- `max_volume=-1.0 dB`
|
||
- 非静音,音量在可播放范围。
|
||
- 字幕验收:
|
||
- 25 秒、27 秒抽帧均可见“你终于找到我了。”
|
||
- 后端健康检查:通过。
|
||
|
||
分项验收结论:
|
||
|
||
- 台词镜头降级策略:通过。任务 JSON 和 Provider prompt 均记录并执行了 `post_tts_subtitle_light_mouth`。
|
||
- 嘴型风险规避:阶段性通过。抽帧显示人物为中景/轻口型/表情反应,未出现明显正脸大幅口型对不上。
|
||
- TTS:通过。最终成片有真实 `minimax-tts` 音轨。
|
||
- 字幕:通过。字幕已烧录入最终成片。
|
||
- BGM:流程通过。仍是系统氛围底音 V1,不是正式音乐素材库。
|
||
- 合成:通过。最终 MP4 30 秒、有音轨、有字幕、有 BGM。
|
||
- 发布级结论:比上一版明显更接近可发布,但仍需人工完整播放审核;本阶段无法替代真实 lip-sync 供应商,也没有真实视觉 QA。
|
||
|
||
遗留问题:
|
||
|
||
- 第 5 镜并不是真正 lip-sync,只是通过中景、轻口型、字幕和 TTS 规避风险。
|
||
- Hailuo 返回片段为 `5.875s`,目标为 `6s`,在 `0.3s` 容差内没有裁切,最终 format 仍为 30 秒。
|
||
- BGM 仍需后续接入素材库/授权库,才能进入正式商用发布标准。
|
||
- `live_action_audio_generate.cost_actual` 仍为 `0`,MiniMax TTS 真实成本需要后续按字符或账单回填。
|
||
- mock 质检分 `94` 不能代表真实视觉 QA,仍需补真实画面审核能力。
|
||
|
||
下一步建议:
|
||
|
||
- 做“发布验收清单 V1”,把音轨、字幕、BGM、lip-sync 降级、mock/real QA、人工审核状态集中显示。
|
||
- 做“真人成片人工验收台 V1”,让后台能直接预览 `asset 341` 并人工通过/驳回。
|
||
- 接入正式 BGM 素材库/授权库,替代系统氛围底音。
|
||
|
||
### 阶段名称
|
||
|
||
真人成片音频噪声 / 台词时间轴修复 V1
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-11 12:14:22 CST
|
||
|
||
问题反馈:
|
||
|
||
- 用户验收 `asset 341` 后反馈:
|
||
- 成片里全是“呼呼”的噪音;
|
||
- 语音先到,说完后画面嘴型/表情才开始动。
|
||
|
||
原因分析:
|
||
|
||
- “呼呼声”不是 MiniMax TTS 的问题,也不是 Hailuo 视频的问题,而是系统兜底 BGM 问题:
|
||
- 旧 `system_ambient_bed_v1` 用 `anoisesrc=color=pink` 生成粉噪声氛围底音;
|
||
- 最终混音后又做整条 loudnorm,把背景噪声进一步抬高;
|
||
- 结果听感像风噪/底噪,不适合发布。
|
||
- “语音先到”不是单纯 AI 平台质量问题,而是当前流水线时间轴问题叠加无 lip-sync Provider:
|
||
- Hailuo 不是音频驱动 lip-sync;
|
||
- 旧策略把第 5 镜对白放在镜头开头 `24.55s`;
|
||
- 画面里的轻口型/表情动作出现在镜头中后段,导致听感错位。
|
||
|
||
完成内容:
|
||
|
||
- 系统兜底 BGM 从粉噪声改为静音保底:
|
||
- `bgm_source` 从 `system_ambient_bed_v1` 调整为 `system_silent_bed_v1`;
|
||
- 不再用粉噪声伪装 BGM;
|
||
- 正式发布用 BGM 后续必须接授权素材库/上传素材库。
|
||
- 混音策略修复:
|
||
- 默认 `LIVE_ACTION_DEFAULT_BGM_VOLUME` 从 `0.16` 降到 `0.08`;
|
||
- `bgm_volume` 参数现在真正参与混音;
|
||
- voice+BGM 混合后不再对整条音轨做 loudnorm,避免把背景噪声拉响;
|
||
- 混合后改用 `alimiter` 做安全限幅。
|
||
- 台词时间轴修复:
|
||
- `visual_fallback=true` 且是 dialogue 的镜头,TTS/字幕不再默认 `0.55s` 入声;
|
||
- 6 秒台词镜头会延后到约 `2.04s` 入声;
|
||
- 本次第 5 镜全片时间从旧 `24.55s` 延后到 `26.04s`。
|
||
- 新增单测:
|
||
- 验证无 lip-sync 的台词镜头会延后进声;
|
||
- 验证混音滤镜不会再把 BGM 通过整体 loudnorm 拉响。
|
||
- 重新合成新版 30 秒成片:
|
||
- `asset.id=345`
|
||
- 文件:`local://rendered-videos/2026-06-11/38a399bd-4550-4684-9855-0ae02e90e59c.mp4`
|
||
- 使用已有 Hailuo 视频片段,不再重跑 Hailuo。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无源码新增文件。
|
||
|
||
生成/新增数据:
|
||
|
||
- `assets`
|
||
- `342`:新版真人对白混音 WAV
|
||
- `343`:新版 SRT 字幕
|
||
- `344`:新版静音 BGM 保底 WAV
|
||
- `345`:新版最终成片 MP4
|
||
- `render_tasks`
|
||
- `343`:`live_action_audio_generate` 成功,台词 `start_seconds=26.04`
|
||
- `344`:`live_action_subtitle_generate` 成功,字幕 `start_seconds=26.04`
|
||
- `345`:`live_action_bgm_generate` 成功,`bgm_source=system_silent_bed_v1`
|
||
- `346`:`live_action_video_render` 成功,`bgm_volume=0`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -- live-action.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- Nest application context 调用 `renderLiveActionEpisode`
|
||
- `ffprobe` 检查新版成片
|
||
- `ffmpeg volumedetect` 检查新版音频
|
||
- `ffmpeg` 抽 25 秒、27 秒画面帧
|
||
- 重启后端 `node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端真人单测:`17 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 build:通过
|
||
- 后端 lint:通过
|
||
- 后端已重启,PID `4060680`,健康检查通过。
|
||
- 新版成片 `asset 345`:
|
||
- 容器:MP4
|
||
- 视频:H.264,`1080x1920`,`24fps`
|
||
- format duration:`30.000s`
|
||
- audio duration:`30.000s`
|
||
- 音频:AAC LC,`44100 Hz`,stereo
|
||
- 文件大小:`10291399 bytes`
|
||
- 新版音量:
|
||
- `mean_volume=-37.0 dB`
|
||
- `max_volume=-7.8 dB`
|
||
- 相比旧版 `mean_volume=-15.8 dB`,背景底噪已明显压下。
|
||
- 新版字幕/台词时间:
|
||
- 第 5 镜台词和字幕从 `26.04s` 开始;
|
||
- 旧版是 `24.55s`。
|
||
- 抽帧:
|
||
- `storage/private/live-action-acceptance/2026-06-11/asset-345-frames/frame-25s.jpg`
|
||
- `storage/private/live-action-acceptance/2026-06-11/asset-345-frames/frame-27s.jpg`
|
||
|
||
分项验收结论:
|
||
|
||
- 呼呼噪声:代码层面已修复。新版使用静音保底 BGM,且混音不再拉响背景。
|
||
- 语音抢跑:代码层面已修复。visual fallback 台词镜头会延后到镜头中后段。
|
||
- 真 lip-sync:仍未实现。当前方案是“规避嘴型风险”,不是音频驱动口型。
|
||
- BGM 发布标准:仍未完成。正式发布需要授权 BGM 素材库,不能依赖系统兜底音。
|
||
|
||
遗留问题:
|
||
|
||
- `asset 345` 是无正式 BGM 版本,只解决噪声和台词时间轴,不代表最终配乐发布标准。
|
||
- Hailuo 仍不是 lip-sync Provider;正脸强台词仍要接入真实 lip-sync 或改变镜头设计。
|
||
- 用户需要人工完整播放 `asset 345`,确认实际听感是否过关。
|
||
|
||
下一步建议:
|
||
|
||
- 后台增加“发布验收清单 V1”:显示是否有正式 BGM、是否静音保底、TTS 起止时间、lip-sync 策略、人工通过/驳回。
|
||
- 做 BGM 素材库/授权库 V1,支持上传可商用 BGM 并控制音量。
|
||
- 对正脸强台词镜头继续优先使用旁白/字幕/背影/反应镜头,直到接入真实 lip-sync Provider。
|
||
|
||
### 阶段名称
|
||
|
||
LipSyncProvider 接入 V1 / 真人后期口型同步 Provider 抽象
|
||
|
||
完成时间:
|
||
|
||
- 2026-06-11 13:44:28 CST
|
||
|
||
完成内容:
|
||
|
||
- 新增独立 Provider 类型:`LipSyncProvider`。
|
||
- 新增 mock Provider:
|
||
- `mock-lipsync`
|
||
- 默认禁用;
|
||
- 只用于测试链路;
|
||
- 明确标记 `mock_passthrough`,不伪装成真实口型同步能力。
|
||
- 新增真实通用 Provider 预设:
|
||
- `generic-lipsync`
|
||
- 默认禁用;
|
||
- driver:`configurable_lip_sync`
|
||
- 默认 env:`LIPSYNC_API_KEY`
|
||
- 默认请求字段:`video`、`audio`、`text`
|
||
- 支持 Provider 返回 `video_url` 或 `content_base64` 后落盘为私有视频片段。
|
||
- 真人视频 DTO 增加:
|
||
- `include_lip_sync`
|
||
- `lip_sync_provider_code`
|
||
- 真人后期链路新增 lip-sync 阶段:
|
||
- 位置:TTS 生成后、最终 FFmpeg 合成前;
|
||
- 输入:原视频片段 + 对应对白音频片段 + 台词文本 + 时间信息;
|
||
- 输出:新的 lip-sync 视频片段;
|
||
- 合成时优先使用 lip-sync 后的新片段。
|
||
- Provider 选择策略:
|
||
- 默认只自动使用已启用的真实 `LipSyncProvider`;
|
||
- mock 不会被当成生产可用能力;
|
||
- 后台/测试可显式指定 `lip_sync_provider_code=mock-lipsync` 验证链路。
|
||
- 审计记录:
|
||
- 新增任务类型 `live_action_lip_sync_generate`;
|
||
- `live_action_video_render.input_json.post_production` 记录 `lip_sync_clip_count` 和 `lip_sync_clips`;
|
||
- 每个 lip-sync clip 记录 source asset、output asset、task、provider、成本和策略。
|
||
- 安全处理:
|
||
- 视频/音频 data URI 只进入 Provider 调用;
|
||
- render task 不保存大 base64;
|
||
- provider logs 已走媒体字段脱敏。
|
||
- Provider 配置已落库:
|
||
- `71 LipSyncProvider:mock-lipsync enabled=false mode=mock`
|
||
- `72 LipSyncProvider:generic-lipsync enabled=false mode=real`
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.dto.ts`
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `backend/src/providers/provider.types.ts`
|
||
- `backend/src/providers/providers.service.ts`
|
||
- `backend/prisma/seed.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无。
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test -- live-action.service.spec.ts`
|
||
- `npm test -- providers.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- Prisma upsert `LipSyncProvider` 配置
|
||
- 重启后端 `node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
- Prisma 查询 `LipSyncProvider` 配置
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Provider 单测:`32 passed`
|
||
- 真人服务单测:`18 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 build:通过
|
||
- 后端 lint:通过
|
||
- 后端已重启,PID `31253`,健康检查通过。
|
||
- 数据库确认:
|
||
- `mock-lipsync` 已存在,默认禁用;
|
||
- `generic-lipsync` 已存在,默认禁用;
|
||
- 未写入任何真实 API Key。
|
||
|
||
分项验收结论:
|
||
|
||
- Provider 抽象:通过。`LipSyncProvider` 已成为独立能力类型。
|
||
- mock 链路:通过。单测已验证指定 `mock-lipsync` 时,会创建 `live_action_lip_sync_generate` 任务、调用 `LipSyncProvider`、保存新片段。
|
||
- 真实 Provider 预留:通过。`configurable_lip_sync` 支持通用 JSON 请求和 URL/base64 视频输出。
|
||
- 生产默认策略:通过。没有真实启用的 LipSyncProvider 时,不会误把 mock 当成可发布口型能力。
|
||
- 成本/审计:通过。任务和 Provider log 已能记录 lip-sync 调用。
|
||
|
||
遗留问题:
|
||
|
||
- 目前还没有开通真实 lip-sync 平台账号,`generic-lipsync` 只是通用适配器配置。
|
||
- 不同厂商可能要求 multipart/form-data、文件先上传或异步任务轮询;当前 V1 优先支持 JSON data URI + video_url/base64 输出。
|
||
- 后台 UI 还没有把 `LipSyncProvider` 单独分组展示,也没有发布验收页展示 `lip_sync_clips`。
|
||
- 尚未用真实 lip-sync Provider 重跑第 5 镜,所以真实口型效果还未验收。
|
||
|
||
下一步建议:
|
||
|
||
- 选定真实 lip-sync 平台后,按其 API 调整 `generic-lipsync` 的 `base_url/create_endpoint/video_field/audio_field/text_field`,填写 Key 后启用。
|
||
- 做后台“LipSyncProvider 配置/测试”入口,避免和普通 VideoProvider 混在一起。
|
||
- 用第 5 镜真实跑一次 lip-sync 小样,比较 `asset 345` 和 lip-sync 后版本的口型效果。
|
||
|
||
### 阶段名称
|
||
|
||
LipSync 成本闸门 V1 / 镜头级按需口型同步
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 14:14 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 明确落地“单镜头级 lip-sync,不做整片默认 lip-sync”的生产策略。
|
||
- `LiveActionGenerateDto` 新增 `lip_sync_max_seconds`,用于限制单集最多进入真实 lip-sync Provider 的秒数。
|
||
- 真人后期合成前新增 lip-sync 预算计划:
|
||
- 默认每集最多 `18s`;
|
||
- 上限硬限制 `120s`;
|
||
- 按 `route_tier`、`importance_score`、`action_score`、`emotion_score` 优先保留高价值镜头;
|
||
- 超出预算的高风险台词镜头自动降级为 `post_tts_subtitle_light_mouth`,不调用 lip-sync Provider。
|
||
- 实际 Provider 调用条件改为只处理 `lip_sync_strategy=provider_lipsync`,避免仅“需要口型同步但被预算跳过”的镜头误触发二次视频处理。
|
||
- 后期任务 `input_json.post_production` 增加:
|
||
- `lip_sync_budget`
|
||
- `lip_sync_policy.segments[].skip_reason`
|
||
- `lip_sync_skip_reason`
|
||
- 单测新增“两个高风险台词镜头只同步高价值镜头,普通镜头预算跳过并降级”的覆盖。
|
||
- 单测新增“显式关闭 lip-sync 时也走轻口型/字幕安全降级”的覆盖,避免关闭后仍按 `provider_lipsync` 排时序。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.dto.ts`
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无。
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test --workspace backend -- live-action.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- `npm test --workspace backend`
|
||
- 重启后端 `setsid -f node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 真人服务单测:`20 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 lint:通过
|
||
- 后端 build:通过
|
||
- 后端全量测试:`24 passed / 195 passed`
|
||
- 后端已重启,PID `94928`,健康检查通过。
|
||
|
||
遗留问题:
|
||
|
||
- 真实 lip-sync Provider 还没有开通并验收,当前只是把成本闸门和调用策略先做生产级保护。
|
||
- `lip_sync_max_seconds` 目前通过接口参数控制,后续后台可以做成项目级/单集级配置项。
|
||
- 后台审计页还未展示 `lip_sync_budget.skipped`,运营人员暂时需要查看任务 JSON。
|
||
|
||
下一步建议:
|
||
|
||
- 选一个真实 lip-sync 平台做小样准入,优先阿里 VideoRetalk。
|
||
- 后台增加 lip-sync 预算档位配置与审计展示:已同步秒数、跳过镜头、跳过原因、节省成本。
|
||
- 继续用第 5 镜或 30s 打破次元壁样片做真实 Provider 对比验收。
|
||
|
||
### 阶段名称
|
||
|
||
LipSync 多平台 Adapter V1 / 阿里 VideoRetalk 可执行接入
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 14:35 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 新增 `configurable_async_lip_sync` Provider 驱动,用于“提交任务 -> task_id 轮询 -> 下载结果视频”的 lip-sync 平台。
|
||
- 阿里云百炼 VideoRetalk 接入为可执行 Adapter:
|
||
- provider_code:`alibaba-videoretalk-lipsync`
|
||
- model:`videoretalk`
|
||
- base_url:`https://dashscope.aliyuncs.com`
|
||
- create_endpoint:`/api/v1/services/aigc/video-generation/video-retalk`
|
||
- task_endpoint_template:`/api/v1/tasks/{task_id}`
|
||
- 请求体:`model + input.video_url/audio_url/text`
|
||
- 请求头:`X-DashScope-Async: enable`
|
||
- 默认禁用。
|
||
- 新增默认禁用 lip-sync Provider 配置:
|
||
- `alibaba-videoretalk-lipsync`
|
||
- `heygen-lipsync`
|
||
- `sync-labs-lipsync`
|
||
- `fal-veed-lipsync`
|
||
- `volcengine-doubao-lipsync`
|
||
- `generic-lipsync`
|
||
- 豆包/火山 lip-sync 先接后台占位,默认禁用;当前未确认稳定“已有视频+音频口型替换”公开 API,不硬写不确定 endpoint。
|
||
- live-action 调用 lip-sync Provider 时,除了 data URI,也会传入已有公网 `video_url/audio_url`;阿里这类要求公网 URL 的平台在没有公网 URL 时会明确报错。
|
||
- Provider bootstrap 保留 `video_field`、`text_field`、`requires_public_urls`、`parameters_json` 等厂商字段,避免后台改完后被初始化覆盖。
|
||
- 数据库已 upsert 当前 `LipSyncProvider` 列表,全部保持 `is_enabled=false`,未写入任何真实 API Key。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/providers/provider.types.ts`
|
||
- `backend/src/providers/providers.service.ts`
|
||
- `backend/src/providers/providers.service.spec.ts`
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无。
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test --workspace backend -- providers.service.spec.ts`
|
||
- `npm test --workspace backend -- live-action.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- `npm test --workspace backend`
|
||
- Prisma upsert `LipSyncProvider` 配置
|
||
- Prisma 查询 `LipSyncProvider` 配置
|
||
- 重启后端 `setsid -f node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Provider 单测:`33 passed`
|
||
- 真人服务单测:`20 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 lint:通过
|
||
- 后端 build:通过
|
||
- 后端全量测试:`24 passed / 196 passed`
|
||
- 数据库确认:
|
||
- `mock-lipsync`:禁用
|
||
- `generic-lipsync`:禁用
|
||
- `alibaba-videoretalk-lipsync`:禁用,`0.08 CNY/s`
|
||
- `heygen-lipsync`:禁用
|
||
- `sync-labs-lipsync`:禁用
|
||
- `fal-veed-lipsync`:禁用
|
||
- `volcengine-doubao-lipsync`:禁用占位
|
||
- 后端已重启,PID `130104`,健康检查通过。
|
||
|
||
遗留问题:
|
||
|
||
- 阿里 VideoRetalk 官方要求公网可访问的 `video_url/audio_url`;当前项目存储层仍以私有本地/MinIO 为主,还需要补“临时公开 URL / 预签名 URL / OSS 中转”才能真实跑阿里。
|
||
- HeyGen、Sync Labs、fal/VEED 已有默认禁用配置,但具体账号版本、endpoint 和响应字段需要开通后用小样校准。
|
||
- 豆包/火山 lip-sync 只做默认禁用占位,等控制台确认正式 API 后再补准确 endpoint。
|
||
|
||
下一步建议:
|
||
|
||
- 先补“lip-sync 素材临时公网 URL”能力,优先 MinIO presigned URL 或 OSS 中转。
|
||
- 阿里百炼开通后填 `ALIBABA_DASHSCOPE_API_KEY`,启用 `alibaba-videoretalk-lipsync`,用第 5 镜跑 6 秒真实小样。
|
||
- 后台 Provider 列表增加 LipSyncProvider 分组和“需要公网素材 URL”提示,避免运营误启用。
|
||
|
||
### 阶段名称
|
||
|
||
ProviderAssetBridge V1 / LipSync 临时公网素材 URL
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 14:58 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 新增后端签名临时素材 URL 能力,兼容本地私有存储和 MinIO 私有存储:
|
||
- `StorageService.createTemporaryPublicUrl`
|
||
- `StorageService.readTemporaryPublicFile`
|
||
- 默认有效期 `3600s`
|
||
- 最短 `60s`,最长 `24h`
|
||
- 需要配置 `PUBLIC_ASSET_BASE_URL`
|
||
- 签名密钥优先读取 `PUBLIC_ASSET_SIGNING_SECRET`,可回退 `JWT_SECRET`
|
||
- 新增无登录公开临时下载入口:
|
||
- `GET /api/public-temp-assets/:token`
|
||
- 只读下载,过期失效
|
||
- `Cache-Control: no-store`
|
||
- 真人 lip-sync 调用新增素材桥接:
|
||
- Provider 配置 `requires_public_urls=true` 时,自动把私有视频片段生成临时 `video_url`;
|
||
- 单句 TTS 音频如果没有公网 URL,先写入私有临时对象,再生成临时 `audio_url`;
|
||
- 传给 Provider 的 input 同时保留 data URI,兼容 fal/通用 Provider;
|
||
- 任务 JSON 记录 `asset_bridge` 审计摘要,不记录真实 URL token。
|
||
- Provider 日志脱敏:
|
||
- `video_url/audio_url` 如果包含 `/public-temp-assets/`,日志中写为 `[REDACTED_TEMP_PUBLIC_ASSET_URL]`。
|
||
- Provider 默认配置新增并保留:
|
||
- `public_url_expires_seconds`
|
||
- `asset_url_expires_seconds`
|
||
- 数据库已同步 LipSyncProvider 配置,阿里/HeyGen/Sync/fal/火山占位继续保持默认禁用。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/assets/storage.service.ts`
|
||
- `backend/src/assets/storage.service.spec.ts`
|
||
- `backend/src/assets/public-temp-assets.controller.ts`
|
||
- `backend/src/assets/assets.module.ts`
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `backend/src/providers/provider.types.ts`
|
||
- `backend/src/providers/providers.service.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- `backend/src/assets/storage.service.spec.ts`
|
||
- `backend/src/assets/public-temp-assets.controller.ts`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test --workspace backend -- storage.service.spec.ts`
|
||
- `npm test --workspace backend -- live-action.service.spec.ts`
|
||
- `npm test --workspace backend -- providers.service.spec.ts`
|
||
- `npm test --workspace backend -- live-action.service.spec.ts storage.service.spec.ts providers.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- `npm test --workspace backend`
|
||
- Prisma upsert `LipSyncProvider` 配置
|
||
- 重启后端 `setsid -f node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Storage 单测:`2 passed`
|
||
- Provider 单测:`33 passed`
|
||
- 真人服务单测:`21 passed`
|
||
- 相关单测合计:`3 passed / 56 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 lint:通过
|
||
- 后端 build:通过
|
||
- 后端全量测试:`25 passed / 199 passed`
|
||
- 数据库同步:
|
||
- `alibaba-videoretalk-lipsync`:禁用,`public_url_expires_seconds=3600`
|
||
- `heygen-lipsync`:禁用,`public_url_expires_seconds=3600`
|
||
- `sync-labs-lipsync`:禁用,`public_url_expires_seconds=3600`
|
||
- `fal-veed-lipsync`:禁用,`public_url_expires_seconds=3600`
|
||
- `volcengine-doubao-lipsync`:禁用,`public_url_expires_seconds=3600`
|
||
- 后端已重启,PID `171746`,健康检查通过。
|
||
|
||
遗留问题:
|
||
|
||
- 真实阿里 VideoRetalk 运行前需要配置公网可访问的 `PUBLIC_ASSET_BASE_URL`,这个地址必须能从阿里云侧访问到本服务器。
|
||
- 生产环境建议单独设置高强度 `PUBLIC_ASSET_SIGNING_SECRET`,不要长期依赖 `JWT_SECRET` 回退。
|
||
- MinIO 直签 / OSS 中转还没做;当前 V1 使用后端签名下载入口,足够先跑小样。
|
||
|
||
下一步建议:
|
||
|
||
- 配置 `PUBLIC_ASSET_BASE_URL=https://你的域名` 和 `PUBLIC_ASSET_SIGNING_SECRET`。
|
||
- 开通阿里百炼后填 `ALIBABA_DASHSCOPE_API_KEY`,启用 `alibaba-videoretalk-lipsync`,用第 5 镜跑真实口型小样。
|
||
- 后台 Provider 页增加“需要公网素材 URL / 临时 URL 有效期 / 当前是否配置 PUBLIC_ASSET_BASE_URL”的提示。
|
||
|
||
### 阶段名称
|
||
|
||
真人视频 Prompt Engine V1 / Provider Profile / 镜头模板库
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 17:52 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 新增真人视频 Prompt Engine V1:
|
||
- 支持 `generic`、`hailuo`、`kling`、`mock` 四种 Provider Profile。
|
||
- 支持按 `scene_type` 选择镜头模板:`dialog`、`conflict`、`reveal`、`dimensional_break`、`xianxia_transformation`、`action`。
|
||
- 输出结构化 `prompt_components`,包含角色、场景、主动作、运镜、灯光、特效、后期音效提示、口型策略、负面提示词。
|
||
- Hailuo Profile 增加方括号运镜指令,例如 `[推进]`、`[拉远]`、`[环绕]`、`[跟拍]`、`[固定]`。
|
||
- Hailuo Profile prompt 控制在 `1800` 字符以内,预留给平台上限和后续追加字段。
|
||
- 真人分镜准备阶段改为用 Prompt Engine 生成通用版 `video_prompt`。
|
||
- 真人视频真实生成阶段改为根据 Router 选出的 `provider_code` 重新生成 Provider 专属 prompt。
|
||
- `live_action_video_clip_generate` 任务输入新增审计字段:
|
||
- `prompt_version`
|
||
- `prompt_profile`
|
||
- `prompt_components`
|
||
- `negative_prompt`
|
||
- 保留原有 lip-sync 降级策略文案,避免没有 lip-sync Provider 时出现正脸口型翻车。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `backend/src/live-action/live-action.module.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- `backend/src/live-action/prompt-builder.service.ts`
|
||
- `backend/src/live-action/prompt-builder.service.spec.ts`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test --workspace backend -- prompt-builder.service.spec.ts live-action.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- `npm test --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Prompt Engine + 真人服务目标测试:`2 passed / 23 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 lint:通过
|
||
- 后端 build:通过
|
||
- 后端全量测试:`26 passed / 201 passed`
|
||
|
||
遗留问题:
|
||
|
||
- Prompt Engine V1 先以内置模板落地,暂未做后台可编辑 Prompt 模板库。
|
||
- 音效/BGM 目前只作为 `sound_cue` 写入 prompt 组件和审计;真实混音仍走后期音频/BGM 流程,不依赖视频 Provider 直接出声。
|
||
- Kling/Veo/Sora 等 Provider 专属模板后续需要真实小样回测再细化。
|
||
|
||
下一步建议:
|
||
|
||
- 用现有 Hailuo Key 重跑“打破次元壁 30 秒小样”,比较 Prompt Engine V1 前后的画面稳定性、动作清晰度和失败原因。
|
||
- 后台 Router 审计页展示 `prompt_profile`、`prompt_version`、`prompt_components`。
|
||
- 第二阶段再把 Prompt Engine 模板前台化,做可编辑的 Prompt Library / 运镜库 / 特效库。
|
||
|
||
### 阶段名称
|
||
|
||
MiniMax LipSyncProvider 占位接入
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 18:15 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 确认 MiniMax/Hailuo 体系已经在项目中区分为:
|
||
- `VideoProvider`:Hailuo 图生视频/文生视频方向。
|
||
- `VoiceProvider`:MiniMax TTS。
|
||
- `LipSyncProvider`:已有视频 + 音频口型替换方向。
|
||
- 新增 `minimax-lipsync` 默认禁用 Provider 占位:
|
||
- `provider_type=LipSyncProvider`
|
||
- `provider_code=minimax-lipsync`
|
||
- `api_key_env=MINIMAX_API_KEY`
|
||
- `driver=configurable_async_lip_sync`
|
||
- `requires_public_urls=true`
|
||
- `public_url_expires_seconds=3600`
|
||
- `create_endpoint/task_endpoint_template` 暂留空,等待 MiniMax 控制台或官方文档确认。
|
||
- 数据库已同步该 Provider:
|
||
- `id=78`
|
||
- `is_enabled=false`
|
||
- 未写入真实 API Key。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/providers/provider.types.ts`
|
||
- `backend/src/providers/providers.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm test --workspace backend -- providers.service.spec.ts`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- `npm test --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- Prisma upsert `minimax-lipsync`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Provider 单测:`34 passed`
|
||
- 后端 typecheck:通过
|
||
- 后端 lint:通过
|
||
- 后端 build:通过
|
||
- 后端全量测试:`26 passed / 202 passed`
|
||
- 数据库同步:`minimax-lipsync` 已创建,默认禁用。
|
||
|
||
遗留问题:
|
||
|
||
- MiniMax 开放平台当前未确认稳定“已有视频+音频口型替换”的公开 API endpoint;该 Provider 不能直接启用。
|
||
- 若 MiniMax 控制台开通后提供 endpoint,需要补齐:
|
||
- `create_endpoint`
|
||
- `task_endpoint_template`
|
||
- 请求体字段映射
|
||
- 输出视频字段
|
||
- 真实计费规则
|
||
|
||
下一步建议:
|
||
|
||
- 继续以 DeepSeek + Hailuo + MiniMax TTS + FFmpeg 跑可发布样片。
|
||
- lip-sync 仍按策略只给高风险正脸台词镜头使用,不做全片 lip-sync。
|
||
- 若要优先真实测试 lip-sync,当前更稳的是阿里 VideoRetalk;MiniMax 等官方 endpoint 确认后再启用。
|
||
|
||
### 阶段名称
|
||
|
||
MiniMax Lip Sync 公开 API 验证
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 18:23 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 读取 MiniMax 官方 `llms.txt` 文档索引和 OpenAPI 规格。
|
||
- 官方 API 索引当前只确认:
|
||
- Text / Responses
|
||
- TTS / 异步 TTS
|
||
- Voice Clone / Voice Design
|
||
- Image Generation
|
||
- Video Generation
|
||
- Video Agent / Template Generation
|
||
- File Management
|
||
- 官方 OpenAPI 当前只检索到以下视频/音频相关路径:
|
||
- `/v1/t2a_async_v2`
|
||
- `/v1/query/t2a_async_query_v2`
|
||
- `/v1/video_generation`
|
||
- `/v1/video_template_generation`
|
||
- `/v1/query/video_template_generation`
|
||
- 对常见 MiniMax lip-sync 路径做无密钥存在性探测,全部返回 `404 page not found`:
|
||
- `/v1/lip_sync`
|
||
- `/v1/lipsync`
|
||
- `/v1/video/lip_sync`
|
||
- `/v1/video/lipsync`
|
||
- `/v1/video_generation/lipsync`
|
||
- `/v1/video/lip-sync`
|
||
- 检查本机环境变量:
|
||
- `MINIMAX_API_KEY`:未配置
|
||
- `MINIMAX_GROUP_ID`:未配置
|
||
- `MINIMAX_BASE_URL`:未配置
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `curl https://platform.minimax.io/docs/llms.txt`
|
||
- `curl https://platform.minimax.io/docs/api-reference/openapi.json`
|
||
- 多个 MiniMax lip-sync 猜测 endpoint 的 `POST {}` 404 探测
|
||
- `.env` MiniMax 相关变量存在性检查
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 官方文档 / OpenAPI:未发现稳定公开“已有视频+音频口型替换” Lip Sync API。
|
||
- 猜测 endpoint 探测:全部 404。
|
||
- 本机未配置 MiniMax Key,无法做鉴权后的真实调用。
|
||
|
||
结论:
|
||
|
||
- `minimax-lipsync` 保持默认禁用占位是正确的。
|
||
- 当前不能把 MiniMax 当作已可用稳定 LipSyncProvider。
|
||
- MiniMax 仍可继续用于 Hailuo 视频生成和 MiniMax TTS;lip-sync 优先测试阿里 VideoRetalk / HeyGen / Sync Labs / fal VEED 等已经有明确 lip-sync API 形态的平台。
|
||
|
||
下一步建议:
|
||
|
||
- 若 MiniMax 控制台或商务支持提供正式 lip-sync endpoint,再补齐 `minimax-lipsync` 的 endpoint、请求体和输出字段。
|
||
- 当前真人短剧流程继续采用“非正脸台词 + TTS + 字幕 + 少量高风险镜头 lip-sync”的低成本策略。
|
||
|
||
### 阶段名称
|
||
|
||
首条真人短剧一集压测用例整理
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 18:32 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 将用户提供的《我送外卖时,继承了百亿集团》整理为系统可用的一集真人短剧测试用例。
|
||
- 输出机器可读 JSON:
|
||
- 项目配置
|
||
- 故事圣经
|
||
- 3 个角色
|
||
- 2 个场景
|
||
- 第 1 集剧情
|
||
- 10 个分镜
|
||
- Router 预期
|
||
- 口型策略
|
||
- 输出要求
|
||
- 验收标准
|
||
- 输出人工审核 Markdown,方便先看剧情、镜头和验收点。
|
||
- 当前只整理用例,不触发 DeepSeek / Hailuo / FFmpeg 真实生成。
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- `storage/private/live-action-testcases/takeaway-heir-episode-001.json`
|
||
- `storage/private/live-action-testcases/takeaway-heir-episode-001.md`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `node -e` JSON 解析与时长/镜头数/角色数/场景数校验
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- JSON 校验通过:
|
||
- 镜头:10 个
|
||
- 总时长:53 秒
|
||
- 角色:3 个
|
||
- 场景:2 个
|
||
- normal 镜头:5 个
|
||
- premium 镜头:5 个
|
||
|
||
遗留问题:
|
||
|
||
- 还未导入数据库。
|
||
- 还未跑 DeepSeek 剧本生成、Prompt Builder、Hailuo 视频、TTS、字幕、BGM、FFmpeg 合成。
|
||
- 该用例目前作为“第一集压测 fixture”,不是最终成片。
|
||
|
||
下一步建议:
|
||
|
||
- 人工先确认剧情和 10 个镜头是否满意。
|
||
- 确认后新增导入脚本,把该 JSON 导入为真实项目/角色/分集/分镜。
|
||
- 再按低风险顺序执行:先 Mock 全链路,再 Hailuo 单镜小样,再 Hailuo 全 10 镜。
|
||
|
||
### 阶段名称
|
||
|
||
首条真人短剧压测项目导入 / Prompt 准备
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 20:18 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 新增真人短剧测试用例导入脚本:
|
||
- 支持默认读取 `storage/private/live-action-testcases/takeaway-heir-episode-001.json`
|
||
- 支持 `--replace=true` 清理同一 `testcase_id` 的旧导入项目
|
||
- 创建 Project / CopyrightRecord / StoryBible / WorldBible / Character / ActorProfile / Episode / EpisodeScript / StoryboardShot / OperationLog
|
||
- 不触发真实 AI Provider,不生成视频,不产生外部成本
|
||
- 已执行一次导入:
|
||
- `project_id=54`
|
||
- `episode_id=40`
|
||
- `owner_user_id=1`
|
||
- `shot_id=231-240`
|
||
- 总时长 `53s`
|
||
- 已执行 `prepareLiveActionShots`:
|
||
- 10 个镜头全部生成 `video_prompt`
|
||
- 项目状态更新为 `live_action_shots_prepared`
|
||
- 下一步为 `live_action_keyframes_generate`
|
||
|
||
修改文件:
|
||
|
||
- `backend/package.json`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- `backend/src/live-action/import-live-action-testcase.ts`
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm run lint --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- `npm test --workspace backend`
|
||
- `npm run live-action:testcase:import --workspace backend -- --replace=true`
|
||
- Prisma 查询校验导入结果
|
||
- Nest ApplicationContext 调用 `LiveActionService.prepareLiveActionShots`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- 后端 typecheck:通过
|
||
- 后端 lint:通过
|
||
- 后端 build:通过
|
||
- 后端全量测试:`26 passed / 202 passed`
|
||
- 数据库导入校验:
|
||
- 角色:3
|
||
- ActorProfile:3
|
||
- 分镜:10
|
||
- 总时长:53 秒
|
||
- Premium 镜头:5
|
||
- `video_prompt`:10/10 已生成
|
||
|
||
遗留问题:
|
||
|
||
- 还未生成关键帧。
|
||
- 还未跑 Mock 视频全链路。
|
||
- 还未调用 Hailuo 真实视频。
|
||
- 还未生成 TTS / 字幕 / BGM / 最终 `episode_001.mp4`。
|
||
|
||
下一步建议:
|
||
|
||
- 先跑 Mock 关键帧和 Mock 视频全链路,确认 10 镜合成、字幕、BGM、审计视图都能走通。
|
||
- 再挑 1 个 premium 镜头,用真实 PNG/JPG 关键帧跑 Hailuo 单镜小样。
|
||
- 单镜合格后再跑全 10 镜真实 Hailuo,严格限制成本上限。
|
||
|
||
### 阶段名称
|
||
|
||
首条真人短剧 Mock 全链路成片验收
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 20:24 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 对项目 `54` / 第 `40` 集执行 Mock 全链路:
|
||
- Mock 关键帧生成
|
||
- Mock 视频片段生成
|
||
- Mock TTS 音频
|
||
- 字幕生成
|
||
- BGM 生成
|
||
- FFmpeg 最终合成
|
||
- 生成最终成片资产:
|
||
- `asset_id=373`
|
||
- `file_path=local://rendered-videos/2026-06-11/e83438a3-ef14-4ef5-89f4-2a8511bcfe19.mp4`
|
||
- 本地路径:`storage/private/rendered-videos/2026-06-11/e83438a3-ef14-4ef5-89f4-2a8511bcfe19.mp4`
|
||
- 发现并修复验收差异:
|
||
- 测试用例要求 `30FPS`
|
||
- 旧 live-action 渲染常量为 `24FPS`
|
||
- 已将 `LIVE_ACTION_RENDER_FPS` 从 `24` 改为 `30`
|
||
- 重新渲染后 ffprobe 确认输出为 `30/1`
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- Nest ApplicationContext 调用:
|
||
- `generateKeyframes`
|
||
- `generateVideoClips`
|
||
- `renderLiveActionEpisode`
|
||
- `ffprobe` 检查最终 MP4
|
||
- `npm run typecheck --workspace backend`
|
||
- `npm test --workspace backend -- live-action.service.spec.ts`
|
||
- `npm run lint --workspace backend`
|
||
- `npm test --workspace backend`
|
||
- `npm run build --workspace backend`
|
||
- 重启后端 `node dist/main.js`
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Mock 关键帧:`10/10`
|
||
- Mock 视频片段:`10/10`
|
||
- 最终成片:成功
|
||
- ffprobe:
|
||
- 视频编码:`h264`
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`30/1`
|
||
- 视频时长:`53.000000s`
|
||
- 音频编码:`aac`
|
||
- 音频时长:`53.000000s`
|
||
- 后端 typecheck:通过
|
||
- 真人服务单测:`21 passed`
|
||
- 后端 lint:通过
|
||
- 后端 build:通过
|
||
- 后端全量测试:`26 passed / 202 passed`
|
||
- 后端已重启,PID `784440`,健康检查通过。
|
||
|
||
遗留问题:
|
||
|
||
- 当前成片是 Mock 视频,不能评价真实画面质量。
|
||
- 当前口型策略为 TTS + 字幕 + 轻口型规避,未启用真实 lip-sync。
|
||
- 真实 Hailuo 单镜还未跑。
|
||
|
||
下一步建议:
|
||
|
||
- 在后台打开资产 `373` 或项目 `54` 的结果页,人工先看 Mock 流程预览和字幕/BGM节奏。
|
||
- 选择一个 premium 镜头做真实 Hailuo 单镜小样,建议优先镜头 `235`(劳斯莱斯停靠 + 王伯鞠躬)或镜头 `240`(车门关闭反击)。
|
||
- 单镜通过后再跑全 10 镜真实 Hailuo。
|
||
|
||
## 2026-06-11 真实 Hailuo 单镜小样验收
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 20:36 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 对项目 `54` / 第 `40` 集 / 镜头 `235` 跑真实 Hailuo 单镜小样。
|
||
- 先将镜头 `235` 的 mock SVG 关键帧替换为可供真实视频接口使用的 PNG 关键帧:
|
||
- `keyframe_asset_id=374`
|
||
- `file_path=local://image/2026-06-11/84761003-b42a-43b5-8e46-b3ba8a1f5f62.png`
|
||
- 真实视频 Provider 预检通过:
|
||
- Provider:`minimax_hailuo_23_fast`
|
||
- 模式:`real`
|
||
- 预计成本:`0.1902 USD`
|
||
- 关键帧:`image/png`
|
||
- 阻断项:无
|
||
- 发起真实 Hailuo 图生视频调用并成功回收视频:
|
||
- `video_clip_id=25`
|
||
- `output_asset_id=375`
|
||
- `provider_id=19`
|
||
- `provider_request_id=408077018386698`
|
||
- 实际成本:`0.1902 USD`
|
||
- 文件:`storage/private/live-action-video-clips/2026-06-11/cb0fd951-657a-4d07-b3c7-661a1d8cfa93.mp4`
|
||
- 执行队列化质检任务:
|
||
- `task_id=376`
|
||
- Provider:`mock-qc`
|
||
- 结果:`passed`
|
||
- 分数:`94`
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- Nest ApplicationContext 调用:
|
||
- `preflightVideoClips`
|
||
- `generateShotVideoClip`
|
||
- `checkVideoClipQuality`
|
||
- `executeQueuedRouterTask`
|
||
- `ffprobe` 检查真实 Hailuo MP4
|
||
- `ffmpeg` 抽帧检查中间画面
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Provider 密钥状态:
|
||
- `.env` 未设置 `MINIMAX_API_KEY`
|
||
- 后台 Provider 已保存加密托管密钥,且已同步到 Hailuo / MiniMax TTS / MiniMax Text
|
||
- Hailuo 单镜生成:成功
|
||
- 质检闭环:成功
|
||
- ffprobe 原始 Provider 输出:
|
||
- 视频编码:`h264`
|
||
- 分辨率:`768x1364`
|
||
- 帧率:`24/1`
|
||
- 时长:`5.875000s`
|
||
- 音频:无
|
||
- 人工抽帧观感:
|
||
- 雨夜、豪车、管家鞠躬、男主站位均符合镜头意图。
|
||
- 该片段是无声单镜,需要进入 TTS / 字幕 / BGM / FFmpeg 合成后才可作为完整成片验收。
|
||
|
||
遗留问题:
|
||
|
||
- Hailuo Fast 原始输出不是 `1080x1920 / 30FPS / 6s`,最终成片必须依赖 FFmpeg 归一化。
|
||
- 资产表当前记录的是目标尺寸 `1080x1920 / 6s`,但真实原始文件为 `768x1364 / 5.875s`;后续后台审计页应同时展示 Provider 原始媒体参数和归一化参数。
|
||
- 当前只验证了单镜真实视频,没有验证 10 镜真实 Hailuo 全集生成和最终音画合成。
|
||
|
||
下一步建议:
|
||
|
||
- 进入 10 镜真实 Hailuo 全集小样,但在全量扣费前先批量准备 PNG/JPG 关键帧。
|
||
- 真实全集跑完后,执行 TTS / 字幕 / BGM / FFmpeg 合成,重点验收音画节奏、字幕、BGM、镜头时长归一化。
|
||
- 后台 Router 审计页补充 Provider 原始输出参数展示,避免 `768x1364/24fps` 和最终 `1080x1920/30fps` 混淆。
|
||
|
||
## 2026-06-11 真实 Hailuo 全 10 镜小样验收
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 20:59 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 对项目 `54` / 第 `40` 集执行真实 Hailuo 全 10 镜小样。
|
||
- 因当前没有启用真实 ImageProvider,先为除第 5 镜外的 9 个镜头生成基础构图 PNG 关键帧,用于真实视频链路压测:
|
||
- 镜头 `231` -> `keyframe_asset_id=376`
|
||
- 镜头 `232` -> `keyframe_asset_id=377`
|
||
- 镜头 `233` -> `keyframe_asset_id=378`
|
||
- 镜头 `234` -> `keyframe_asset_id=379`
|
||
- 镜头 `236` -> `keyframe_asset_id=380`
|
||
- 镜头 `237` -> `keyframe_asset_id=381`
|
||
- 镜头 `238` -> `keyframe_asset_id=382`
|
||
- 镜头 `239` -> `keyframe_asset_id=383`
|
||
- 镜头 `240` -> `keyframe_asset_id=384`
|
||
- 整集真实 Hailuo 预检通过:
|
||
- 镜头数:`10`
|
||
- 关键帧:`10/10` 均为 PNG
|
||
- Provider:`minimax_hailuo_23_fast`
|
||
- 预估成本:`1.6801 USD`
|
||
- 阻断项:无
|
||
- 补跑剩余 9 条真实 Hailuo 视频片段:
|
||
- 镜头 `231` -> `video_clip_id=26` / `asset_id=385`
|
||
- 镜头 `232` -> `video_clip_id=27` / `asset_id=386`
|
||
- 镜头 `233` -> `video_clip_id=28` / `asset_id=387`
|
||
- 镜头 `234` -> `video_clip_id=29` / `asset_id=388`
|
||
- 镜头 `236` -> `video_clip_id=30` / `asset_id=389`
|
||
- 镜头 `237` -> `video_clip_id=31` / `asset_id=390`
|
||
- 镜头 `238` -> `video_clip_id=32` / `asset_id=391`
|
||
- 镜头 `239` -> `video_clip_id=33` / `asset_id=392`
|
||
- 镜头 `240` -> `video_clip_id=34` / `asset_id=393`
|
||
- 结合已完成的镜头 `235`:
|
||
- 10 条真实 Hailuo 视频片段全部成功。
|
||
- 10 条片段质检全部通过,分数均为 `94`。
|
||
- 强制重新合成整集:
|
||
- `render_task_id=398`
|
||
- `output_asset_id=397`
|
||
- 文件:`storage/private/rendered-videos/2026-06-11/69f4335a-cbe5-4a80-99ff-dbbcb7f32741.mp4`
|
||
- 状态:`active`
|
||
- 后期资产:
|
||
- TTS:`audio_task_id=395` / `audio_asset_id=394`
|
||
- VoiceProvider:`minimax-tts`
|
||
- `audio_is_mock=false`
|
||
- 字幕:`subtitle_task_id=396` / `subtitle_asset_id=395`
|
||
- BGM:`bgm_task_id=397` / `bgm_asset_id=396`
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- `git status --short`
|
||
- Nest ApplicationContext / dist 脚本调用:
|
||
- PNG 关键帧上传并回写镜头
|
||
- `preflightVideoClips`
|
||
- `generateShotVideoClip`
|
||
- `checkVideoClipQuality`
|
||
- `executeQueuedRouterTask`
|
||
- `renderLiveActionEpisode`
|
||
- `ffprobe` 检查最终 MP4
|
||
- `ffmpeg` 抽帧与接触图检查
|
||
|
||
测试结果:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- Hailuo 视频生成:
|
||
- 成功:`10/10`
|
||
- 失败:`0`
|
||
- 单条耗时约 `64s-88s`
|
||
- 每条实际成本:`0.1902 USD`
|
||
- 总视频成本:`1.902 USD`
|
||
- Hailuo 成本估算差异:
|
||
- 系统预估 `5s` 镜头为 `0.1585 USD`
|
||
- 实际 Hailuo Fast 仍按 `6s` 档返回/扣费,实际为 `0.1902 USD`
|
||
- 后续成本模型应按 Provider 档位估算,而不是简单按秒线性估算。
|
||
- 最终成片 ffprobe:
|
||
- 视频编码:`h264`
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`30/1`
|
||
- 视频流时长:`52.600000s`
|
||
- 音频编码:`aac`
|
||
- 音频流时长:`53.000000s`
|
||
- 容器时长:`53.000000s`
|
||
- clip_normalization:
|
||
- 5 秒业务镜头均从 Hailuo 原始 `5.875s` 裁切到 `5s`
|
||
- 6 秒业务镜头保留约 `5.867s`
|
||
- 合成后总时长对齐到 `53s`
|
||
- TTS:
|
||
- 已走真实 `minimax-tts`
|
||
- 发现第 1 个音频片段超时:
|
||
- 目标:`2.85s`
|
||
- 实际:`4s`
|
||
- 超出:`1.15s`
|
||
- 人工抽帧 / 接触图观感:
|
||
- 画面已经是真人短剧风格,字幕烧录位置基本正常。
|
||
- 第 4 镜黑卡、雨夜车、管家、人物近景等主要叙事元素可识别。
|
||
- 由于 9 个关键帧是临时构图图,不是真实定妆图,角色一致性和服装一致性仍不足。
|
||
- 当前 BGM 是 `system_silent_bed_v1`,只能算底噪/铺底,不是正式都市逆袭音乐。
|
||
|
||
遗留问题:
|
||
|
||
- 这版证明真实 Hailuo + MiniMax TTS + 字幕 + FFmpeg 合成链路跑通,但不能直接判定为发布级成片。
|
||
- 发布级还缺真实角色定妆图 / 角色锚点图,否则人物脸和服装会漂。
|
||
- 成本估算需要按 Hailuo `6s/10s` 档位修正。
|
||
- 第 1 镜台词过长,TTS 超出分配时长,需要脚本压缩或镜头延长。
|
||
- BGM 还不是正式音乐,需要接音乐素材库或 BGM Provider。
|
||
- 质检仍是 `mock-qc`,还没有真实视觉质检模型。
|
||
|
||
下一步建议:
|
||
|
||
- 优先做“真人定妆图 / 角色锚点图小样 V1”:先固定林凡、陈雪、王伯三个人的真实头像和服装,再重跑 2-3 个关键镜头验证角色一致性。
|
||
- 修复 Hailuo 成本估算:按 Provider 配置的 duration 档位向上取整到 `6s/10s`。
|
||
- 优化 TTS 节奏:台词超时自动压缩、分拆或延长镜头。
|
||
- 给 BGM 增加正式素材或 Provider,替换 `system_silent_bed_v1`。
|
||
|
||
## 2026-06-11 公版热门故事《画皮》30 秒质量定位
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 21:39 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 停止继续使用《我送外卖时,继承了百亿集团》做画质判断,改用公版热门故事《聊斋志异·画皮》做 30 秒质量定位。
|
||
- 新增内部测试用例:
|
||
- `storage/private/live-action-testcases/painted-skin-episode-001.json`
|
||
- 6 镜头,每镜 `5s`
|
||
- 总时长 `30s`
|
||
- 风格:古风悬疑真人短剧
|
||
- 导入新测试项目:
|
||
- `project_id=55`
|
||
- `episode_id=41`
|
||
- `shot_id=241-246`
|
||
- 运行现有 Prompt Builder 准备真人分镜提示词:
|
||
- 6/6 镜头已进入 `prepared`
|
||
- 使用 Codex 内置图片生成能力生成三张真人定妆图,并上传为项目私有资产:
|
||
- 王生:`character_id=79` / `anchor_asset_id=398`
|
||
- 画皮女子:`character_id=80` / `anchor_asset_id=399`
|
||
- 老道士:`character_id=81` / `anchor_asset_id=400`
|
||
- 已写入:
|
||
- `characters.anchor_asset_id`
|
||
- `actor_profiles.anchor_asset_id`
|
||
- `actor_profiles.reference_asset_ids`
|
||
- `character_images`
|
||
- 只跑 3 个关键镜头真实 Hailuo 小样,未跑整集:
|
||
- 镜头 `242` 女子求助:`video_clip_id=35` / `asset_id=401`
|
||
- 镜头 `244` 道士警告:`video_clip_id=36` / `asset_id=402`
|
||
- 镜头 `245` 窗外窥视:`video_clip_id=37` / `asset_id=403`
|
||
- 新增真实视频成本:
|
||
- `0.1902 USD * 3 = 0.5706 USD`
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- `storage/private/live-action-testcases/painted-skin-episode-001.json`
|
||
|
||
运行命令:
|
||
|
||
- `npm run live-action:testcase:import --workspace backend -- --file=/www/wwwroot/ai/storage/private/live-action-testcases/painted-skin-episode-001.json --replace=true`
|
||
- Nest ApplicationContext / dist 脚本调用:
|
||
- `prepareLiveActionShots`
|
||
- 上传角色锚点图到资产库
|
||
- 回写角色 / ActorProfile / CharacterImage
|
||
- `preflightVideoClips`
|
||
- `generateShotVideoClip`
|
||
- `ffmpeg` 抽帧生成三镜头接触图:
|
||
- `/tmp/painted-skin-sample/contact.jpg`
|
||
|
||
测试结果:
|
||
|
||
- 30 秒故事结构明显比上一版更清楚:
|
||
- 夜巷初遇
|
||
- 女子求助
|
||
- 书斋收留
|
||
- 道士警告
|
||
- 窗外窥视
|
||
- 画皮真相一闪
|
||
- 三张角色定妆图质量可用:
|
||
- 服装、年龄、气质、古风身份都基本符合设定。
|
||
- 三条 Hailuo 关键镜头生成均成功。
|
||
- 人工抽帧结论:
|
||
- 角色脸和服装比临时构图图稳定得多。
|
||
- 但直接把“人物肖像图”作为 Hailuo 首帧,会导致视频更像人物肖像动图,而不是完整场景动作。
|
||
- Hailuo 对首帧构图继承很强,首帧不是场景图,后续很难自然生成复杂动作和双人互动。
|
||
|
||
关键结论:
|
||
|
||
- 不应该继续用“纯角色头像”直接跑整集 Hailuo。
|
||
- 正确流程应升级为:
|
||
- 角色锚点图
|
||
- 生成每个镜头的场景关键帧
|
||
- 场景关键帧中已经包含角色、服装、场景、动作起手式
|
||
- 再送 Hailuo 图生视频
|
||
- 也就是说,角色锚点图是必要条件,但不是视频首帧本身。
|
||
|
||
下一步建议:
|
||
|
||
- 做“场景关键帧 V1”:用角色锚点图约束人物,再为镜头 `242 / 244 / 245` 各生成一张真正的场景关键帧。
|
||
- 只重跑这 3 个镜头,不跑整集,确认动作和场景是否改善。
|
||
- 如果 3 个镜头可用,再补全 30 秒整集;如果仍不行,先改 Prompt Builder 和关键帧生成策略,不再继续烧视频额度。
|
||
|
||
## 2026-06-11 《画皮》场景关键帧 V1 验证
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 22:04 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 基于项目 `55` / 第 `41` 集,继续验证“角色锚点图 -> 场景关键帧 -> Hailuo 图生视频”的正确链路。
|
||
- 使用 Codex 内置图片生成能力生成 3 张场景关键帧:
|
||
- 镜头 `242` 女子求助:`asset_id=404`
|
||
- 镜头 `244` 道士警告:`asset_id=405`
|
||
- 镜头 `245` 窗外窥视:`asset_id=406`
|
||
- 将三张场景关键帧替换为对应镜头的 `keyframe_asset_id`。
|
||
- 重跑 3 条真实 Hailuo 视频:
|
||
- 镜头 `242` -> `video_clip_id=38` / `asset_id=407`
|
||
- 镜头 `244` -> `video_clip_id=39` / `asset_id=408`
|
||
- 镜头 `245` -> `video_clip_id=40` / `asset_id=409`
|
||
- 3 条新片段全部通过 mock-qc:
|
||
- `clip_id=38` -> `94`
|
||
- `clip_id=39` -> `94`
|
||
- `clip_id=40` -> `94`
|
||
- 将这 3 条片段合成 15 秒小样:
|
||
- `render_asset_id=413`
|
||
- 文件:`storage/private/rendered-videos/2026-06-11/3c388019-7ac4-4699-ba52-f9d4f0260eb1.mp4`
|
||
- 包含真实 MiniMax TTS、字幕、BGM 铺底。
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- 无
|
||
|
||
运行命令:
|
||
|
||
- Codex 内置图片生成:3 张场景关键帧
|
||
- Nest ApplicationContext / dist 脚本调用:
|
||
- 上传场景关键帧
|
||
- 回写 `StoryboardShot.keyframe_asset_id`
|
||
- `preflightVideoClips`
|
||
- `generateShotVideoClip`
|
||
- `checkVideoClipQuality`
|
||
- `executeQueuedRouterTask`
|
||
- `renderLiveActionEpisode`
|
||
- `ffprobe` 检查 15 秒小样
|
||
- `ffmpeg` 抽帧和生成对比图
|
||
|
||
测试结果:
|
||
|
||
- 三条 Hailuo 生成全部成功:
|
||
- 成本:`0.1902 USD * 3 = 0.5706 USD`
|
||
- 单条耗时约 `76s-97s`
|
||
- 15 秒小样 ffprobe:
|
||
- 视频编码:`h264`
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`30/1`
|
||
- 视频时长:`15.000000s`
|
||
- 音频编码:`aac`
|
||
- 音频时长:`15.000000s`
|
||
- TTS:
|
||
- Provider:`minimax-tts`
|
||
- `audio_is_mock=false`
|
||
- 无 TTS 超时警告
|
||
- clip_normalization:
|
||
- Hailuo 原始 `5.875s`
|
||
- 每条裁切到目标 `5s`
|
||
|
||
人工观感结论:
|
||
|
||
- 场景关键帧版明显优于头像首帧版。
|
||
- 镜头 `242` 能看到女子、王生、伞、夜巷、红灯笼,求助关系成立。
|
||
- 镜头 `244` 能看到老道士、王生、竹杖拦路、街市口,警告关系成立。
|
||
- 镜头 `245` 能看到王生窗外窥视、屋内烛光和模糊白衣女子,悬疑关系成立。
|
||
- 这说明“先生成场景首帧,再送 Hailuo”是正确方向。
|
||
|
||
遗留问题:
|
||
|
||
- 当前场景关键帧由 Codex 图片生成能力手动生成,还未进入后台自动化流程。
|
||
- 角色锚点图没有被真实 ImageProvider 以多图参考方式自动消费,仍是人工 prompt 对齐。
|
||
- Hailuo 图生视频仍无原生音频,音频必须靠后期 TTS/字幕/BGM。
|
||
- BGM 仍是系统铺底,不是正式古风悬疑音乐。
|
||
- 成本估算仍需按 Hailuo `6s/10s` 档位修正。
|
||
|
||
下一步建议:
|
||
|
||
- 把“场景关键帧生成”做成后台正式流程:
|
||
- 输入:镜头分镜 + 角色锚点图 + 场景设定
|
||
- 输出:`ShotImage(image_type=scene_keyframe)` + `StoryboardShot.keyframe_asset_id`
|
||
- 然后再进入 Hailuo 视频生成
|
||
- 继续补齐《画皮》剩余 `241 / 243 / 246` 三个镜头的场景关键帧,再跑完整 30 秒。
|
||
- 之后再走前端 E2E,因为现在核心质量方向已经明确。
|
||
|
||
## 2026-06-11 《画皮》30 秒完整真人小样验收
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 22:31 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 继续基于项目 `55` / 第 `41` 集,补齐剩余三个镜头的场景关键帧:
|
||
- 镜头 `241` 夜巷初遇:`keyframe_asset_id=414`
|
||
- 镜头 `243` 书斋收留:`keyframe_asset_id=416`
|
||
- 镜头 `246` 画皮真相一闪:`keyframe_asset_id=418`
|
||
- 分别使用真实 Hailuo 生成三条新片段:
|
||
- 镜头 `241` -> `video_clip_id=41` / `asset_id=415`
|
||
- 镜头 `243` -> `video_clip_id=42` / `asset_id=417`
|
||
- 镜头 `246` -> `video_clip_id=43` / `asset_id=419`
|
||
- 合并前 3 条已验证片段:
|
||
- 镜头 `242` -> `video_clip_id=38` / `asset_id=407`
|
||
- 镜头 `244` -> `video_clip_id=39` / `asset_id=408`
|
||
- 镜头 `245` -> `video_clip_id=40` / `asset_id=409`
|
||
- 合成完整 30 秒成片:
|
||
- `render_asset_id=423`
|
||
- 文件:`storage/private/rendered-videos/2026-06-11/1511d944-273b-493f-a860-dae29249a0c5.mp4`
|
||
- 包含真实 MiniMax TTS、字幕、静音 BGM 占位。
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
新增文件:
|
||
|
||
- `storage/private/live-action-testcases/painted-skin-episode-001.json`
|
||
|
||
运行命令:
|
||
|
||
- Codex 内置图片生成:补齐 3 张场景关键帧。
|
||
- `npm run live-action:acceptance --workspace backend`:
|
||
- 逐条跑 `241 / 243 / 246`
|
||
- Provider:`minimax_hailuo_23_fast`
|
||
- `confirm_real_video=true`
|
||
- Nest `dist` ApplicationContext:
|
||
- `renderLiveActionEpisode`
|
||
- `ffprobe`:
|
||
- 验证最终成片视频/音频流
|
||
- `ffmpeg`:
|
||
- 抽帧检查 6 镜头时间线
|
||
- `volumedetect` 检查最终音频电平
|
||
- `curl http://127.0.0.1:3000/api/health`
|
||
|
||
测试结果:
|
||
|
||
- Hailuo 本轮新增 3 条均成功:
|
||
- `clip_id=41` / `42` / `43`
|
||
- 成本:`0.1902 USD * 3 = 0.5706 USD`
|
||
- mock 质检:均 `94`
|
||
- 《画皮》6 条 Hailuo 片段合计:
|
||
- 成本:`0.1902 USD * 6 = 1.1412 USD`
|
||
- 约合人民币按汇率浮动约 `8 元` 左右。
|
||
- 30 秒成片规格:
|
||
- 视频:`h264`
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`30fps`
|
||
- 视频时长:`30.000000s`
|
||
- 音频:`aac`
|
||
- 音频时长:`30.000000s`
|
||
- 文件大小:约 `14.8MB`
|
||
- 后期:
|
||
- TTS Provider:`minimax-tts`
|
||
- `audio_is_mock=false`
|
||
- `audio_warnings=[]`
|
||
- 字幕 cue:`6`
|
||
- BGM:`system_silent_bed_v1`,当前只是静音占位,不是正式音乐。
|
||
- clip_normalization:
|
||
- 6 条 Hailuo 原始视频均约 `5.875s`
|
||
- 合成前全部自动裁切到目标 `5s`
|
||
- 最终总时长准确为 `30s`
|
||
- 后端健康检查:
|
||
- `/api/health` 返回 `status=ok`
|
||
|
||
人工观感结论:
|
||
|
||
- 这版明显优于之前“外卖继承百亿”和“头像首帧直接跑 Hailuo”的结果。
|
||
- 6 个镜头都与剧情相关,没有出现蜡烛图、无关画面或明显断片。
|
||
- 叙事链路基本成立:
|
||
- 夜巷初遇
|
||
- 女子求助
|
||
- 书斋收留
|
||
- 道士警告
|
||
- 窗外窥视
|
||
- 画皮揭露
|
||
- 字幕位置没有挡脸,画面和字幕节奏基本可读。
|
||
- 当前还不能判定为“可直接上架发布”,但已经证明质量问题的主因不是 Hailuo 单点,而是前置关键帧和 Prompt Builder。
|
||
|
||
遗留问题:
|
||
|
||
- 角色一致性仍未达到生产级:
|
||
- 王生服装在蓝袍、灰袍之间漂移。
|
||
- 人脸一致性比纯文字 prompt 好,但还不够稳定。
|
||
- 场景关键帧目前仍是人工生成,尚未自动接入后台 ImageProvider。
|
||
- 当前 BGM 是静音占位,不能满足正式发布的音乐需求。
|
||
- 旁白/对白已经存在,但未做真实 lip-sync,正脸对白仍应继续走“中景轻口型 + 字幕 + 旁白”策略,或后续接 lip-sync Provider。
|
||
- mock 质检只验证流程,不能替代人工画面审片。
|
||
|
||
关键结论:
|
||
|
||
- 后续真人短剧流水线必须改为:
|
||
- 故事/分镜
|
||
- 角色锚点图
|
||
- 场景关键帧生成
|
||
- Hailuo 图生视频
|
||
- TTS/字幕/BGM
|
||
- clip_normalization
|
||
- 人工审片
|
||
- 不建议再用“纯文字 prompt -> Hailuo”或“纯人物头像 -> Hailuo”跑整集。
|
||
|
||
下一步建议:
|
||
|
||
- 优先做“场景关键帧自动化 V1”:
|
||
- 把 `scene_keyframe` 作为正式中间资产。
|
||
- 后台能看到每个镜头的关键帧、视频片段、最终成片对比。
|
||
- 角色锚点图作为关键帧生成输入,而不是直接作为视频首帧。
|
||
- 同时补“正式 BGM 资产/模板 V1”:
|
||
- 都市逆袭、古风悬疑、情感虐恋、修仙爆点各一套。
|
||
- 允许后台上传或选择 BGM。
|
||
- 质量通过后再走前端 E2E,避免继续在低质量画面上验 UI 流程。
|
||
|
||
## 2026-06-11 仿真人发布级质感 V1
|
||
|
||
完成时间:
|
||
|
||
2026-06-11 23:03 Asia/Shanghai
|
||
|
||
完成内容:
|
||
|
||
- 围绕“像抖音真人拍摄短剧”的差距,先补合成层的发布包装能力,不继续盲目烧 Hailuo 额度。
|
||
- 后端真人视频最终合成新增轻量影视包装:
|
||
- 轻对比
|
||
- 轻降饱和
|
||
- 轻暗角
|
||
- 细颗粒
|
||
- 后端默认 BGM 从静音占位升级为系统低频悬疑氛围底:
|
||
- `system_silent_bed_v1` -> `system_cinematic_bed_v1`
|
||
- 使用 FFmpeg 合成低频 pad,不再是完全静音轨。
|
||
- `live_action_video_render.input_json` 新增 `video_polish` 审计字段:
|
||
- `version=live-action-video-polish-v1`
|
||
- 记录使用的后期包装项。
|
||
- 基于已有《画皮》6 条 Hailuo 片段重做导演剪辑版:
|
||
- 不重新调用 Hailuo
|
||
- 不增加视频生成成本
|
||
- 将平均 `5s * 6 = 30s` 改为更短更快的 `18.9s`
|
||
- 缩短旁白/对白,避免正脸长对白。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/dist/**`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
数据调整:
|
||
|
||
- 项目 `55` / 第 `41` 集《画皮》测试集:
|
||
- 镜头 `241`:`3s`
|
||
- 镜头 `242`:`3.8s`
|
||
- 镜头 `243`:`2.7s`
|
||
- 镜头 `244`:`3.2s`
|
||
- 镜头 `245`:`2.8s`
|
||
- 镜头 `246`:`3.4s`
|
||
- 台词压缩:
|
||
- `女子:公子,救我。`
|
||
- `道士:她不是人。`
|
||
- `王生:不可能。`
|
||
|
||
新增成片:
|
||
|
||
- 导演剪辑版 asset:
|
||
- `render_asset_id=431`
|
||
- 文件:`storage/private/rendered-videos/2026-06-11/6e44c8a9-6d22-438c-ba36-73da0ac230e0.mp4`
|
||
- 时长:`18.9s`
|
||
|
||
测试结果:
|
||
|
||
- `npm run typecheck --workspace backend`:通过。
|
||
- `npm run build --workspace backend`:通过。
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts`:
|
||
- `21 passed`
|
||
- FFmpeg BGM 表达式验证:通过。
|
||
- 成片 ffprobe:
|
||
- 视频:`1080x1920`
|
||
- 帧率:`30fps`
|
||
- 视频时长:`18.900000s`
|
||
- 音频:`aac`
|
||
- 音频时长:`18.900000s`
|
||
- 音频电平:
|
||
- `mean_volume=-18.6 dB`
|
||
- `max_volume=-2.4 dB`
|
||
- render task 审计:
|
||
- `audio_warnings=[]`
|
||
- `video_polish.version=live-action-video-polish-v1`
|
||
- `bgm_volume=0.18`
|
||
- 后端重启并验证:
|
||
- 新进程:`node dist/main.js`
|
||
- 父进程:`1`
|
||
- `/api/health` 返回 `status=ok`
|
||
|
||
人工观感结论:
|
||
|
||
- 导演剪辑版比 30 秒平均镜头版节奏更接近短视频。
|
||
- 字幕更短,读起来更干净。
|
||
- 合成层统一调色、颗粒、暗角后,画面少了一点“AI直出平铺感”。
|
||
- 但它仍不是最终发布级,原因不是合成层能完全解决的:
|
||
- 角色一致性仍会漂。
|
||
- 真人表演感仍不足。
|
||
- 镜头内动作还不够像真实演员自然运动。
|
||
- 真实环境声、脚步声、雨声、衣料声、转场音效还没系统化。
|
||
- 未接真实 lip-sync,正脸对白仍不能大量使用。
|
||
|
||
关键结论:
|
||
|
||
- “发布级仿真人”不是单纯 Hailuo 重跑,而是需要进入导演工艺层:
|
||
- 短镜头节奏
|
||
- 更短台词
|
||
- 避免正脸长对白
|
||
- 真实声音设计
|
||
- 人工挑片
|
||
- 角色一致性约束
|
||
- 关键镜头多候选择优
|
||
|
||
下一步建议:
|
||
|
||
- 做“候选片段择优 V1”:
|
||
- 每个关键镜头允许生成 2-3 个候选。
|
||
- 后台人工选择最像真人的一条作为 `video_clip_asset_id`。
|
||
- 不通过的候选保留成本和失败原因。
|
||
- 做“音效轨 V1”:
|
||
- 雨声、脚步、门响、心跳、低频转场、惊悚 sting。
|
||
- 按 `scene_type/effect_type` 自动铺音效。
|
||
- 做“角色一致性强化 V1”:
|
||
- 场景关键帧自动生成时必须消费角色锚点图。
|
||
- 后台显示锚点图、场景关键帧、视频中帧三栏对比。
|
||
|
||
## 2026-06-12 候选片段择优 V1 + 音效轨 V1
|
||
|
||
本阶段目标:
|
||
|
||
- 让关键镜头可以一次生成 `2-3` 条候选,后台人工选择最像真人的一条。
|
||
- 给真人短剧后期增加独立 SFX 音效轨,先解决“画面有了但不像真实拍摄环境”的声音缺口。
|
||
|
||
完成内容:
|
||
|
||
- `LiveActionGenerateDto` 新增:
|
||
- `candidate_count`
|
||
- `include_sfx`
|
||
- `sfx_volume`
|
||
- 单镜头真人视频生成支持候选片段:
|
||
- `candidate_count` 限制为 `1-3`。
|
||
- 多候选生成时,默认第 1 条自动绑定到 `StoryboardShot.video_clip_asset_id`。
|
||
- 第 2/3 条只作为候选保留在 `video_clips`,不会覆盖当前 active clip。
|
||
- render task 的 `input_json` 记录:
|
||
- `candidate_index`
|
||
- `candidate_count`
|
||
- `auto_select_clip`
|
||
- 新增候选选择接口:
|
||
- `POST /api/live-action/video-clips/:clipId/select-candidate`
|
||
- 选择后更新分镜:
|
||
- `video_clip_asset_id = clip.output_asset_id`
|
||
- `video_status = video_clip_candidate_selected`
|
||
- 写入 `operation_logs`:
|
||
- `live_action_video_clip_candidate_selected`
|
||
- 记录旧 asset、新 asset、质量分、成本、选择原因。
|
||
- 真人后期新增 SFX 音效轨:
|
||
- 新 task 类型:`live_action_sfx_generate`
|
||
- 新系统音效源标识:`system_scene_sfx_v1`
|
||
- 自动按镜头文本/分数生成 cue:
|
||
- `rain`
|
||
- `footstep`
|
||
- `door`
|
||
- `heartbeat`
|
||
- `sting`
|
||
- SFX 独立生成 audio asset,最终和 BGM / TTS 分轨混音。
|
||
- `post_production` 审计新增:
|
||
- `include_sfx`
|
||
- `sfx_asset_id`
|
||
- `sfx_task_id`
|
||
- `sfx_volume`
|
||
- `sfx_cue_count`
|
||
- `sfx_cues`
|
||
- SFX 音量策略:
|
||
- 默认 `sfx_volume=0.45`
|
||
- SFX 总线增加总增益和限幅,避免“有音效但听不见”。
|
||
|
||
改动文件:
|
||
|
||
- `backend/src/live-action/live-action.dto.ts`
|
||
- `backend/src/live-action/live-action.controller.ts`
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
测试结果:
|
||
|
||
- `npm run typecheck --workspace backend`:通过。
|
||
- `npm run lint --workspace backend`:通过。
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts`:
|
||
- `24 passed`
|
||
- `npm run build --workspace backend`:通过。
|
||
- 后端重启并验证:
|
||
- `/api/health` 返回 `status=ok`
|
||
|
||
实测验收:
|
||
|
||
- 复用项目 `55` / 第 `41` 集《画皮:书生夜遇美人》。
|
||
- 未重新触发 Hailuo 视频生成。
|
||
- 使用参数:
|
||
- `force=true`
|
||
- `include_audio=false`
|
||
- `include_subtitle=false`
|
||
- `include_bgm=true`
|
||
- `include_sfx=true`
|
||
- `bgm_volume=0.055`
|
||
- 生成最终验证版:
|
||
- `render_asset_id=440`
|
||
- 文件:`storage/private/rendered-videos/2026-06-12/78e1b854-c177-41e9-9622-b05146933e69.mp4`
|
||
- 时长:`18.9s`
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`30fps`
|
||
- 音频:`aac / 44100Hz / stereo`
|
||
- SFX 审计:
|
||
- `render_task_id=435`
|
||
- `sfx_task_id=434`
|
||
- `sfx_asset_id=439`
|
||
- `sfx_volume=0.45`
|
||
- `sfx_cue_count=14`
|
||
- SFX 文件:`storage/private/generated-audio/2026-06-12/f5ea97b2-29d5-420d-892d-d0baeeab0b24.wav`
|
||
- 音量检测:
|
||
- 最终成片:`mean_volume=-37.7 dB`,`max_volume=-24.0 dB`
|
||
- SFX 源轨:`mean_volume=-35.5 dB`,`max_volume=-20.1 dB`
|
||
|
||
当前结论:
|
||
|
||
- 候选片段择优的后端闭环已经具备,下一步需要后台 UI 把同一 shot 的候选并排预览出来。
|
||
- SFX 音效轨已可自动生成、落库、审计、混音;对惊悚、雨夜、反转类镜头会明显提升“像真实后期”的感觉。
|
||
- 这一步仍不解决角色漂移和真人表演不自然,后续还要继续做:
|
||
- 后台候选片段并排挑选 UI。
|
||
- 角色锚点图参与关键帧/视频 prompt。
|
||
- 关键镜头候选的人工评分和失败原因回流。
|
||
- 台词镜头仅给必要镜头接 lip-sync,其他继续走旁白/字幕/中景策略。
|
||
|
||
## 2026-06-12 导演分镜 V1 / 连续剪辑优化
|
||
|
||
问题复盘:
|
||
|
||
- 《画皮:书生夜遇美人》目标时长是 `30s`,但当前实际分镜总时长只有 `18.9s`。
|
||
- 当前 6 个镜头分别只有 `2.7-3.8s`,节奏更像“AI 图片快切预告”,不是“真人导演拍摄的一场戏”。
|
||
- 主要问题不是单纯 6 秒不够,而是:
|
||
- 场景跳转太大。
|
||
- 每个镜头都像独立生成。
|
||
- 缺少建立镜头、动作衔接、反应镜头、插入镜头的剪辑组合。
|
||
- 缺少 eyeline / match-on-action / sound bridge 一类连续剪辑信息。
|
||
|
||
完成内容:
|
||
|
||
- 新增导演分镜计划:
|
||
- `LIVE_ACTION_DIRECTOR_PLAN_VERSION=live-action-director-plan-v1`
|
||
- 每个镜头自动标记:
|
||
- `establishing`
|
||
- `movement`
|
||
- `dialogue`
|
||
- `reaction`
|
||
- `insert`
|
||
- `reveal`
|
||
- 真人分镜准备阶段新增目标时长分配:
|
||
- 按 `episode.target_duration` 分配镜头时长。
|
||
- 单镜头限制在 `2.5-8s`。
|
||
- 建立镜头、对白镜头、揭示镜头权重更高。
|
||
- 插入镜头、反应镜头相对更短。
|
||
- 对 episode 41 的 6 镜头测试数据,导演分镜计划会把总时长分配到 `30s`,不是旧版 `18.9s`。
|
||
- 新增连续剪辑字段进入生成提示词:
|
||
- `scene_group_id`
|
||
- `shot_role`
|
||
- `shot_size`
|
||
- `blocking`
|
||
- `continuity_in`
|
||
- `continuity_out`
|
||
- `edit_intent`
|
||
- `sound_bridge`
|
||
- Prompt Builder 升级:
|
||
- Hailuo 中文 prompt 中加入:
|
||
- `导演分镜`
|
||
- `剪辑目的`
|
||
- `连续性`
|
||
- `声音桥`
|
||
- `场景组`
|
||
- 英文/generic prompt 中加入:
|
||
- director beat
|
||
- editing intent
|
||
- continuity in/out
|
||
- sound bridge
|
||
- negative prompt 增加:
|
||
- `montage slideshow look`
|
||
- `unmotivated time jump`
|
||
- `new location jump cut`
|
||
- `prepareLiveActionShots(force=true)` 会写入更强的:
|
||
- `duration`
|
||
- `actor_action`
|
||
- `camera_instruction`
|
||
- `performance_instruction`
|
||
- `live_action_desc`
|
||
- `video_prompt`
|
||
- 导演分镜重写时会清空旧的 `video_clip_asset_id`,避免新分镜继续误用旧短片。
|
||
- 真人视频生成阶段新增 active clip 复用保护:
|
||
- 只复用当前 shot 绑定的 `video_clip_asset_id`。
|
||
- 只复用时长仍匹配当前分镜目标时长的片段。
|
||
- 如果旧片段只有约 `3s`、新导演分镜要求 `5-8s`,会强制重新生成,不再混入旧素材。
|
||
|
||
改动文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/prompt-builder.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `backend/src/live-action/prompt-builder.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
测试结果:
|
||
|
||
- `npm run typecheck --workspace backend`:通过。
|
||
- `npm run lint --workspace backend`:通过。
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`:
|
||
- `28 passed`
|
||
- `npm run build --workspace backend`:通过。
|
||
- 后端重启并验证:
|
||
- `/api/health` 返回 `status=ok`
|
||
|
||
注意事项:
|
||
|
||
- 没有直接把现有《画皮》旧素材重合成为 `30s`。
|
||
- 原因:
|
||
- 旧 Hailuo 视频片段本身只有约 `3s` 一条。
|
||
- 只改分镜目标时长、不重新生成视频,会造成素材时长和目标时长不一致。
|
||
- 正确验证方式是:下一条真实小样先重新执行 `prepareLiveActionShots(force=true)`,再按新时长重新生成视频片段。
|
||
|
||
下一步建议:
|
||
|
||
- 用《画皮》或新的 30 秒测试集重新跑一版真实 Provider:
|
||
- 2 个场景以内。
|
||
- 6-8 个镜头。
|
||
- 总时长严格接近 `30s`。
|
||
- 每个镜头都带导演分镜计划。
|
||
- 后台增加导演分镜审计视图:
|
||
- 显示 shot_role、duration、continuity_in/out、edit_intent、sound_bridge。
|
||
- 后续继续做:
|
||
- 角色锚点图参与关键帧。
|
||
- 候选片段并排挑选 UI。
|
||
- 真实 SFX 素材库替换当前系统合成音效。
|
||
|
||
## 2026-06-12 《画皮》导演分镜版 30 秒真实 Hailuo 小样
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 20:05 Asia/Shanghai
|
||
|
||
目标:
|
||
|
||
- 继续使用公版《聊斋志异·画皮》,但不沿用旧版“夜巷 -> 街市 -> 书斋”跨场景快切结构。
|
||
- 新版只做一场戏:王生深夜隔窗窥见画皮真相。
|
||
- 验证:
|
||
- 导演分镜 V1
|
||
- Hailuo 图生视频
|
||
- FFmpeg 自动裁切
|
||
- MiniMax TTS
|
||
- 字幕
|
||
- BGM
|
||
- SFX 音效轨
|
||
- 质检任务化闭环
|
||
|
||
完成内容:
|
||
|
||
- 新增测试用例:
|
||
- `storage/private/live-action-testcases/painted-skin-director-episode-001.json`
|
||
- 5 个镜头,总目标时长 `30s`
|
||
- 结构:
|
||
- 建立镜头:雨夜书斋窗外
|
||
- 窥视镜头:王生从窗缝看向屋内
|
||
- 插入镜头:铜镜、画笔、人皮轮廓暗示
|
||
- 反应镜头:王生屏息后退
|
||
- 揭示镜头:铜镜中女子发现窗外有人
|
||
- 导入新测试项目:
|
||
- `project_id=57`
|
||
- `episode_id=43`
|
||
- `shot_id=248-252`
|
||
- 执行导演分镜准备:
|
||
- 镜头时长重新分配为:
|
||
- `7.66s`
|
||
- `4.08s`
|
||
- `7.09s`
|
||
- `4.08s`
|
||
- `7.09s`
|
||
- 合计约 `30s`
|
||
- 为新项目复制并绑定旧《画皮》场景 PNG 关键帧:
|
||
- `441-445`
|
||
- 仅用于低成本验证导演分镜和后期链路,未重新生成全新导演级首帧。
|
||
- 使用真实 Hailuo 生成 5 个视频片段:
|
||
- `clip_id=44` / `asset_id=446` / `0.317 USD`
|
||
- `clip_id=45` / `asset_id=447` / `0.1902 USD`
|
||
- `clip_id=46` / `asset_id=448` / `0.317 USD`
|
||
- `clip_id=47` / `asset_id=449` / `0.1902 USD`
|
||
- `clip_id=48` / `asset_id=450` / `0.317 USD`
|
||
- 合成最终成片:
|
||
- `render_asset_id=455`
|
||
- 文件:`storage/private/rendered-videos/2026-06-12/e2cdb72c-d6d0-45e8-b3c5-ca8de2cd488d.mp4`
|
||
- `render_task_id=450`
|
||
|
||
验收结果:
|
||
|
||
- Hailuo 生成:
|
||
- 成功:`5/5`
|
||
- 失败:`0/5`
|
||
- 真实视频成本合计:`1.3314 USD`
|
||
- 最终成片规格:
|
||
- 视频:H.264
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`30fps`
|
||
- 视频时长:`30.000000s`
|
||
- 音频:AAC stereo
|
||
- 音频时长:`30.000000s`
|
||
- 文件大小:约 `11.8MB`
|
||
- 音频检测:
|
||
- `mean_volume=-19.3 dB`
|
||
- `max_volume=-2.9 dB`
|
||
- 不再是静音成片。
|
||
- 后期层:
|
||
- `audio_is_mock=false`
|
||
- `audio_provider_codes=["minimax-tts"]`
|
||
- `subtitle_cue_count=5`
|
||
- `sfx_cue_count=13`
|
||
- `include_bgm=true`
|
||
- `include_sfx=true`
|
||
- `audio_warnings=[]`
|
||
- FFmpeg 裁切:
|
||
- 5 个 Hailuo 原始片段全部按分镜目标时长裁切。
|
||
- `10.125s` 原始片段裁为约 `7.1-7.67s`。
|
||
- `5.875s` 原始片段裁为约 `4.07s`。
|
||
- 质检任务补跑:
|
||
- `clip_id=44`:`passed / 94`
|
||
- `clip_id=45`:`passed / 94`
|
||
- `clip_id=46`:`passed / 94`
|
||
- `clip_id=47`:`passed / 94`
|
||
- `clip_id=48`:`needs_retry / 72`
|
||
- 第 5 镜被 mock-qc 的恐怖/画皮关键词打低分,原因包含 `mock_quality_keyword` 和 `AUTO_REPAIR_DISABLED`。
|
||
|
||
人工抽帧观感:
|
||
|
||
- 对比旧版 `18.9s` 快切,节奏明显更接近“一场戏”:
|
||
- 建立镜头 -> 窥视 -> 插入 -> 反应 -> 揭示
|
||
- 字幕、音轨、雨声、心跳和 sting 已经形成完整后期层。
|
||
- 仍未达到发布级:
|
||
- 第 2/4 镜复用了同一张窗外关键帧,画面重复感明显。
|
||
- 第 3/5 镜复用了同一张揭示关键帧,结尾缺少真正“镜中抬眼”的新动作起点。
|
||
- 关键帧不是为新版 5 镜专门生成,所以视频仍像“旧素材重新导演剪辑”,不是完整专业拍摄。
|
||
- 第 5 镜需要人工看画面决定是否接受,当前系统质检状态是 `needs_retry`。
|
||
|
||
修改文件:
|
||
|
||
- `storage/private/live-action-testcases/painted-skin-director-episode-001.json`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- `jq empty storage/private/live-action-testcases/painted-skin-director-episode-001.json`:通过。
|
||
- `npm run live-action:testcase:import --workspace backend -- --file=/www/wwwroot/ai/storage/private/live-action-testcases/painted-skin-director-episode-001.json --replace=true`:通过。
|
||
- Nest ApplicationContext 调用:
|
||
- `prepareLiveActionShots(force=true)`
|
||
- 复制并绑定关键帧资产
|
||
- `preflightVideoClips`
|
||
- `generateShotVideoClip`
|
||
- `renderLiveActionEpisode`
|
||
- `executeQueuedRouterTask` 补跑质检任务
|
||
- `ffprobe`:通过,最终视频/音频均为 `30s`。
|
||
- `ffmpeg volumedetect`:通过,非静音。
|
||
- `npm run typecheck --workspace backend`:通过。
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`:
|
||
- `28 passed`
|
||
- `npm run lint --workspace backend`:通过。
|
||
- `npm run build --workspace backend`:通过。
|
||
- `/api/health`:返回 `status=ok`。
|
||
|
||
当前结论:
|
||
|
||
- “继续用画皮”是合适的,因为它能稳定暴露古风真人短剧的关键问题:角色、场景、镜头连续性、惊悚后期和揭示镜头质量。
|
||
- 导演分镜 V1 有效,30 秒成片节奏比旧快切版更顺。
|
||
- 但这版不能算最终 PASS,原因不是 Hailuo 接入失败,而是关键帧不够精细:
|
||
- 必须为每个镜头单独生成“导演级场景首帧”。
|
||
- 不能复用同一张关键帧承担不同剪辑功能。
|
||
|
||
下一步建议:
|
||
|
||
- 继续围绕《画皮》做“导演级关键帧 V1”:
|
||
- 为 `248-252` 每个镜头重新生成专属首帧。
|
||
- 第 5 镜单独生成“铜镜中女子抬眼”的首帧。
|
||
- 再只重跑第 2/4/5 镜,先不全片重跑。
|
||
- 后台增加关键帧验收:每个镜头生成视频前先人工确认首帧是否符合导演分镜。
|
||
|
||
## 2026-06-12 《画皮》导演级关键帧 V1 / 局部重跑
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 20:25 Asia/Shanghai
|
||
|
||
目标:
|
||
|
||
- 继续优化 `project_id=57` / `episode_id=43` 的《画皮:书斋窥真》导演分镜版。
|
||
- 不全片重跑,只针对上一版问题最明显的镜头重新生成导演级首帧并重跑:
|
||
- 第 2 镜:窗缝窥看
|
||
- 第 4 镜:王生反应
|
||
- 第 5 镜:铜镜回望反转
|
||
- 验证是否能降低“复用旧关键帧导致的重复镜头感”。
|
||
|
||
完成内容:
|
||
|
||
- 使用 `imagegen` 生成 3 张新 PNG 首帧:
|
||
- 第 2 镜:over-the-shoulder 窗缝窥看,明确王生视线和屋内女子空间关系。
|
||
- 第 4 镜:王生中近景反应,独立于第 2 镜,不再复用同构窗外画面。
|
||
- 第 5 镜:铜镜中女子抬眼回望,作为真正的结尾反转首帧。
|
||
- 上传并绑定新关键帧:
|
||
- `shot_id=249` -> `asset_id=456`
|
||
- `shot_id=251` -> `asset_id=457`
|
||
- `shot_id=252` -> `asset_id=458`
|
||
- 只重跑 3 条 Hailuo 真实片段:
|
||
- `shot_id=249` -> `clip_id=49` / `asset_id=459` / `0.1902 USD`
|
||
- `shot_id=251` -> `clip_id=50` / `asset_id=460` / `0.1902 USD`
|
||
- `shot_id=252` -> `clip_id=51` / `asset_id=461` / `0.317 USD`
|
||
- 新增真实视频成本:
|
||
- `0.6974 USD`
|
||
- 重新合成最终成片:
|
||
- `render_asset_id=466`
|
||
- 文件:`storage/private/rendered-videos/2026-06-12/5785a058-7ebf-423f-8822-80c3ce4bdcdc.mp4`
|
||
- `render_task_id=461`
|
||
|
||
验收结果:
|
||
|
||
- 最终成片规格:
|
||
- 视频:H.264
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`30fps`
|
||
- 视频时长:`30.000000s`
|
||
- 音频:AAC stereo
|
||
- 音频时长:`30.000000s`
|
||
- 文件大小:约 `12MB`
|
||
- 音频检测:
|
||
- `mean_volume=-19.5 dB`
|
||
- `max_volume=-1.4 dB`
|
||
- 音轨正常,非静音。
|
||
- 质检结果:
|
||
- `clip_id=49`:`passed / 94`
|
||
- `clip_id=50`:`passed / 94`
|
||
- `clip_id=51`:`needs_retry / 72`
|
||
- 第 5 镜仍被 mock-qc 按“画皮/揭示”关键词打低分,当前不自动重跑,等待人工看画面决定。
|
||
- FFmpeg 裁切:
|
||
- 新片段均按业务分镜时长裁切:
|
||
- 第 2 镜:`5.875s -> 4.067s`
|
||
- 第 4 镜:`5.875s -> 4.067s`
|
||
- 第 5 镜:`10.125s -> 7.1s`
|
||
|
||
人工抽帧观感:
|
||
|
||
- 明显改善:
|
||
- 第 2 镜和第 4 镜不再是同一张窗外窥视图的重复。
|
||
- 第 2 镜承担“视线关系 / 王生看见屋内”的功能。
|
||
- 第 4 镜承担“王生反应 / 控制恐惧”的功能。
|
||
- 第 5 镜变成真正的“镜中凝视 / 被发现”反转镜头。
|
||
- 仍未达到最终发布级:
|
||
- 第 3 镜仍沿用旧“贴脸画皮”图,和新版第 5 镜空间衔接略硬。
|
||
- 第 3 镜应该改成真正的插入特写:画笔、铜镜边缘、苍白纸/面皮轮廓、女子手部,而不是人物正面恐怖动作。
|
||
- 第 5 镜质检状态仍是 `needs_retry`,需要人工观看实际视频后决定是否接受或再生成 1 条候选。
|
||
|
||
新增 / 变更资产:
|
||
|
||
- 新关键帧:
|
||
- `456`:`local://image/2026-06-12/1c4de6c5-a187-43e0-baa2-8d0f52d799eb.png`
|
||
- `457`:`local://image/2026-06-12/de392947-fc73-4ad4-b8cc-0f96cdfe8548.png`
|
||
- `458`:`local://image/2026-06-12/acd2eea1-094a-4ab4-a5a7-2dda68e7fe16.png`
|
||
- 新视频片段:
|
||
- `459`
|
||
- `460`
|
||
- `461`
|
||
- 新最终成片:
|
||
- `466`
|
||
|
||
修改文件:
|
||
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行 / 验证:
|
||
|
||
- `ffprobe`:通过,最终视频/音频均为 `30s`。
|
||
- `ffmpeg volumedetect`:通过,非静音。
|
||
- 抽帧接触图:
|
||
- `/tmp/painted-skin-director/final-asset-466/contact.jpg`
|
||
- `/tmp/painted-skin-director/final-asset-466/frame-27s.jpg`
|
||
|
||
当前结论:
|
||
|
||
- “导演级首帧”方向是有效的。
|
||
- 后续系统不应该只写 prompt 后直接生成视频,而应该多一步:
|
||
- 分镜角色:establishing / POV / insert / reaction / reveal
|
||
- 每种角色生成对应首帧
|
||
- 首帧人工确认
|
||
- 再进入 Hailuo / Kling 视频生成
|
||
- 下一步最适合补第 3 镜“插入特写首帧”,只重跑第 3 镜和最终合成,不全片重跑。
|
||
|
||
## 2026-06-12 法相天地 10 秒爆点样片 / Hailuo 真实生成
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 20:55 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户暂停《画皮》优化,要求按提供的“法相天地三段分镜提示词”做一条 10 秒样片,对比抖音强视觉爆点效果。
|
||
- 本轮不做剧情完整性,只验证:
|
||
- 强动作
|
||
- 强运镜
|
||
- 仙侠 VFX
|
||
- 音效冲击
|
||
- Hailuo 对高价值爆点镜头的表现
|
||
|
||
完成内容:
|
||
|
||
- 新增法相天地测试用例:
|
||
- `storage/private/live-action-testcases/faxiang-tiandi-episode-001.json`
|
||
- 项目名:`法相天地:千臂法身`
|
||
- `project_id=58`
|
||
- `episode_id=44`
|
||
- 镜头:
|
||
- `shot_id=253`:浴血惊鸿,`3s`
|
||
- `shot_id=254`:繁花结印,`3s`
|
||
- `shot_id=255`:法身降临,`4s`
|
||
- 生成 3 张专属关键帧:
|
||
- 浴血落地
|
||
- 手部结印 + 紫色光球
|
||
- 低机位千臂法身
|
||
- 上传并绑定关键帧:
|
||
- `asset_id=467`
|
||
- `asset_id=468`
|
||
- `asset_id=469`
|
||
- 扩展真人后期 SFX 规则:
|
||
- 新增 `wind`
|
||
- 新增 `debris`
|
||
- 新增 `electric`
|
||
- 新增 `impact`
|
||
- 用于法相、灵力、电流、碎石、轰鸣、低频冲击类镜头。
|
||
- 使用真实 Hailuo 生成 3 条视频片段:
|
||
- `clip_id=52` / `asset_id=470` / `0.1902 USD`
|
||
- `clip_id=53` / `asset_id=471` / `0.1902 USD`
|
||
- `clip_id=54` / `asset_id=472` / `0.1902 USD`
|
||
- 第一次合成:
|
||
- `asset_id=475`
|
||
- 文件:`storage/private/rendered-videos/2026-06-12/36971308-23f7-4bc8-8db5-dfb3a8be8484.mp4`
|
||
- 因音效电平偏弱,未重跑 Hailuo,只重新合成更大声 SFX/BGM 版:
|
||
- `asset_id=478`
|
||
- 文件:`storage/private/rendered-videos/2026-06-12/84977037-fe9b-4211-8e7e-c92a63de2d9b.mp4`
|
||
|
||
验收结果:
|
||
|
||
- Hailuo 生成:
|
||
- 成功:`3/3`
|
||
- 失败:`0`
|
||
- 真实视频成本:`0.5706 USD`
|
||
- 质检:
|
||
- `clip_id=52`:`passed / 94`
|
||
- `clip_id=53`:`passed / 94`
|
||
- `clip_id=54`:`passed / 94`
|
||
- 最终成片规格:
|
||
- 分辨率:`1080x1920`
|
||
- 帧率:`30fps`
|
||
- 时长:`10.000000s`
|
||
- 视频编码:H.264
|
||
- 音频编码:AAC
|
||
- 字幕:无
|
||
- TTS:无
|
||
- BGM:有
|
||
- SFX:有
|
||
- FFmpeg 裁切:
|
||
- 3 条 Hailuo 原始片段均约 `5.875s`
|
||
- 分别裁切到 `3s / 3s / 4s`
|
||
- SFX:
|
||
- 生成 `15` 个音效点。
|
||
- 包含:
|
||
- `wind`
|
||
- `debris`
|
||
- `electric`
|
||
- `impact`
|
||
- `heartbeat`
|
||
- `sting`
|
||
- 音量检测:
|
||
- 第一版 `asset_id=475`:
|
||
- `mean_volume=-28.8 dB`
|
||
- `max_volume=-16.9 dB`
|
||
- 增强版 `asset_id=478`:
|
||
- `mean_volume=-25.2 dB`
|
||
- `max_volume=-12.6 dB`
|
||
|
||
人工抽帧观感:
|
||
|
||
- 整体比《画皮》更接近抖音爆点视频。
|
||
- 第 3 镜“法身降临”效果最好:
|
||
- 低机位仰拍成立。
|
||
- 千臂法身规模感明显。
|
||
- 白裙女仙和巨大法身的比例关系有压迫感。
|
||
- 第 2 镜“繁花结印”稳定:
|
||
- 手部和紫色光球清晰。
|
||
- 适合做中段能量聚集。
|
||
- 第 1 镜“浴血惊鸿”首帧强,但后续仍需人工看完整视频判断动作幅度:
|
||
- 如果动作偏小,下一步只重跑第 1 镜,生成 2 条候选,选落地/推眼动作更强的一条。
|
||
- 当前仍未达到商业发布级的原因:
|
||
- 系统合成 SFX 不如真实商业音效库炸裂。
|
||
- 三镜之间仍偏“高级概念镜头拼接”,还不是完整武指/剪辑师调过的动作连续段。
|
||
- Hailuo 对复杂千臂法身能保住大画面,但细看手臂细节可能仍有 AI 感。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `storage/private/live-action-testcases/faxiang-tiandi-episode-001.json`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- `jq empty storage/private/live-action-testcases/faxiang-tiandi-episode-001.json`:通过。
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts`:
|
||
- `27 passed`
|
||
- `npm run typecheck --workspace backend`:通过。
|
||
- `npm run lint --workspace backend`:通过。
|
||
- `npm run build --workspace backend`:通过。
|
||
- `ffprobe`:通过,最终视频/音频均为 `10s`。
|
||
- `ffmpeg volumedetect`:通过,非静音。
|
||
- 抽帧接触图:
|
||
- `/tmp/faxiang-tiandi/final-asset-478/contact.jpg`
|
||
- `/tmp/faxiang-tiandi/final-asset-478/frame-8_5s.jpg`
|
||
|
||
当前结论:
|
||
|
||
- 对比《画皮》,法相天地这种强 VFX 题材更容易获得“第一眼爆点”。
|
||
- 现有流水线已经能生成 10 秒高冲击仙侠样片,但要接近抖音成熟爆款,还需要:
|
||
- 关键镜头候选片段择优。
|
||
- 商业音效库 / 音乐素材库。
|
||
- Motion Director Prompt V1,把每镜内部 0-1s / 1-2s / 2-3s 动作节奏写进 prompt。
|
||
|
||
## 2026-06-12 法相天地 Motion Director Prompt V1 / 动作导演层
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 21:08 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户反馈当前法相天地样片质量与抖音热门“法相天地”差距很大:
|
||
- 热门动作没有。
|
||
- 结印手法没有。
|
||
- 镜头仍偏静态概念图运动,缺少武指 / 动作导演 / 剪辑节奏。
|
||
- 公开搜索 `sholi888` / 抖音法相天地相关结果时,抖音详情页无法稳定直接观看,但能确认该类爆点视频的核心不是单纯“法相出现”,而是:
|
||
- 明确手部结印动作。
|
||
- 睁眼 / 爆光 / 抬头 / 展臂等强动作卡点。
|
||
- 低机位、快速推进、拉远显规模。
|
||
- 音效与动作同步卡点。
|
||
- 本轮不继续消耗真实 Hailuo 额度,先修系统 Prompt Engine。
|
||
|
||
完成内容:
|
||
|
||
- 在真人视频 Prompt Engine 中新增 `motion_director` 结构化组件:
|
||
- `motion_version`
|
||
- `beat_style`
|
||
- `action_technique`
|
||
- `time_beats`
|
||
- `camera_rhythm`
|
||
- `vfx_timing`
|
||
- `sound_hits`
|
||
- `negative_motion`
|
||
- 为 `xianxia_transformation` 增加 3 类动作导演模板:
|
||
- 浴血落地 / 抬头爆眼:
|
||
- 凌空翻身落地。
|
||
- 手掌和膝盖触地。
|
||
- 碎石震开。
|
||
- 镜头极速推进到眼部。
|
||
- 繁花结印 / 紫色光球:
|
||
- 手部特写。
|
||
- 食指中指并拢交错。
|
||
- 手腕翻转。
|
||
- 拇指扣成莲花印。
|
||
- 紫色光球随第二次手印出现,最后双掌震出爆亮。
|
||
- 千臂法身 / 法相降临:
|
||
- 女仙双臂像凤凰展翅一样展开。
|
||
- 透明法身从地面升起。
|
||
- 千只巨手一层层展开并结印。
|
||
- 地裂、碎石上浮、粉化按时间递进。
|
||
- Hailuo / Kling / Generic / Mock prompt 均会输出动作导演字段。
|
||
- `negative_prompt` 自动加入动作禁忌,例如:
|
||
- `random hand waving`
|
||
- `blurred fingers`
|
||
- `static magical orb only`
|
||
- `tiny dharma body`
|
||
- `static statue behind actor`
|
||
- 修正识别优先级:
|
||
- 出现 `法相 / 法身 / 千臂 / 巨手` 时优先走“法身降临”模板。
|
||
- 避免因为“千只巨手结印”被误判为普通手部结印镜头。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/prompt-builder.service.ts`
|
||
- `backend/src/live-action/prompt-builder.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- `npm run test --workspace backend -- prompt-builder.service.spec.ts`:
|
||
- `4 passed`
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts`:
|
||
- `27 passed`
|
||
- `npm run typecheck --workspace backend`:通过。
|
||
- `npm run lint --workspace backend`:通过。
|
||
- `npm run build --workspace backend`:通过。
|
||
|
||
当前结论:
|
||
|
||
- 这轮没有重跑真实视频,没有新增 Hailuo 成本。
|
||
- 之前样片质量差的根因已定位为:
|
||
- 不是单纯 Provider 不行。
|
||
- 也不是分镜秒数问题本身。
|
||
- 而是 Prompt Engine 缺少“动作导演层”,没有把 3-4 秒内的热门动作拆成模型可执行的时间节奏。
|
||
- 下一步建议只重跑第 2 镜“繁花结印”和第 3 镜“法身降临”:
|
||
- 使用新版 Motion Director Prompt。
|
||
- 默认每镜只生成 1 条,控制成本。
|
||
- 如果仍达不到标准,再考虑关键镜头候选片段择优。
|
||
|
||
## 2026-06-12 法相天地 BGM Director V1 / 剧情驱动配乐
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 21:24 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户指出当前法相天地样片缺少 BGM 音乐带来的情绪推进:
|
||
- 没有音乐,爆点效果少一半。
|
||
- BGM 需要根据剧情和镜头插入,而不是简单铺一条环境底音。
|
||
- 本轮不重跑 Hailuo 视频片段,先升级后期合成系统,并用已有真实 Hailuo 片段重新合成验证。
|
||
|
||
完成内容:
|
||
|
||
- 新增 BGM Director V1:
|
||
- `LiveActionBgmCue`
|
||
- `LiveActionBgmCueType`
|
||
- `buildLiveActionBgmCues`
|
||
- `createLiveActionCueBgmTrack`
|
||
- 系统会根据分镜自动生成 BGM cue:
|
||
- `urban_drama`:普通都市剧情底乐。
|
||
- `suspense_tension`:悬疑 / 惊悚 / 高情绪张力。
|
||
- `xianxia_tension`:仙侠开场压迫、废墟、狂风、浴血。
|
||
- `xianxia_build_up`:结印、聚能、光球、电流。
|
||
- `xianxia_epic`:法相 / 法身 / 千臂 / 威压 / 史诗爆发。
|
||
- 法相天地 3 镜自动识别为:
|
||
- `0-3s`:`xianxia_tension`
|
||
- `3-6s`:`xianxia_build_up`
|
||
- `6-10s`:`xianxia_epic`
|
||
- `live_action_bgm_generate` 任务会记录:
|
||
- `cue_count`
|
||
- `cues`
|
||
- `bgm_source`
|
||
- `duration_seconds`
|
||
- `live_action_video_render` 的 `post_production` 审计新增:
|
||
- `bgm_cue_count`
|
||
- `bgm_cues`
|
||
- BGM / SFX 默认音量改为自动策略:
|
||
- 有对白:BGM 自动压低,避免盖住人声。
|
||
- 无对白仙侠爆点:BGM / SFX 自动提高,适合测试强视觉爆点。
|
||
- 仍保留 `bgm_volume` / `sfx_volume` 人工 override。
|
||
|
||
生成验证:
|
||
|
||
- 未重跑 Hailuo,未新增真实视频 Provider 成本。
|
||
- 用已有真实片段重新合成两版:
|
||
- `asset_id=481`
|
||
- 文件:`storage/private/rendered-videos/2026-06-12/67809a8c-3bac-44ea-9c63-d5134f9b680b.mp4`
|
||
- `bgm_volume=0.32`
|
||
- `sfx_volume=0.85`
|
||
- `mean_volume=-25.7 dB`
|
||
- `max_volume=-11.3 dB`
|
||
- `asset_id=484`
|
||
- 文件:`storage/private/rendered-videos/2026-06-12/f372bfb3-fdb4-4fee-a212-353f73d3bbf0.mp4`
|
||
- `bgm_volume=0.55`
|
||
- `sfx_volume=0.95`
|
||
- `mean_volume=-22.1 dB`
|
||
- `max_volume=-7.7 dB`
|
||
- 当前建议优先查看 `asset_id=484`,这是无对白爆点测试更接近短视频观感的一版。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`:
|
||
- `32 passed`
|
||
- `npm run typecheck --workspace backend`:通过。
|
||
- `npm run lint --workspace backend`:通过。
|
||
- `npm run build --workspace backend`:通过。
|
||
- `ffprobe asset_id=484`:
|
||
- `10.000000s`
|
||
- `1080x1920`
|
||
- `30fps`
|
||
- `H.264 + AAC`
|
||
- `ffmpeg volumedetect asset_id=484`:
|
||
- `mean_volume=-22.1 dB`
|
||
- `max_volume=-7.7 dB`
|
||
|
||
当前结论:
|
||
|
||
- 系统后期从“有无 BGM”升级为“按分镜剧情自动配乐”。
|
||
- 对法相天地这类测试片,后续不需要前端手动传音量也能获得更强的默认音乐冲击。
|
||
- 下一步可以进入低成本视频质量复测:
|
||
- 用新版 Motion Director Prompt 重跑第 1 镜 / 第 2 镜 / 第 3 镜。
|
||
- 每镜默认 1 条,继续控制成本。
|
||
- 对比 `asset_id=484` 的后期版本,看问题是否主要剩在画面动作本身。
|
||
|
||
## 2026-06-12 法相天地 Motion Director 真实重跑 / Hailuo 三镜复测
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 21:36 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户确认测试优化阶段可以继续重跑,只要系统质量有进步。
|
||
- 本轮目标:
|
||
- 用新版 Motion Director Prompt 重跑第 1 / 2 / 3 镜。
|
||
- 每镜只生成 1 条,控制成本。
|
||
- 用 BGM Director V1 自动配乐重新合成。
|
||
- 检查动作导演提示词是否真实进入 Hailuo 请求。
|
||
|
||
执行内容:
|
||
|
||
- 固定真实 Provider:
|
||
- `minimax_hailuo_23_fast`
|
||
- `confirm_real_video=true`
|
||
- `max_cost_per_clip=0.3`
|
||
- `candidate_count=1`
|
||
- 重跑镜头:
|
||
- 第 1 镜 `shot_id=253`:浴血惊鸿
|
||
- 第 2 镜 `shot_id=254`:繁花结印
|
||
- 第 3 镜 `shot_id=255`:法身降临
|
||
- 新生成片段:
|
||
- `clip_id=55` / `asset_id=485` / `0.1902 USD`
|
||
- `clip_id=56` / `asset_id=486` / `0.1902 USD`
|
||
- `clip_id=57` / `asset_id=487` / `0.1902 USD`
|
||
- 本轮新增真实视频成本:
|
||
- `0.5706 USD`
|
||
- 队列质检任务:
|
||
- `task_id=481`
|
||
- `task_id=483`
|
||
- `task_id=485`
|
||
- 由于 worker 未实时消费,手动通过正式 `executeQueuedRouterTask` 执行 3 个 pending 质检任务。
|
||
- 质检结果:
|
||
- `clip_id=55`:`passed / 94`
|
||
- `clip_id=56`:`passed / 94`
|
||
- `clip_id=57`:`passed / 94`
|
||
|
||
关键 Prompt 验收:
|
||
|
||
- 第 1 镜真实请求已包含:
|
||
- `凌空翻身`
|
||
- `手掌和膝盖触地滑停`
|
||
- `碎石被冲击震开`
|
||
- `镜头极速推进到眼部特写`
|
||
- `瞳孔金光爆亮`
|
||
- 第 2 镜真实请求已包含:
|
||
- `食指中指并拢交错`
|
||
- `手腕快速翻转`
|
||
- `拇指扣成莲花印`
|
||
- `双掌向外一震`
|
||
- `紫色光球在第二次手印后出现`
|
||
- 第 3 镜真实请求已包含:
|
||
- `女仙双臂像凤凰展翅一样猛然后扫`
|
||
- `身后千臂法身随动作拔地而起`
|
||
- `每一层巨手依次结出不同仙印`
|
||
- `地裂 / 碎石失重上浮 / 粉化三层递进`
|
||
|
||
最终成片:
|
||
|
||
- `asset_id=490`
|
||
- 文件:
|
||
- `storage/private/rendered-videos/2026-06-12/24e4df88-0041-4547-bdfd-30249093c08e.mp4`
|
||
- 规格:
|
||
- `10.000000s`
|
||
- `1080x1920`
|
||
- `30fps`
|
||
- `H.264 + AAC`
|
||
- 音量检测:
|
||
- `mean_volume=-22.1 dB`
|
||
- `max_volume=-7.7 dB`
|
||
- 后期:
|
||
- `BGM cue_count=3`
|
||
- `SFX cue_count=15`
|
||
- `bgm_volume=0.55`
|
||
- `sfx_volume=0.95`
|
||
- 裁切:
|
||
- Hailuo 原片均约 `5.875s`
|
||
- 合成时裁到 `3s / 3s / 4s`
|
||
- `trim_strategy=head`
|
||
- 抽帧接触图:
|
||
- `/tmp/faxiang-tiandi/final-asset-490/contact.jpg`
|
||
|
||
人工抽帧观感:
|
||
|
||
- 对比上一版,进步明显:
|
||
- 第 1 镜已经能看到落地、撑地、尘土和身体动作。
|
||
- 第 2 镜有清晰手部近景和结印动作构图。
|
||
- 第 3 镜法身规模、爆光和压迫感增强。
|
||
- 仍未达到顶级抖音爆款的原因:
|
||
- 手指结印虽然有构图,但是否精确到“漂亮手法”还要看完整视频动态。
|
||
- Hailuo 对复杂手部动作和千臂细节仍可能有 AI 变形风险。
|
||
- 目前还缺商业级真实音乐库 / 打击音效库,系统生成音频已经能铺情绪,但不是最终商用音效品质。
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`:失败,当前目录不是 Git 仓库。
|
||
- `ffprobe asset_id=490`:通过。
|
||
- `ffmpeg volumedetect asset_id=490`:通过。
|
||
- 抽帧接触图人工检查:通过。
|
||
- 目标测试在上一阶段已通过:
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`
|
||
- `32 passed`
|
||
- `typecheck / lint / build` 均通过。
|
||
|
||
当前结论:
|
||
|
||
- 本轮验证 Motion Director Prompt 已真实进入 Hailuo 请求。
|
||
- 法相天地样片从“静态概念图拼接”提升到“有动作层级的爆点片段”。
|
||
- 现在最值得人工打开 `asset_id=490` 看完整动态:
|
||
- 如果第 2 镜手势动态仍不够漂亮,下一步不要继续调普通 prompt,而应做“手部结印关键帧 / 手势参考图 V1”。
|
||
- 如果第 3 镜法身动作仍不够炸,下一步考虑只给第 3 镜开候选 2 条,或等 Kling / Vidu / Wan 真实账号接入后做横向 Provider 对比。
|
||
|
||
## 2026-06-12 法相天地 10 秒一镜到底 / Hailuo 真实生成
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 21:56 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户指出 3 段式法相天地仍然割裂:
|
||
- 切镜太多,像图片拼接。
|
||
- 翻滚落地、结印手法、法身爆发不够像抖音热门作品。
|
||
- Hailuo 支持 10s,不应继续把 6s 片段裁成 3s/3s/4s。
|
||
- 本轮目标:
|
||
- 把“浴血落地 -> 抬头觉醒 -> 双手结印 -> 紫色光球 -> 展臂 -> 千臂法身”压成 10 秒一镜到底。
|
||
- 验证真实 Hailuo API 是否按 10s 返回。
|
||
- 检查 Prompt Engine 是否把完整动作节奏写进请求。
|
||
|
||
代码改动:
|
||
|
||
- `backend/src/live-action/prompt-builder.service.ts`
|
||
- Hailuo 9 秒以上镜头 prompt 上限从 `1800` 提升到 `2400`。
|
||
- 新增 10 秒一镜到底仙侠爆点 Motion Director:
|
||
- `0.0-2.0s` 受伤落地 / 撑地 / 碎石冲击
|
||
- `2.0-3.0s` 抬头 / 眼部金光 / 快速推进
|
||
- `3.0-5.0s` 双手胸前结印 / 莲花印动作
|
||
- `5.0-6.5s` 紫色光球聚能
|
||
- `6.5-8.0s` 凤凰展臂 / 千臂法身拔地
|
||
- `8.0-10.0s` 法身完全展开 / 爆光定格
|
||
- `backend/src/live-action/prompt-builder.service.spec.ts`
|
||
- 新增 Hailuo 10 秒一镜到底 prompt 测试。
|
||
|
||
测试数据:
|
||
|
||
- 项目:
|
||
- `project_id=58`
|
||
- 新建测试集:
|
||
- `episode_id=45`
|
||
- `episode_no=2`
|
||
- 标题:`法相天地 10秒一镜到底测试`
|
||
- 新建测试镜头:
|
||
- `shot_id=256`
|
||
- `duration=10`
|
||
- `scene_type=xianxia_transformation`
|
||
- `route_tier=premium`
|
||
- `importance/emotion/action = 10/10/10`
|
||
- 关键帧:`asset_id=467`
|
||
|
||
真实 Provider 执行:
|
||
|
||
- Provider:
|
||
- `minimax_hailuo_23_fast`
|
||
- `confirm_real_video=true`
|
||
- `candidate_count=1`
|
||
- `max_cost_per_clip=0.5`
|
||
- 真实片段:
|
||
- `clip_id=58`
|
||
- `output_asset_id=491`
|
||
- `provider_log.id=535`
|
||
- `request_input.duration=10`
|
||
- `response.duration=10`
|
||
- `cost_actual=0.317 USD`
|
||
- 结论:
|
||
- Hailuo 本次确实返回 10 秒视频。
|
||
- 不再发生 6 秒片段被裁成 3 秒/4 秒的问题。
|
||
|
||
质检与合成:
|
||
|
||
- 队列质检任务:
|
||
- `task_id=490`
|
||
- `live_action_video_clip_quality_check`
|
||
- 手动执行队列质检:
|
||
- `status=success`
|
||
- `quality_status=passed`
|
||
- `quality_score=94`
|
||
- `issues=[]`
|
||
- 最终成片:
|
||
- `asset_id=494`
|
||
- 文件:
|
||
- `storage/private/rendered-videos/2026-06-12/ca7b56a7-1995-4197-9dc5-ca4e45dad14a.mp4`
|
||
- 规格:
|
||
- `10.000000s`
|
||
- `1080x1920`
|
||
- `30fps`
|
||
- `H.264 + AAC`
|
||
- 裁切:
|
||
- `trimmed=false`
|
||
- `source_duration=10.125`
|
||
- `final_duration=10.134`
|
||
- `target_duration=10`
|
||
- 后期:
|
||
- `BGM cue_count=1`
|
||
- `SFX cue_count=6`
|
||
- `bgm_volume=0.55`
|
||
- `sfx_volume=0.95`
|
||
- 音量检测:
|
||
- `mean_volume=-27.2 dB`
|
||
- `max_volume=-13.9 dB`
|
||
- 抽帧接触图:
|
||
- `/tmp/faxiang-tiandi/final-asset-494/contact.jpg`
|
||
|
||
人工抽帧观感:
|
||
|
||
- 明显改善:
|
||
- 人物、服装、废墟空间在 10 秒内基本连续。
|
||
- 镜头从受伤跪地、眼部发光、手部聚能、法身爆发有完整递进。
|
||
- 千臂法身最后 2 秒的画面冲击比三段式更完整。
|
||
- 仍未达到抖音头部爆款:
|
||
- “凌空翻滚落地”被 Hailuo 弱化成跪地/滑落/撑地,缺少真正空中翻身动作。
|
||
- 结印有近景和手部动作,但还不像专业武术/舞蹈手诀。
|
||
- BGM/SFX 已进入合成,但本轮音量偏低,发布级还需要更强音乐和打击音量。
|
||
- 这说明单纯调文字 prompt 有上限;下一步若继续冲击热门质感,应加“动作参考 / 姿势关键帧 / Provider 横向对比”。
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`
|
||
- 失败:当前目录不是 Git 仓库。
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts prompt-builder.service.spec.ts`
|
||
- 通过:`33 passed`
|
||
- `npm run typecheck --workspace backend`
|
||
- 通过
|
||
- `npm run lint --workspace backend`
|
||
- 通过
|
||
- `npm run build --workspace backend`
|
||
- 通过
|
||
|
||
当前结论:
|
||
|
||
- 系统层面:
|
||
- 10 秒单镜头 Hailuo 流程已跑通。
|
||
- Prompt Engine 可以按 10 秒动作节奏发送真实请求。
|
||
- 真实 Provider、质检任务、FFmpeg 合成、音效轨、审计记录均可闭环。
|
||
- 质量层面:
|
||
- 10 秒一镜到底方向比 3 段裁切更适合法相天地这类爆点镜头。
|
||
- 但 Hailuo 对“凌空翻滚 + 精准结印 + 巨型法身复杂动作”的可控性仍不足。
|
||
- 后续不建议继续无脑烧 Hailuo 多次重跑;更优先做动作/姿势参考输入和 Kling/Vidu/Wan 横向 Provider 小样。
|
||
|
||
## 2026-06-12 后台 AI 平台 10 秒成本展示
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 22:15 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户希望后台 AI 平台接入列表能直接展示各平台成本,按视频生产常用口径换算为“每 10 秒多少钱”。
|
||
- 当前系统已有 `cost_rule_json`,但运营需要看 JSON 或只看到单次/当日阈值,不方便比较 Hailuo / Seedance / Kling / Wan / Vidu。
|
||
|
||
完成内容:
|
||
|
||
- 后端 Provider 安全返回结构新增 `cost_summary`:
|
||
- `estimated_cost_10s_label`
|
||
- `estimated_cost_10s / min / max`
|
||
- `currency`
|
||
- `price_per_second`
|
||
- `max_cost_per_call`
|
||
- `daily_cost_limit`
|
||
- `pricing_basis`
|
||
- `needs_manual_pricing`
|
||
- `note`
|
||
- `price_per_second=0` 不再被当作免费:
|
||
- 视为未回填正式账单价。
|
||
- 可使用展示估算价,但会标记 `needs_manual_pricing=true`。
|
||
- 后台页面:
|
||
- “AI 平台入口”费用提醒列新增主成本展示。
|
||
- “AI 接入列表”新增“10秒成本”列。
|
||
- 成本单元格使用换行样式,避免 PC/H5 表格中文字和按钮挤压重叠。
|
||
|
||
当前抽样成本展示:
|
||
|
||
- `minimax_hailuo_23_fast`
|
||
- `10秒约 $0.3170`
|
||
- `minimax_hailuo_23`
|
||
- `10秒约 $0.4670`
|
||
- `alibaba_wan26_i2v_flash`
|
||
- `10秒约 $0.2150`
|
||
- `vidu_q3_turbo_reference`
|
||
- `10秒约 $0.5000`
|
||
- `kling-image-to-video`
|
||
- `10秒约 $0.7500`
|
||
- 显示估算,需开通后用实际账单回填。
|
||
- `jimeng_seedance`
|
||
- `10秒约 ¥1.72-¥3.46`
|
||
- 显示估算,需开通后用实际账单回填。
|
||
|
||
改动文件:
|
||
|
||
- `backend/src/providers/provider.types.ts`
|
||
- `backend/src/providers/providers.service.spec.ts`
|
||
- `admin/src/App.vue`
|
||
- `admin/src/styles.css`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`
|
||
- 失败:当前目录不是 Git 仓库。
|
||
- `npm run test --workspace backend -- providers.service.spec.ts`
|
||
- 通过:`35 passed`
|
||
- `npm run typecheck --workspace backend`
|
||
- 通过
|
||
- `npm run lint --workspace backend`
|
||
- 通过
|
||
- `npm run build --workspace backend`
|
||
- 通过
|
||
- `npm run build --workspace admin`
|
||
- 通过
|
||
- 数据库抽样脚本确认 Provider 成本摘要可正常生成。
|
||
|
||
当前结论:
|
||
|
||
- 后台已经可以按“每 10 秒多少钱”查看视频 Provider 成本。
|
||
- 后续开通 Kling / Seedance / Runway 等账号后,只需要把 `cost_rule_json.price_per_second` 或 10 秒估算字段回填,后台会自动更新展示。
|
||
- Router 后续也可以直接复用 `cost_summary` 做预算路由、降级和成本审计展示。
|
||
|
||
## 2026-06-12 AI 视频测试踩坑记录 V1
|
||
|
||
完成时间:
|
||
|
||
2026-06-12 22:25 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户确认当前仍是测试阶段,核心不是马上上线,而是把真人/漫剧视频流水线磨合好。
|
||
- 前面已遇到多类问题:
|
||
- Hailuo 对复杂修仙动作、凌空翻滚、精准结印控制不足。
|
||
- 3 秒碎切导致镜头像图片拼接,缺少电影感。
|
||
- 无声音、无字幕、无 BGM 的样片不可发布。
|
||
- 正脸台词无 lip-sync 时容易嘴型错位。
|
||
- mock-qc 分数不能代表真实人工观感。
|
||
- 成本必须按 10 秒、Provider、候选数进行前置估算。
|
||
- 需要形成长期记录,后续接入 Kling / Seedance / Wan / Vidu / Runway / Veo 时避免重复踩坑。
|
||
|
||
完成内容:
|
||
|
||
- 新增根目录测试手册:
|
||
- `AI_VIDEO_TEST_LESSONS.md`
|
||
- 内容覆盖:
|
||
- 当前阶段定位。
|
||
- Hailuo 已验证适用场景。
|
||
- Hailuo 不适合硬扛的镜头。
|
||
- 分镜时长经验。
|
||
- 10 秒一镜到底结论。
|
||
- Prompt Engine 经验。
|
||
- 角色锚点/定妆图经验。
|
||
- BGM/SFX/字幕经验。
|
||
- lip-sync 策略。
|
||
- 成本控制策略。
|
||
- Provider Router 经验。
|
||
- 新 Provider 准入测试标准。
|
||
- 人工验收标准。
|
||
- 不要重复踩的坑。
|
||
- 下一步建议。
|
||
|
||
关键沉淀:
|
||
|
||
- Hailuo 做低成本都市量产,不再默认硬扛法相/打斗/复杂手诀。
|
||
- 复杂动作失败 1-2 次后,优先切 Provider 或补动作参考/姿势关键帧,不继续无脑烧钱。
|
||
- 复杂动作/爆点镜头优先 8-10 秒一镜到底,普通都市镜头可 5-6 秒。
|
||
- 没有声音、字幕、BGM 的视频判定为失败。
|
||
- 无 lip-sync Provider 时,正脸台词自动改中景/旁白/字幕/轻口型。
|
||
- 候选片段默认 1 条,只有封面级/爆点/人工验收才允许 2 条。
|
||
- 新 Provider 必须用同一项目、同一角色锚点、同一关键帧、同一镜头横向测试。
|
||
|
||
改动文件:
|
||
|
||
- `AI_VIDEO_TEST_LESSONS.md`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`
|
||
- 失败:当前目录不是 Git 仓库。
|
||
- 本次仅新增/更新 Markdown 测试记录,没有改动业务代码,未重新运行 lint/typecheck/test。
|
||
|
||
当前结论:
|
||
|
||
- 测试阶段经验已形成可复用记录。
|
||
- 后续每接一个新 AI 视频平台,都应该按 `AI_VIDEO_TEST_LESSONS.md` 的 Provider 准入测试标准记录质量、成本、失败率和人工观感。
|
||
|
||
## 2026-06-13 都市退婚神豪短剧 5x10 秒导演版测试用例
|
||
|
||
完成时间:
|
||
|
||
2026-06-13 14:35 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户提供《被未婚妻退婚后,我成了首富》第一季和第 1 集设定。
|
||
- 用户明确要求:
|
||
- 要连贯性,不要一个个突破拼接。
|
||
- 看起来像真人拍摄。
|
||
- 有专业运镜、专业剪辑、专业配音、高潮 BGM。
|
||
- Hailuo 只有 6s 或 10s,因此按 10s 每镜设计。
|
||
|
||
完成内容:
|
||
|
||
- 新增测试用例:
|
||
- `storage/private/live-action-testcases/urban-heir-engagement-director-episode-001.json`
|
||
- 结构:
|
||
- 5 个导演长镜头。
|
||
- 每镜固定 `10s`。
|
||
- 总时长 `50s`。
|
||
- 场景只保留两个场景组:
|
||
- 酒店订婚宴会厅。
|
||
- 酒店外雨夜街道。
|
||
- 5 个镜头:
|
||
- 镜头 1:订婚宴开场到林雨薇挽周浩入场。
|
||
- 镜头 2:林雨薇当众退婚。
|
||
- 镜头 3:周浩羞辱与顾辰沉默。
|
||
- 镜头 4:顾辰雨夜离场。
|
||
- 镜头 5:劳斯莱斯与顾氏继承权反转。
|
||
|
||
系统优化:
|
||
|
||
- 后端真人导演计划上限从 `8s` 调整为 `10s`:
|
||
- `LIVE_ACTION_DIRECTOR_MAX_SHOT_SECONDS = 10`
|
||
- 导演时长分配规则支持 5 个 10 秒镜头完整保留。
|
||
- 新增都市高潮 BGM 类型:
|
||
- `urban_climax`
|
||
- 用于退婚、羞辱、打脸、首富、继承权、黑金卡、劳斯莱斯等短剧高潮段落。
|
||
- 修复镜头类型误判:
|
||
- 原规则中只要出现“手”就会误判为 `insert`,导致“手里的戒指盒”被压成 5 秒。
|
||
- 已改为只有“手部/手指/手掌/手腕/手势”等明确手部特写词才算 `insert`。
|
||
- 台词镜头优先判定为 `dialogue`,避免“避免嘴部特写”里的“特写”把镜头误判为 `insert`。
|
||
|
||
导入结果:
|
||
|
||
- 已导入后台项目:
|
||
- `project_id=61`
|
||
- `episode_id=48`
|
||
- 分镜:
|
||
- `shot_id=262` / 镜头 1 / `10s`
|
||
- `shot_id=263` / 镜头 2 / `10s`
|
||
- `shot_id=264` / 镜头 3 / `10s`
|
||
- `shot_id=265` / 镜头 4 / `10s`
|
||
- `shot_id=266` / 镜头 5 / `10s`
|
||
- 已执行 `prepareLiveActionShots`:
|
||
- 5 个镜头均为 `video_status=prepared`
|
||
- 5 个镜头均保留 `duration=10`
|
||
- 5 个镜头 Prompt 均包含 `10秒`
|
||
|
||
Hailuo Fast 成本预估:
|
||
|
||
- Provider:
|
||
- `minimax_hailuo_23_fast`
|
||
- 总镜头数:
|
||
- `5`
|
||
- 总时长:
|
||
- `50s`
|
||
- 每镜:
|
||
- `10s`
|
||
- 每镜预估:
|
||
- `$0.317`
|
||
- 总预估:
|
||
- `$1.585`
|
||
|
||
踩坑记录同步:
|
||
|
||
- 已更新 `AI_VIDEO_TEST_LESSONS.md`
|
||
- 新增 Hailuo 时长设计规则。
|
||
- 明确真人短剧主流程优先按 10 秒长镜头设计。
|
||
- 明确 prepare 阶段不得把 10 秒镜头压缩成 5 秒或 8 秒。
|
||
- 明确负面约束和“手里的道具”不能误触 insert 特写。
|
||
|
||
改动文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `storage/private/live-action-testcases/urban-heir-engagement-director-episode-001.json`
|
||
- `AI_VIDEO_TEST_LESSONS.md`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
运行 / 验证:
|
||
|
||
- `git status --short`
|
||
- 失败:当前目录不是 Git 仓库。
|
||
- JSON 校验:
|
||
- 通过,5 镜共 `50s`。
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts`
|
||
- 通过:`29 passed`
|
||
- `npm run typecheck --workspace backend`
|
||
- 通过
|
||
- `npm run lint --workspace backend`
|
||
- 通过
|
||
- `npm run build --workspace backend`
|
||
- 通过
|
||
- 导入测试用例:
|
||
- 通过
|
||
- prepare 真人镜头:
|
||
- 通过,5 个镜头全部保持 10 秒。
|
||
|
||
当前结论:
|
||
|
||
- 这集已经按 Hailuo 真实 10 秒规格重排成导演连续版。
|
||
- 当前尚未调用真实 Hailuo 生成视频,避免直接扣费。
|
||
- 下一步如果用户确认,可以先跑 Mock 全流程,再选择是否用 Hailuo Fast 跑 5 条真实 10 秒小样。
|
||
|
||
## 2026-06-13 都市退婚神豪短剧 Mock 全链路验收
|
||
|
||
完成时间:
|
||
|
||
2026-06-13 14:40 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户要求继续推进上一步 5x10 秒导演版测试。
|
||
- 本轮目标不是评价真实 Hailuo 画面质量,而是验证:
|
||
- 5 个 10 秒长镜头是否能完整进入生成链路。
|
||
- 关键帧、Mock 视频片段、TTS、字幕、BGM、SFX、最终合成是否完整落库。
|
||
- 后台预览资产是否存在,避免再次出现文件不存在类问题。
|
||
|
||
执行对象:
|
||
|
||
- `project_id=61`
|
||
- `episode_id=48`
|
||
- `shot_id=262-266`
|
||
|
||
执行流程:
|
||
|
||
1. `preflightVideoClips`
|
||
- 初始结果:未就绪。
|
||
- 阻断原因:5 个镜头均缺关键帧。
|
||
- 统计:
|
||
- `shot_count=5`
|
||
- `prepared_shot_count=5`
|
||
- `keyframe_count=0`
|
||
- `provider_clip_count=5`
|
||
- `total_seconds=50`
|
||
2. `generateKeyframes`
|
||
- 生成关键帧资产:5 个。
|
||
3. 再次 `preflightVideoClips`
|
||
- 结果:就绪。
|
||
- 阻断项:0。
|
||
- 统计:
|
||
- `keyframe_count=5`
|
||
- `provider_clip_count=5`
|
||
- `total_seconds=50`
|
||
4. `generateVideoClips`
|
||
- Provider:`mock-video`
|
||
- 生成片段:
|
||
- clip `59` / shot `262` / asset `500` / `10s`
|
||
- clip `60` / shot `263` / asset `501` / `10s`
|
||
- clip `61` / shot `264` / asset `502` / `10s`
|
||
- clip `62` / shot `265` / asset `503` / `10s`
|
||
- clip `63` / shot `266` / asset `504` / `10s`
|
||
- 真实视频费用:`0`
|
||
5. `renderLiveActionEpisode`
|
||
- `include_audio=true`
|
||
- `include_subtitle=true`
|
||
- `include_bgm=true`
|
||
- `include_sfx=true`
|
||
- `include_lip_sync=false`
|
||
|
||
输出资产:
|
||
|
||
- 对白/TTS 混音:
|
||
- asset `505`
|
||
- `local://generated-audio/2026-06-13/d6b4f222-a5f5-4619-9851-762c2fe03f47.wav`
|
||
- `duration=49.55s`
|
||
- `status=active`
|
||
- 字幕:
|
||
- asset `506`
|
||
- `local://generated-subtitles/2026-06-13/7acf1a1b-81bc-4daf-bd8d-2dbc31484843.srt`
|
||
- `duration=50s`
|
||
- `status=active`
|
||
- BGM:
|
||
- asset `507`
|
||
- `local://generated-audio/2026-06-13/82bc90e6-0959-4ec2-8c0b-bed3bfd46a68.wav`
|
||
- `duration=50s`
|
||
- `status=active`
|
||
- SFX:
|
||
- asset `508`
|
||
- `local://generated-audio/2026-06-13/37b8e5d6-9729-4cc3-8b1c-b1b3b6f22e2c.wav`
|
||
- `duration=50s`
|
||
- `status=active`
|
||
- 最终成片:
|
||
- asset `509`
|
||
- `local://rendered-videos/2026-06-13/c7163cfe-0be3-4014-baad-1fe81eacb586.mp4`
|
||
- `duration=50s`
|
||
- `size=2130857`
|
||
- `status=mock`
|
||
|
||
后期策略记录:
|
||
|
||
- BGM cue:
|
||
- 5 个镜头均生成 BGM cue。
|
||
- 镜头 1、2、3、5 使用 `urban_climax`。
|
||
- 镜头 4 使用 `suspense_tension`。
|
||
- `bgm_volume=0.14`
|
||
- SFX cue:
|
||
- 共 `22` 个。
|
||
- 包含 `rain`、`footstep`、`door`、`heartbeat`、`sting`、`impact`。
|
||
- `sfx_volume=0.45`
|
||
- 字幕 cue:
|
||
- 共 `5` 个。
|
||
- lip-sync:
|
||
- 本轮关闭真实 lip-sync。
|
||
- 策略记录中 `required_count=2`,但 `lip_sync_clip_count=0`。
|
||
- 代表系统能识别关键台词镜头,但当前按“中景轻口型 + TTS + 字幕”降级。
|
||
|
||
FFprobe 验证:
|
||
|
||
- 文件:
|
||
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/c7163cfe-0be3-4014-baad-1fe81eacb586.mp4`
|
||
- 视频流:
|
||
- `h264`
|
||
- `1080x1920`
|
||
- `50.000000s`
|
||
- 音频流:
|
||
- `aac`
|
||
- `50.000000s`
|
||
- 音量:
|
||
- `mean_volume=-18.8 dB`
|
||
- `max_volume=-1.2 dB`
|
||
- 抽帧联系表:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-mock-asset-509-contact.jpg`
|
||
|
||
重要发现:
|
||
|
||
- 本轮没有调用真实 Hailuo,真实视频费用为 `0`。
|
||
- 但音频链路使用了已配置并启用的 `minimax-tts`,因此严格意义上不是“全零成本 Mock”。
|
||
- 这对发布级验收是好事,因为可以顺便验证真实 TTS、字幕、BGM、SFX 混音。
|
||
- 如果后续只想做零成本流程测试,应显式指定 `voice_provider_code=mock-voice` 或关闭 `include_audio`。
|
||
|
||
当前结论:
|
||
|
||
- 5x10 秒导演版 Mock 全链路已跑通。
|
||
- 关键帧、视频片段、音频、字幕、BGM、SFX、最终成片均已落库。
|
||
- 成片存在可预览文件,不存在 `ENOENT` 类文件缺失问题。
|
||
- Mock 画面是占位色块,只能证明流程,不能代表真实画面质量。
|
||
- 下一步适合用这 5 个镜头跑真实 Hailuo Fast,验收真人画面连贯性、角色一致性和真实镜头观感。
|
||
|
||
## 2026-06-13 都市退婚神豪短剧 Hailuo 真实 5x10 秒小样
|
||
|
||
完成时间:
|
||
|
||
2026-06-13 17:30 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户确认下一步跑真实 Hailuo 5 条 10 秒镜头。
|
||
- 目标:
|
||
- 验证真实 Hailuo Fast 是否能按 10 秒镜头跑通。
|
||
- 验证真实片段能否进入后期合成。
|
||
- 初步判断真人画面、镜头连贯、角色一致性。
|
||
|
||
真实 Provider 前置检查:
|
||
|
||
- Provider:
|
||
- `minimax_hailuo_23_fast`
|
||
- 模式:`real`
|
||
- 状态:启用
|
||
- 初次 preflight 结果:
|
||
- 未通过。
|
||
- 原因:5 个关键帧均为 Mock SVG。
|
||
- 阻断码:`LIVE_ACTION_KEYFRAME_RASTER_REQUIRED`
|
||
- 结论:真实视频 Provider 必须使用 PNG/JPG/WebP,不能把 Mock SVG 发给 Hailuo。
|
||
|
||
临时真人关键帧处理:
|
||
|
||
- 使用 `imagegen` 生成 5 张真人摄影风关键帧。
|
||
- 统一转为 `1080x1920 PNG`。
|
||
- 本地目录:
|
||
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-keyframes-normalized/`
|
||
- 联系表:
|
||
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-keyframes/contact.jpg`
|
||
- 绑定资产:
|
||
- shot `262` -> keyframe asset `510`
|
||
- shot `263` -> keyframe asset `511`
|
||
- shot `264` -> keyframe asset `512`
|
||
- shot `265` -> keyframe asset `513`
|
||
- shot `266` -> keyframe asset `514`
|
||
- 再次 preflight:
|
||
- 通过。
|
||
- `raster_keyframe_count=5`
|
||
- `provider_clip_count=5`
|
||
- `total_seconds=50`
|
||
- `estimated_cost=$1.585`
|
||
|
||
Hailuo 真实生成结果:
|
||
|
||
- 开始:
|
||
- `2026-06-13T09:18:15.268Z`
|
||
- 完成:
|
||
- `2026-06-13T09:27:18.180Z`
|
||
- 总耗时:
|
||
- 约 9 分钟
|
||
- 生成方式:
|
||
- 5 条顺序生成。
|
||
- 每条 `10s`。
|
||
- `candidate_count=1`,未生成候选,避免成本翻倍。
|
||
- 片段:
|
||
- clip `64` / shot `262` / asset `515` / cost `$0.317`
|
||
- clip `65` / shot `263` / asset `516` / cost `$0.317`
|
||
- clip `66` / shot `264` / asset `517` / cost `$0.317`
|
||
- clip `67` / shot `265` / asset `518` / cost `$0.317`
|
||
- clip `68` / shot `266` / asset `519` / cost `$0.317`
|
||
- 总成本记录:
|
||
- `$1.585`
|
||
|
||
真实成片合成结果:
|
||
|
||
- 成片 asset:
|
||
- `524`
|
||
- 文件:
|
||
- `local://rendered-videos/2026-06-13/d5a3f566-48fe-4f67-a5d7-4e6929e9eba5.mp4`
|
||
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/d5a3f566-48fe-4f67-a5d7-4e6929e9eba5.mp4`
|
||
- 状态:
|
||
- `active`
|
||
- 时长:
|
||
- `50s`
|
||
- 大小:
|
||
- `26412374`
|
||
- 后期资产:
|
||
- TTS/audio asset `520`
|
||
- subtitle asset `521`
|
||
- BGM asset `522`
|
||
- SFX asset `523`
|
||
- render task:
|
||
- `518`
|
||
- status `success`
|
||
|
||
FFprobe 验证:
|
||
|
||
- 视频:
|
||
- `h264`
|
||
- `1080x1920`
|
||
- `50.000000s`
|
||
- 音频:
|
||
- `aac`
|
||
- `50.000000s`
|
||
- 音量:
|
||
- `mean_volume=-18.9 dB`
|
||
- `max_volume=-2.3 dB`
|
||
|
||
抽帧验收文件:
|
||
|
||
- 5 秒间隔联系表:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-hailuo-asset-524/contact.jpg`
|
||
- 2 秒间隔联系表:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-hailuo-asset-524/contact-2s.jpg`
|
||
|
||
初步人工观感:
|
||
|
||
- 明显优于 Mock 和之前碎切测试。
|
||
- Hailuo 在都市酒店、雨夜、车灯、人物中景上表现可用。
|
||
- 5x10 秒长镜头比 3-6 秒碎切更像短剧段落。
|
||
- 字幕、TTS、BGM、SFX 均进入成片。
|
||
- 仍存在生产级问题:
|
||
- 男主在室内和雨夜之间脸有漂移。
|
||
- 部分镜头更像关键帧慢推,表演调度还不够“真实拍摄”。
|
||
- 台词镜头仍依赖 TTS + 字幕,口型不做强同步。
|
||
- 第 4/5 镜头画面质感较好,但角色锚点还不够稳。
|
||
|
||
当前结论:
|
||
|
||
- Hailuo Fast 真实 5x10 秒都市短剧链路已跑通。
|
||
- 技术链路 PASS:
|
||
- raster keyframe -> Hailuo -> 视频片段落库 -> FFmpeg 合成 -> 字幕/TTS/BGM/SFX -> active 成片。
|
||
- 质量链路进入下一轮:
|
||
- 需要“角色锚点图 / 同脸参考 / 定妆图 V1”。
|
||
- 需要把关键帧生成也纳入系统 Provider,而不是临时手动生成。
|
||
- 需要后台把真实 Provider 耗时、成本、关键帧类型、人工观感评分记录到审计页。
|
||
|
||
## 2026-06-13 角色锚点图 / 定妆图 V1 与 1/3/5 镜重跑
|
||
|
||
完成时间:
|
||
|
||
2026-06-13 18:50 Asia/Shanghai
|
||
|
||
背景:
|
||
|
||
- 用户确认下一步做“角色锚点图 / 定妆图 V1”。
|
||
- 目标:
|
||
- 固定顾辰、林雨薇、周浩、老管家四个角色的脸、服装、年龄气质。
|
||
- 写入系统 `actor_profiles`。
|
||
- 用锚点图约束重做第 1、3、5 镜关键帧。
|
||
- 只重跑第 1、3、5 镜 Hailuo,避免全片重复烧成本。
|
||
|
||
锚点图生成:
|
||
|
||
- 使用 `imagegen` 生成 4 张角色半身定妆图。
|
||
- 角色:
|
||
- 顾辰
|
||
- 林雨薇
|
||
- 周浩
|
||
- 老管家
|
||
- 本地目录:
|
||
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-actor-anchors/`
|
||
- 联系表:
|
||
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-actor-anchors/contact.jpg`
|
||
|
||
锚点资产落库:
|
||
|
||
- 顾辰:
|
||
- actor_profile `27`
|
||
- character `99`
|
||
- anchor asset `525`
|
||
- 林雨薇:
|
||
- actor_profile `28`
|
||
- character `100`
|
||
- anchor asset `526`
|
||
- 周浩:
|
||
- actor_profile `29`
|
||
- character `101`
|
||
- anchor asset `527`
|
||
- 老管家:
|
||
- actor_profile `31`
|
||
- character `103`
|
||
- anchor asset `528`
|
||
- 已写入:
|
||
- `actor_profiles.anchor_asset_id`
|
||
- `actor_profiles.reference_asset_ids`
|
||
- `characters.anchor_asset_id`
|
||
- 锚点角色状态:
|
||
- `status=locked`
|
||
|
||
锚点关键帧重做:
|
||
|
||
- 重做镜头:
|
||
- shot `262` / 镜头 1
|
||
- shot `264` / 镜头 3
|
||
- shot `266` / 镜头 5
|
||
- 本地目录:
|
||
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-keyframes/`
|
||
- 归一化目录:
|
||
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-keyframes-normalized/`
|
||
- 联系表:
|
||
- `storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-keyframes/contact.jpg`
|
||
- 绑定资产:
|
||
- shot `262` -> keyframe asset `529`
|
||
- shot `264` -> keyframe asset `530`
|
||
- shot `266` -> keyframe asset `531`
|
||
- preflight:
|
||
- 3 个镜头均通过。
|
||
- 每镜 `10s`
|
||
- 每镜预估 `$0.317`
|
||
- 本轮预计 `$0.951`
|
||
|
||
Hailuo 真实重跑:
|
||
|
||
- 重跑镜头:
|
||
- 第 1、3、5 镜。
|
||
- Provider:
|
||
- `minimax_hailuo_23_fast`
|
||
- 生成结果:
|
||
- clip `69` / shot `262` / input asset `529` / output asset `532` / cost `$0.317`
|
||
- clip `70` / shot `264` / input asset `530` / output asset `533` / cost `$0.317`
|
||
- clip `71` / shot `266` / input asset `531` / output asset `534` / cost `$0.317`
|
||
- 本轮真实视频成本:
|
||
- `$0.951`
|
||
- 生成耗时:
|
||
- `2026-06-13T10:42:14.256Z` 到 `2026-06-13T10:47:30.345Z`
|
||
- 约 5 分 16 秒
|
||
|
||
锚点增强版成片:
|
||
|
||
- 使用:
|
||
- 新第 1 镜 asset `532`
|
||
- 旧第 2 镜 asset `516`
|
||
- 新第 3 镜 asset `533`
|
||
- 旧第 4 镜 asset `518`
|
||
- 新第 5 镜 asset `534`
|
||
- 成片 asset:
|
||
- `539`
|
||
- 文件:
|
||
- `local://rendered-videos/2026-06-13/b3e3faa4-f320-42b6-9e08-f4c80935d427.mp4`
|
||
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/b3e3faa4-f320-42b6-9e08-f4c80935d427.mp4`
|
||
- 状态:
|
||
- `active`
|
||
- 时长:
|
||
- `50s`
|
||
- render task:
|
||
- `526`
|
||
- status `success`
|
||
|
||
FFprobe 验证:
|
||
|
||
- 视频:
|
||
- `h264`
|
||
- `1080x1920`
|
||
- `50.000000s`
|
||
- 音频:
|
||
- `aac`
|
||
- `50.000000s`
|
||
- 音量:
|
||
- `mean_volume=-19.0 dB`
|
||
- `max_volume=-0.5 dB`
|
||
|
||
抽帧验收:
|
||
|
||
- 5 秒间隔:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-rerun-asset-539/contact.jpg`
|
||
- 2 秒间隔:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/urban-heir-anchor-rerun-asset-539/contact-2s.jpg`
|
||
|
||
人工观感:
|
||
|
||
- 有改善:
|
||
- 第 1 镜空间关系更稳定,顾辰和入场二人组关系更明确。
|
||
- 第 3 镜羞辱动作更清楚,周浩拍肩、顾辰低头拿戒指盒更像剧情动作。
|
||
- 第 5 镜老管家、豪车、递文件动作更明确,反转感比上一版强。
|
||
- 仍有问题:
|
||
- 第 2、4 镜没有重跑,因此全片同脸一致性还没有完全统一。
|
||
- Hailuo 运动过程中仍会轻微改脸,尤其侧脸和低头动作。
|
||
- 目前只把锚点图用于关键帧生成,没有真正把多角色参考图直接传给 Hailuo,因为当前 Hailuo Fast 配置是单首帧图生视频。
|
||
|
||
当前结论:
|
||
|
||
- 角色锚点图 / 定妆图 V1 方向有效。
|
||
- 比临时关键帧版更适合进入生产流程。
|
||
- 但要达到可上架,还需要:
|
||
- 关键帧生成必须系统化,而不是临时 `imagegen` 手工生成。
|
||
- 需要把第 2、4 镜也用锚点重做一次,得到全片统一版本。
|
||
- 后续 Provider 若支持 character reference / 多参考图,应优先用于高价值镜头。
|
||
|
||
## 2026-06-13 真人短剧多角色对白 / 多声线 TTS V1
|
||
|
||
目标:
|
||
|
||
- 修复真人短剧成片里“所有人像同一个解说在读”的问题。
|
||
- 同一镜头内多个人说话时,按 `角色名:台词` 自动拆成多个 TTS 段。
|
||
- 每个角色优先使用 Character 表里的 `voice_provider_code` / `voice_id` / `voice_style`。
|
||
|
||
本次代码改动:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `prepareLiveActionPostProductionAssets` 增加项目角色加载。
|
||
- `buildLiveActionAudioSegments` 支持一镜多说话人拆分。
|
||
- 新增角色声音映射:
|
||
- `buildLiveActionCharacterVoiceMap`
|
||
- `resolveLiveActionSegmentVoice`
|
||
- `defaultLiveActionVoiceId`
|
||
- TTS Provider 输入增加:
|
||
- `voice_id`
|
||
- `speaker`
|
||
- `instructions`
|
||
- 音频任务记录增加:
|
||
- `voice_id`
|
||
- `voice_style`
|
||
- `character_id`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- 新增单测:同一镜头中 `林雨薇 / 顾辰 / 周浩` 三人对白拆成 3 个独立 TTS 段。
|
||
|
||
当前项目 61 声线配置:
|
||
|
||
- 顾辰 / character `99`
|
||
- Provider:`minimax-tts`
|
||
- voice_id:`Chinese (Mandarin)_Sincere_Adult`
|
||
- 林雨薇 / character `100`
|
||
- Provider:`minimax-tts`
|
||
- voice_id:`Arrogant_Miss`
|
||
- 周浩 / character `101`
|
||
- Provider:`minimax-tts`
|
||
- voice_id:`Chinese (Mandarin)_Reliable_Executive`
|
||
- 老管家 / character `103`
|
||
- Provider:`minimax-tts`
|
||
- voice_id:`Chinese (Mandarin)_Gentle_Senior`
|
||
|
||
重合成结果:
|
||
|
||
- 新成片 asset:
|
||
- `544`
|
||
- 文件:
|
||
- `local://rendered-videos/2026-06-13/4a42aeea-5e5e-489b-a724-c098f06a2042.mp4`
|
||
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/4a42aeea-5e5e-489b-a724-c098f06a2042.mp4`
|
||
- 状态:
|
||
- `active`
|
||
- 时长:
|
||
- `50s`
|
||
- render task:
|
||
- `531`
|
||
- audio task:
|
||
- `527`
|
||
|
||
音频分段对比:
|
||
|
||
- 旧版 audio task `522`
|
||
- `segment_count=5`
|
||
- 每个镜头一段,多个角色被合成同一个 TTS 文本。
|
||
- 新版 audio task `527`
|
||
- `segment_count=10`
|
||
- 每个人独立发声:
|
||
- 主持人:`Chinese (Mandarin)_News_Anchor`
|
||
- 顾辰:`Chinese (Mandarin)_Sincere_Adult`
|
||
- 林雨薇:`Arrogant_Miss`
|
||
- 周浩:`Chinese (Mandarin)_Reliable_Executive`
|
||
- 旁白:`Chinese (Mandarin)_News_Anchor`
|
||
- 老管家:`Chinese (Mandarin)_Gentle_Senior`
|
||
|
||
FFprobe 验证:
|
||
|
||
- 视频:
|
||
- `h264`
|
||
- `1080x1920`
|
||
- `30fps`
|
||
- `50.000000s`
|
||
- 音频:
|
||
- `aac`
|
||
- `stereo`
|
||
- `50.000000s`
|
||
- 音量:
|
||
- `mean_volume=-19.3 dB`
|
||
- `max_volume=-0.3 dB`
|
||
|
||
验证命令:
|
||
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts`
|
||
- 30 passed
|
||
- `npm run typecheck --workspace backend`
|
||
- passed
|
||
- `npm run lint --workspace backend`
|
||
- passed
|
||
- `npm run build --workspace backend`
|
||
- passed
|
||
|
||
当前结论:
|
||
|
||
- “多人对白被一个声音读完”的问题已修复。
|
||
- 后台/API 已重启到新版代码。
|
||
- 这一步只解决多角色声音,不等于解决严格口型同步。
|
||
- 如果要发布级正脸对白,仍需要后续接 lip-sync Provider 或继续采用中景轻口型策略。
|
||
|
||
## 2026-06-13 老管家声线纠偏
|
||
|
||
问题:
|
||
|
||
- 多角色对白版 asset `544` 比上一版明显改善。
|
||
- 但第 5 镜老管家听感偏女声。
|
||
- 原因:
|
||
- 老管家绑定了 `Chinese (Mandarin)_Gentle_Senior`。
|
||
- 实际听感不适合“中老年男性管家”。
|
||
|
||
修复:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- 老管家 / 王伯 / elder 类默认 MiniMax 声线从:
|
||
- `Chinese (Mandarin)_Gentle_Senior`
|
||
- 改为:
|
||
- `Chinese (Mandarin)_Gentleman`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- 新增单测:
|
||
- 管家对白默认使用 `Chinese (Mandarin)_Gentleman`。
|
||
- 数据库:
|
||
- project `61`
|
||
- character `103`
|
||
- 老管家 voice_id 已改为 `Chinese (Mandarin)_Gentleman`
|
||
- voice_style 已改为:
|
||
- `中老年男性,沉稳、正式、低沉,像忠诚管家汇报重要消息。`
|
||
|
||
重合成结果:
|
||
|
||
- 新成片 asset:
|
||
- `549`
|
||
- 文件:
|
||
- `local://rendered-videos/2026-06-13/70c30ded-2a9e-4b19-9ed0-5873dc2c8feb.mp4`
|
||
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/70c30ded-2a9e-4b19-9ed0-5873dc2c8feb.mp4`
|
||
- 音频 task:
|
||
- `532`
|
||
- 音频 asset:
|
||
- `545`
|
||
- segment_count:
|
||
- `10`
|
||
- 老管家分段:
|
||
- segment `9`
|
||
- voice_id:`Chinese (Mandarin)_Gentleman`
|
||
- segment `10`
|
||
- voice_id:`Chinese (Mandarin)_Gentleman`
|
||
|
||
验证:
|
||
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts`
|
||
- 31 passed
|
||
- `npm run typecheck --workspace backend`
|
||
- passed
|
||
- `npm run lint --workspace backend`
|
||
- passed
|
||
- `npm run build --workspace backend`
|
||
- passed
|
||
- 后端 API 已重启,`/api/health` 正常。
|
||
|
||
当前结论:
|
||
|
||
- 管家女声问题已修复为男声候选。
|
||
- 是否最终采用 `Gentleman` 还要人工听感确认。
|
||
- 如果仍觉得太年轻或不够稳,下一轮可横测:
|
||
- `Chinese (Mandarin)_Male_Announcer`
|
||
- `Chinese (Mandarin)_Reliable_Executive`
|
||
- `Chinese (Mandarin)_Humorous_Elder`
|
||
|
||
## 2026-06-13 Hailuo 2.3 Fast vs 标准版第 5 镜 A/B 小样
|
||
|
||
目标:
|
||
|
||
- 验证当前海螺质量问题是否主要来自 Fast 模型档位。
|
||
- 只测试第 5 镜“劳斯莱斯与继承权反转”,避免整集烧钱。
|
||
|
||
A 版本:
|
||
|
||
- clip:
|
||
- `71`
|
||
- asset:
|
||
- `534`
|
||
- Provider:
|
||
- `minimax_hailuo_23_fast`
|
||
- 模型:
|
||
- `MiniMax-Hailuo-2.3-Fast`
|
||
- 分辨率:
|
||
- `768P`
|
||
- 目标时长:
|
||
- `10s`
|
||
- 实际时长:
|
||
- `10.125s`
|
||
- 成本:
|
||
- `$0.317`
|
||
- 文件:
|
||
- `/www/wwwroot/ai/storage/private/live-action-video-clips/2026-06-13/52538a5b-5cb0-4c26-a42d-003cb7662739.mp4`
|
||
|
||
B 版本:
|
||
|
||
- clip:
|
||
- `72`
|
||
- asset:
|
||
- `550`
|
||
- Provider:
|
||
- `minimax_hailuo_23`
|
||
- 模型:
|
||
- `MiniMax-Hailuo-2.3`
|
||
- 分辨率:
|
||
- `1080P`
|
||
- 目标时长:
|
||
- `6s`
|
||
- 实际时长:
|
||
- `5.875s`
|
||
- 成本:
|
||
- `$0.2802`
|
||
- 生成耗时:
|
||
- 约 4 分 20 秒
|
||
- 文件:
|
||
- `/www/wwwroot/ai/storage/private/live-action-video-clips/2026-06-13/a2b99754-4447-46a4-8c74-e150ef54b31b.mp4`
|
||
|
||
测试保护:
|
||
|
||
- 临时启用 `minimax_hailuo_23`。
|
||
- 生成完成后已恢复为关闭状态,避免后台误点烧更高成本。
|
||
- 第 5 镜 `video_clip_asset_id` 已还原为原 Fast asset `534`。
|
||
- 原整集成片不受本次 A/B 影响。
|
||
|
||
对比产物:
|
||
|
||
- 抽帧图:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/hailuo-standard-ab-shot5/fast-vs-standard-contact.jpg`
|
||
- 并排视频:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/hailuo-standard-ab-shot5/fast-vs-standard-side-by-side.mp4`
|
||
|
||
初步观感:
|
||
|
||
- 标准版 1080P 的清晰度、车灯、雨夜质感略优于 Fast。
|
||
- 但两个版本动作结构仍接近:
|
||
- 基于同一首帧缓慢推进。
|
||
- 老管家递卡和顾辰反应仍不够像真实剧组调度。
|
||
- 没有产生明显“电影拍摄感”的质变。
|
||
- 结论:
|
||
- Fast 不是唯一问题。
|
||
- 更大的瓶颈是:
|
||
- 单首帧图生视频。
|
||
- 缺少中间/结束关键帧。
|
||
- 缺少可控动作参考。
|
||
- 高价值反转镜头需要更强 Provider 或多关键帧流程。
|
||
|
||
下一步建议:
|
||
|
||
- 不建议直接把整集切到 Hailuo 标准版。
|
||
- 建议继续做:
|
||
- 第 5 镜三关键帧流程:
|
||
- 起始:车灯照亮顾辰和管家。
|
||
- 中段:管家递黑金卡。
|
||
- 结束:顾辰震惊看卡。
|
||
- 横测 Kling / Seedance / Wan / Vidu。
|
||
- 同一镜头只比较一个变量,建立 Provider 准入表。
|
||
|
||
## 2026-06-13 动作节拍链式生成 V1
|
||
|
||
目标:
|
||
|
||
- 解决高价值镜头“单首帧图生视频像图片慢慢动”的问题。
|
||
- 不默认增加全片成本,只在显式开启 `action_beat_mode=true` 时启用。
|
||
- 用上一段视频的结尾帧作为下一段首帧,降低动作断裂和模型自由发挥。
|
||
|
||
本次代码改动:
|
||
|
||
- `backend/src/live-action/live-action.dto.ts`
|
||
- `LiveActionGenerateDto` 新增:
|
||
- `action_beat_mode`
|
||
- `action_beat_count`
|
||
- `LiveActionPreflightQueryDto` 新增同名字段。
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- 新增动作节拍子片段规划:
|
||
- `buildLiveActionProviderClipSegments`
|
||
- `liveActionActionBeatPrompts`
|
||
- `resolveLiveActionActionBeatProviderDuration`
|
||
- 生成流程支持:
|
||
- 第 1 段使用原始 `keyframe_asset_id`。
|
||
- 第 2 段开始使用上一段视频结尾帧作为新首帧。
|
||
- 新增尾帧抽取入库:
|
||
- `storeLiveActionSegmentEndFrameAsset`
|
||
- 同步写入 `shot_images.image_type=action_beat_end_N`
|
||
- 多段拼接后会裁回目标镜头时长:
|
||
- `trimLiveActionGeneratedClipBuffer`
|
||
- preflight 已同步显示 action beat 后的真实:
|
||
- `provider_clip_count`
|
||
- `provider_clip_durations`
|
||
- `estimated_cost`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- 新增单测:
|
||
- 开启 `action_beat_mode` 后,第 5 镜拆为 2 段。
|
||
- 第 2 段使用 `previous_segment_end_frame`。
|
||
|
||
第 5 镜测试:
|
||
|
||
- 镜头:
|
||
- shot `266`
|
||
- `劳斯莱斯与继承权反转`
|
||
- Provider:
|
||
- `minimax_hailuo_23_fast`
|
||
- 模式:
|
||
- `action_beat_mode=true`
|
||
- `action_beat_count=2`
|
||
- 分段:
|
||
- beat 1:
|
||
- 原始关键帧 asset `531`
|
||
- 6s
|
||
- 管家撑伞走近、递黑金卡和文件袋。
|
||
- beat 2:
|
||
- 使用 beat 1 结尾帧作为首帧。
|
||
- 6s
|
||
- 顾辰看卡、抬眼震惊。
|
||
- 生成结果:
|
||
- clip `73`
|
||
- asset `552`
|
||
- task `538`
|
||
- 成本 `$0.3804`
|
||
- 生成耗时约 2 分 47 秒
|
||
- 文件:
|
||
- `/www/wwwroot/ai/storage/private/live-action-video-clips/2026-06-13/4843e97d-52ba-47ea-ba4d-6cccf32eedbc.mp4`
|
||
|
||
对比产物:
|
||
|
||
- 三版本抽帧:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/action-beat-shot5/fast-standard-actionbeat-contact.jpg`
|
||
- 三版本并排视频:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/action-beat-shot5/fast-standard-actionbeat-side-by-side.mp4`
|
||
- action beat 后半段抽帧:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/action-beat-shot5/actionbeat-second-half-contact.jpg`
|
||
|
||
系统保护:
|
||
|
||
- 本次测试没有替换正式成片镜头。
|
||
- shot `266` 当前 `video_clip_asset_id` 已还原为原 Fast asset `534`。
|
||
- action beat 生成的 asset `552` 作为候选样片保留。
|
||
|
||
预检验证:
|
||
|
||
- action beat preflight:
|
||
- `provider_clip_count=2`
|
||
- `provider_clip_durations=[6,6]`
|
||
- `estimated_cost=$0.3804`
|
||
- warning:
|
||
- `动作节拍模式会拆成 2 个连续子片段,并使用上一段尾帧承接下一段。`
|
||
|
||
人工观感:
|
||
|
||
- 有明显进步:
|
||
- 后半段能看到顾辰低头看卡、再抬眼震惊。
|
||
- 黑金卡和手套道具更清楚。
|
||
- 比单首帧慢推更像一个连续动作链。
|
||
- 仍有问题:
|
||
- 第 1 段到第 2 段仍可能有轻微跳切。
|
||
- 这是“链式尾帧”方案,不等于真正的三关键帧/首尾帧 Provider。
|
||
- 成本从单条 Fast `$0.317` 增加到 `$0.3804`。
|
||
|
||
当前结论:
|
||
|
||
- action beat 链式生成 V1 方向有效,值得保留到系统。
|
||
- 默认不能全量开启,应只用于:
|
||
- 反转镜头
|
||
- 封面级镜头
|
||
- 爆点镜头
|
||
- 高价值动作镜头
|
||
- 下一步应该在后台给高价值镜头加开关:
|
||
- 普通模式:单条生成。
|
||
- 动作节拍模式:2 段链式生成。
|
||
- 真正多关键帧模式:待接支持 start/end/reference 的 Provider 后启用。
|
||
|
||
## 2026-06-13 第一集 action beat 版重合成
|
||
|
||
目标:
|
||
|
||
- 使用第 5 镜 action beat 候选 asset `552` 重合成完整第一集。
|
||
- 验证动作节拍链式生成放进整集后的观感。
|
||
- 不重新烧 1-4 镜真实视频。
|
||
|
||
合成策略:
|
||
|
||
- 第 1 镜:
|
||
- asset `532`
|
||
- 第 2 镜:
|
||
- asset `516`
|
||
- 第 3 镜:
|
||
- asset `533`
|
||
- 第 4 镜:
|
||
- asset `518`
|
||
- 第 5 镜:
|
||
- 临时替换为 action beat asset `552`
|
||
- 合成完成后:
|
||
- shot `266` 当前指针已恢复为原 asset `534`
|
||
- 本次新成片 asset `557` 保留用于预览对比
|
||
|
||
生成结果:
|
||
|
||
- 新成片 asset:
|
||
- `557`
|
||
- 文件:
|
||
- `local://rendered-videos/2026-06-13/6d4980e3-f4f7-49f7-a4b1-986319d3e059.mp4`
|
||
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/6d4980e3-f4f7-49f7-a4b1-986319d3e059.mp4`
|
||
- render task:
|
||
- `543`
|
||
- 使用 clip_asset_ids:
|
||
- `[532,516,533,518,552]`
|
||
- post production:
|
||
- `segment_count=10`
|
||
- 状态:
|
||
- `active`
|
||
- 时长:
|
||
- `50s`
|
||
|
||
验证:
|
||
|
||
- FFprobe:
|
||
- video:`h264`
|
||
- size:`1080x1920`
|
||
- fps:`30`
|
||
- duration:`50.000000s`
|
||
- audio:`aac stereo`
|
||
- 音量:
|
||
- `mean_volume=-20.0 dB`
|
||
- `max_volume=-0.2 dB`
|
||
- 抽帧:
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/episode48-actionbeat-render-557/contact-5s.jpg`
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/episode48-actionbeat-render-557/contact-2s.jpg`
|
||
|
||
人工观感:
|
||
|
||
- 第 5 镜整体比旧版更像动作链:
|
||
- 管家递卡更明确。
|
||
- 顾辰低头看卡、再抬眼震惊更清楚。
|
||
- 黑金卡道具更突出。
|
||
- 整集仍有短板:
|
||
- 第 2、4 镜仍是旧单首帧素材。
|
||
- 前半段表演和镜头调度仍偏 AI 生成感。
|
||
- 角色一致性和真实拍摄感还没有达到可发布标准。
|
||
|
||
当前结论:
|
||
|
||
- action beat 放进整集后有效,值得用于反转/爆点镜头。
|
||
- 下一步如果继续优化第一集,应优先重做:
|
||
- 第 2 镜退婚对峙
|
||
- 第 4 镜雨夜离场
|
||
- 这两镜若也走“更短动作节拍 + 明确反应 + 更少动作目标”,整集观感会明显提升。
|
||
|
||
## 2026-06-13 第一集全镜头 action beat 版生成
|
||
|
||
目标:
|
||
|
||
- 5 个镜头全部用 `action_beat_mode=true` 重新生成。
|
||
- 验证动作节拍链式生成放到整集后,是否能改善“单首帧慢推 / 图片动”的整体观感。
|
||
|
||
预检:
|
||
|
||
- 镜头数:
|
||
- `5`
|
||
- provider:
|
||
- `minimax_hailuo_23_fast`
|
||
- provider 子片段数:
|
||
- `10`
|
||
- 每镜:
|
||
- `2` 段
|
||
- 每段 `6s`
|
||
- 最终裁回每镜 `10s`
|
||
- 预计视频成本:
|
||
- `$1.902`
|
||
- 阻断:
|
||
- 无
|
||
|
||
生成结果:
|
||
|
||
| 镜头 | clip | asset | 成本 | 用时 |
|
||
| --- | --- | --- | --- | --- |
|
||
| 第 1 镜 订婚宴开场到破局 | `74` | `559` | `$0.3804` | `148s` |
|
||
| 第 2 镜 当众退婚 | `75` | `561` | `$0.3804` | `155s` |
|
||
| 第 3 镜 富二代羞辱与顾辰沉默 | `76` | `563` | `$0.3804` | `148s` |
|
||
| 第 4 镜 雨夜离场 | `77` | `565` | `$0.3804` | `156s` |
|
||
| 第 5 镜 劳斯莱斯与继承权反转 | `78` | `567` | `$0.3804` | `146s` |
|
||
|
||
视频生成成本:
|
||
|
||
- 合计:
|
||
- `$1.902`
|
||
|
||
新整集成片:
|
||
|
||
- asset:
|
||
- `572`
|
||
- 文件:
|
||
- `local://rendered-videos/2026-06-13/01824074-610e-4b34-8742-3948ebf38c9d.mp4`
|
||
- `/www/wwwroot/ai/storage/private/rendered-videos/2026-06-13/01824074-610e-4b34-8742-3948ebf38c9d.mp4`
|
||
- render task:
|
||
- `553`
|
||
- 使用 clip_asset_ids:
|
||
- `[559,561,563,565,567]`
|
||
- post production:
|
||
- `segment_count=10`
|
||
- 渲染耗时:
|
||
- `55s`
|
||
|
||
当前镜头指针:
|
||
|
||
- 第 1 镜:
|
||
- asset `559`
|
||
- 第 2 镜:
|
||
- asset `561`
|
||
- 第 3 镜:
|
||
- asset `563`
|
||
- 第 4 镜:
|
||
- asset `565`
|
||
- 第 5 镜:
|
||
- asset `567`
|
||
|
||
文件验证:
|
||
|
||
- FFprobe:
|
||
- `h264`
|
||
- `1080x1920`
|
||
- `30fps`
|
||
- `50.000000s`
|
||
- audio `aac stereo`
|
||
- 音量:
|
||
- `mean_volume=-20.1 dB`
|
||
- `max_volume=-0.3 dB`
|
||
|
||
抽帧:
|
||
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/episode48-full-actionbeat-render-572/contact-5s.jpg`
|
||
- `/www/wwwroot/ai/storage/private/live-action-acceptance/2026-06-13/episode48-full-actionbeat-render-572/contact-2s.jpg`
|
||
|
||
人工观感:
|
||
|
||
- 有改善:
|
||
- 第 1 镜人物推进和男主正脸更明显。
|
||
- 第 2 镜退婚对峙比旧版更有连续表演感。
|
||
- 第 3 镜羞辱和男主反应更连贯。
|
||
- 第 4 镜雨夜情绪转场更完整。
|
||
- 第 5 镜递卡、顾辰看卡反应比单首帧版更明确。
|
||
- 新问题:
|
||
- 第 5 镜中段管家道具出现比例异常,像大文件夹/牌匾,黑金卡不够真实。
|
||
- action beat 全量开启后,每镜有潜在轻微跳切风险。
|
||
- 角色脸部仍会有轻微漂移,尤其中近景和侧脸转换时。
|
||
- 仍没有真正 lip-sync,正脸对白仍只能靠中景轻口型规避。
|
||
|
||
当前结论:
|
||
|
||
- 全镜头 action beat 版比旧版更能看出完整效果。
|
||
- 方向有效,但不能盲目全片默认开启。
|
||
- 更合理的生产策略:
|
||
- 普通对话:
|
||
- 单条或轻量 action beat。
|
||
- 情绪反应 / 转折:
|
||
- 2 段 action beat。
|
||
- 反转道具 / 爆点:
|
||
- 必须加“道具关键帧 / 结束关键帧”,否则容易道具变形。
|
||
- 正脸对白:
|
||
- 仍需 lip-sync 或继续规避口型。
|
||
|
||
下一步建议:
|
||
|
||
- 优化第 5 镜道具策略:
|
||
- 黑金卡单独生成清晰道具参考图。
|
||
- prompt 禁止文件夹/大牌匾。
|
||
- 第 5 镜只保留黑金卡,不同时递文件袋。
|
||
- 后台应增加镜头级开关:
|
||
- `单条生成`
|
||
- `动作节拍`
|
||
- `道具锁定`
|
||
- `角色锁定`
|
||
- `需要 lip-sync`
|
||
|
||
## 2026-06-14 Live-action Character Lock V1
|
||
|
||
触发原因:
|
||
|
||
- 第一集 action beat 整集样片虽然动作连续性更好,但用户复看后确认不是单点问题:
|
||
- 整集人物都有换脸感。
|
||
- 同名角色跨镜头像不同演员。
|
||
- 这会直接破坏真人短剧发布观感。
|
||
|
||
问题定位:
|
||
|
||
- 数据库已经有:
|
||
- `characters.anchor_asset_id`
|
||
- `character_images`
|
||
- `actor_profiles.anchor_asset_id`
|
||
- `actor_profiles.reference_asset_ids`
|
||
- 但真实视频生成阶段重新 build provider prompt 时,没有按本镜头角色重新加载 actor profile。
|
||
- prepare 阶段的 `actorHints` 也存在把全项目角色混入单镜 prompt 的风险。
|
||
- 结果:
|
||
- 第 1 镜可能带入非本镜角色描述。
|
||
- 第 5 镜也可能缺少顾辰/管家明确同脸锁定。
|
||
- Hailuo 只能吃首帧图生视频时,缺少稳定的角色文字锁定,模型更容易自由换脸。
|
||
|
||
本阶段完成:
|
||
|
||
- 新增 `LiveActionActorLockContext`:
|
||
- 解析本镜头 `characters_json`。
|
||
- 只加载本镜出现角色的 `ActorProfile`。
|
||
- 组装 `actor_hints`:
|
||
- 角色描述。
|
||
- 外貌锁定。
|
||
- 服装锁定。
|
||
- 表演方式。
|
||
- 同名角色禁止换脸/换年龄/换演员。
|
||
- 收集:
|
||
- `anchor_asset_ids`
|
||
- `reference_asset_ids`
|
||
- `missing_actor_profile_character_ids`
|
||
- `missing_anchor_character_ids`
|
||
- 真实视频生成任务 `input_json` 记录:
|
||
- `actor_lock`
|
||
- `character_reference_asset_ids`
|
||
- Provider prompt 现在会注入本镜头角色一致性规则。
|
||
- 如果未来 Provider 支持多角色参考图:
|
||
- 自动把角色参考图转成 `reference_images` 传入。
|
||
- 当前 Hailuo 配置仍显示 `supports_character_reference=false`,所以主要靠首帧 + prompt 锁定。
|
||
- 修复 prepare 阶段:
|
||
- 不再把全项目 actor profiles 混进单镜 prompt。
|
||
- 只按本镜出现角色注入演员提示。
|
||
- mock prompt 也显示 `演员一致性 / actor_consistency`,方便本地验收和后台审计。
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/live-action/live-action.service.ts`
|
||
- `backend/src/live-action/prompt-builder.service.ts`
|
||
- `backend/src/live-action/live-action.service.spec.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
验证:
|
||
|
||
- `npm run test --workspace backend -- live-action.service.spec.ts`
|
||
- 33 tests passed
|
||
- `npm run typecheck --workspace backend`
|
||
- passed
|
||
- `npm run lint --workspace backend`
|
||
- passed
|
||
- `npm run build --workspace backend`
|
||
- passed
|
||
- 后端已重启:
|
||
- `ai-backend.service`
|
||
- PID `4003094`
|
||
- `http://127.0.0.1:3000/api/health` 返回 `ok`
|
||
|
||
当前结论:
|
||
|
||
- 整集换脸问题已在流程层补上第一道防线。
|
||
- 但这不是最终锁脸方案:
|
||
- Hailuo 当前不是强角色参考模型。
|
||
- 仍需要先做角色定妆图/锚点图,并用锚点图生成每个镜头首帧。
|
||
- 发布级样片建议重跑第 1、3、5 镜验证,再决定是否整集重跑。
|
||
|
||
下一步建议:
|
||
|
||
- 先不要再全量重跑整集。
|
||
- 先做:
|
||
- 顾辰 / 林雨薇 / 周浩 / 管家 4 个角色锚点图检查。
|
||
- 用 Character Lock V1 重跑第 1、3、5 镜。
|
||
- 对比旧版抽帧,看是否仍明显换脸。
|
||
- 如果仍严重换脸,再接 Kling / Vidu / Seedance 这类更适合角色参考的 Provider 做横测。
|
||
|
||
## 2026-06-15 Git 提交前数据/代码整理
|
||
|
||
触发问题:
|
||
|
||
- 准备提交 Git 前,需要区分:
|
||
- 哪些是代码和默认初始化数据,应该提交。
|
||
- 哪些是服务器测试/生产运行数据,不应该提交。
|
||
- AI 平台配置是否能通过初始化生成。
|
||
|
||
检查结果:
|
||
|
||
- 当前 `/www/wwwroot/ai` 还不是 Git 仓库:
|
||
- `git status` 返回 `fatal: not a git repository`
|
||
- 当前目录总大小约:
|
||
- `2.3G`
|
||
- 主要运行时数据:
|
||
- `storage` 约 `1.8G`
|
||
- 根 `node_modules` 约 `264M`
|
||
- `backend/node_modules` 约 `235M`
|
||
- `backend/dist`、`admin/dist`、`user-app/dist`、`workers/dist` 为构建产物
|
||
- 当前数据库存在大量测试/运行数据:
|
||
- 用户 `44`
|
||
- 项目 `59`
|
||
- 小说源 `36`
|
||
- 章节 `75`
|
||
- 故事圣经 `33`
|
||
- 角色 `96`
|
||
- 分镜 `280`
|
||
- 任务 `594`
|
||
- Provider 调用日志 `676`
|
||
- 视频片段 `78`
|
||
- 素材 `604`
|
||
- 当前启用 Provider:
|
||
- mock 系列默认 Provider
|
||
- `deepseek-text`
|
||
- `deepseek-novel`
|
||
- `minimax-tts`
|
||
- `minimax_hailuo_23_fast`
|
||
|
||
判断:
|
||
|
||
- 数据库里的项目、任务、素材、调用日志、用户、额度、真实 Provider 启用状态和 Key 配置都属于当前服务器运行数据,不提交 Git。
|
||
- `storage/private/**` 下的图片、音频、视频、小说上传、Hailuo 测试片段都是运行时私有素材,不提交 Git。
|
||
- `.env` 包含数据库、JWT、Provider Key 等本地/生产配置,不提交 Git。
|
||
- AI Provider 默认模板已经在代码中:
|
||
- `backend/src/providers/provider.types.ts`
|
||
- `backend/prisma/migrations/20260602130000_domestic_video_providers/migration.sql`
|
||
- `backend/prisma/seed.ts`
|
||
- 后台保存后的真实 Key 和启用状态应保留在数据库或 `.env`,不进入 Git。
|
||
|
||
本阶段完成:
|
||
|
||
- 加固 `.gitignore`,防止误提交:
|
||
- `node_modules`
|
||
- `dist`
|
||
- `.vite`
|
||
- `.output`
|
||
- `coverage`
|
||
- `.env`
|
||
- 日志文件
|
||
- runtime storage
|
||
- zip/tar/sql/dump/bak
|
||
- sqlite/db 本地数据库
|
||
|
||
修改文件:
|
||
|
||
- `.gitignore`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
提交建议:
|
||
|
||
- 应提交:
|
||
- 源码:`backend/src`、`admin/src`、`user-app/src`、`workers/src`
|
||
- Prisma:`backend/prisma/schema.prisma`、`backend/prisma/migrations`、`backend/prisma/seed.ts`
|
||
- 配置模板:`.env.example`
|
||
- 包管理:`package.json`、`package-lock.json`、各 workspace `package.json`
|
||
- 运维模板:`deploy`
|
||
- 根说明文档和进度文档
|
||
- 不提交:
|
||
- `.env`
|
||
- `storage/private/**`
|
||
- `backend/storage/**`
|
||
- `*.log`
|
||
- `dist`
|
||
- `node_modules`
|
||
- 服务器数据库导出、zip 包、运行备份
|
||
|
||
验证:
|
||
|
||
- 本阶段只调整 Git 忽略规则和进度记录,没有修改业务代码。
|
||
- 未运行 lint/typecheck/test。
|
||
|
||
## 2026-06-14 用户端制作页单列流程 / 下一步自动滚动
|
||
|
||
触发问题:
|
||
|
||
- 用户反馈前端制作页面 PC 端是双列,流程不好看。
|
||
- 希望制作页改成一列纵向流程,并且每次完成当前动作后自动滚动到下一步对应位置。
|
||
|
||
本阶段完成:
|
||
|
||
- 用户端制作页外层增加 `studio-flow`,仅影响“制作”页。
|
||
- PC 端制作页不再使用双列卡片流,强制改为一列往下跑:
|
||
- 进度
|
||
- 额度
|
||
- 来源
|
||
- 版权
|
||
- 故事圣经
|
||
- 角色库
|
||
- 长篇记忆
|
||
- 分集计划
|
||
- 脚本和分镜
|
||
- AI 真人短剧
|
||
- 图片/音频/视频
|
||
- 内容审核
|
||
- 制作页内部表单在 `studio-flow` 下也改为单列,减少 PC/H5 字段和按钮挤压。
|
||
- 给制作页关键步骤增加锚点:
|
||
- `source`
|
||
- `copyright`
|
||
- `story`
|
||
- `characters`
|
||
- `memory`
|
||
- `episodes`
|
||
- `script`
|
||
- `live-action`
|
||
- `render`
|
||
- `review`
|
||
- 新增下一步定位逻辑:
|
||
- 动作成功后根据当前项目状态自动判断下一步。
|
||
- 自动滚动到对应步骤卡片。
|
||
- AI 原创项目未生成正文时,优先回到“来源”。
|
||
- 真人短剧项目在最终成片前,优先回到“AI 真人短剧”面板。
|
||
- 排除不应该滚动的局部操作:
|
||
- 恢复会话
|
||
- 视频预检刷新
|
||
- 小样预检刷新
|
||
- 单张锚点重生成
|
||
- 单张锚点切换
|
||
- 素材预览
|
||
- 成品下载
|
||
|
||
修改文件:
|
||
|
||
- `user-app/src/pages/index/index.vue`
|
||
- `user-app/src/styles.css`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
验证:
|
||
|
||
- `npm run typecheck --workspace user-app`
|
||
- passed
|
||
- `npm run lint --workspace user-app`
|
||
- passed
|
||
- `npm run test --workspace user-app`
|
||
- passed, no test files
|
||
- `curl -I http://152.53.37.118:5174/`
|
||
- `200 OK`
|
||
|
||
下一步建议:
|
||
|
||
- 人工打开 PC/H5 制作页,点一遍“版权确认 -> 解析小说 -> 故事圣经 -> 角色 -> 分集 -> 脚本/分镜 -> 真人视频/合成”,确认自动滚动位置是否符合操作习惯。
|
||
- 如果仍觉得步骤太长,可以再加一个右侧/顶部“当前流程目录”,点击可跳到任一步。
|
||
|
||
## 2026-06-14 前端真人视频流程同步 / Action Beat 控制
|
||
|
||
触发问题:
|
||
|
||
- 用户询问 `http://152.53.37.118:5174/` 前端按流程生成视频时,到底是 mock 还是同步了最近真实 Hailuo 测试步骤。
|
||
|
||
问题定位:
|
||
|
||
- 前端普通主流程的“生成视频/合成”仍是系统 A 常规 FFmpeg 合成链路,不等于真人 Hailuo 视频片段生成链路。
|
||
- 前端已有“AI 真人短剧”面板,能执行演员定妆、真人分镜、关键帧、视频片段、合成。
|
||
- 后端已支持 `action_beat_mode/action_beat_count`,但用户端没有暴露开关,导致无法在前端明确控制“默认 1 条”还是“复杂动作拆成 2-3 个子片段”。
|
||
|
||
本阶段完成:
|
||
|
||
- 用户端真人视频表单新增:
|
||
- `动作节拍`
|
||
- `节拍段数`
|
||
- 默认关闭动作节拍,保持单镜头默认 1 条,避免默认成本翻倍。
|
||
- 开启动作节拍后,前端预检、小样生成、整集片段生成、片段重试都会带上:
|
||
- `action_beat_mode`
|
||
- `action_beat_count`
|
||
- 统一真人视频前端参数构造,减少小样和整集口径不一致。
|
||
- `UserApiClient` 的真人视频 preflight/generate/retry 类型和 query/body 增加 action beat 参数。
|
||
|
||
修改文件:
|
||
|
||
- `user-app/src/pages/index/index.vue`
|
||
- `user-app/src/api/client.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
验证:
|
||
|
||
- `npm run typecheck --workspace user-app`
|
||
- passed
|
||
- `npm run lint --workspace user-app`
|
||
- passed
|
||
- `npm run test --workspace user-app`
|
||
- passed, no test files
|
||
- `curl -I http://152.53.37.118:5174/`
|
||
- `200 OK`
|
||
|
||
当前判断:
|
||
|
||
- 前端普通流程的“多角色音频”会按当前 Provider 配置走真实 MiniMax 或 mock。
|
||
- 前端普通流程的“生成视频/合成”是 FFmpeg 合成,不会直接调用 Hailuo 生成真人视频。
|
||
- 前端“AI 真人短剧”面板里的“视频片段/小样视频片段”才是 Hailuo/Kling/Jimeng/Mock 真实视频 Provider 链路。
|
||
- 选择真实 Hailuo Provider 并勾选真实费用确认后,才会调用真实 Hailuo;不选 Provider 时走 Router,Router 可能因为配置/可用性落到 Mock。
|
||
- 后端 Character Lock V1 已自动生效,但前端目前只使用它,不单独展示 actor_lock 审计明细。
|
||
|
||
下一步建议:
|
||
|
||
- 把前端“普通生成视频”和“真人视频片段生成”视觉上再拆清楚,避免误点普通合成却以为在跑 Hailuo。
|
||
- 后台/前端补 actor_lock、关键帧来源、clip_normalization 的可视化,让每个片段是否锁脸、是否裁切、是否动作节拍拆段一眼可见。
|
||
|
||
## 2026-06-14 TTS / Upload Blocking Fix
|
||
|
||
触发问题:
|
||
|
||
- 用户端点击“多角色音频”报:
|
||
- `MINIMAX_TTS_EMPTY_AUDIO`
|
||
- 上传小说时报:
|
||
- `request entity too large`
|
||
|
||
问题定位:
|
||
|
||
- 最近失败的 `minimax-tts` ProviderLog 显示:
|
||
- 多角色音频把 `voice=coral` 发给了 MiniMax。
|
||
- `coral` 是 OpenAI TTS 声音名,不是 MiniMax voice_id。
|
||
- `runConfigurableSpeechProvider` 解析 JSON 响应时,没有先检查 MiniMax `base_resp.status_code`,会把业务拒绝误报成 `MINIMAX_TTS_EMPTY_AUDIO`。
|
||
- 上传小说的后端文件限制为 20MB。
|
||
- 加密上传会把文件转成 base64 放入 JSON,Nest 默认 body parser 限制会先拦截,导致 `request entity too large`。
|
||
|
||
本阶段完成:
|
||
|
||
- MiniMax TTS 兼容:
|
||
- `body_style=minimax_tts` 时,如果输入是 OpenAI voice 名(如 `coral`),自动降级为 MiniMax 配置默认 `voice_id`。
|
||
- MiniMax JSON 响应先检查 `base_resp.status_code`,真实业务错误会显示 `MINIMAX_TTS_PROVIDER_REJECTED`,不再误报空音频。
|
||
- JSON 无音频时带上安全摘要,方便后台排查。
|
||
- Media 多角色音频 provider input 增加 `voice_id` 字段,方便 Provider 适配。
|
||
- 上传限制:
|
||
- 小说/素材上传默认上限从 20MB 提高到 100MB。
|
||
- 新增 `MAX_UPLOAD_BYTES` 环境变量支持。
|
||
- Nest body parser 改为显式配置:
|
||
- 默认 `REQUEST_BODY_LIMIT=160mb`
|
||
- 支持 `MAX_REQUEST_BODY_SIZE`
|
||
- 兼容 encrypted JSON/base64 上传。
|
||
- 用户端错误文案:
|
||
- 增加 `MINIMAX_TTS_EMPTY_AUDIO`
|
||
- 增加 `MINIMAX_TTS_PROVIDER_REJECTED`
|
||
- 增加 `request entity too large`
|
||
|
||
修改文件:
|
||
|
||
- `backend/src/providers/providers.service.ts`
|
||
- `backend/src/providers/providers.service.spec.ts`
|
||
- `backend/src/media/media.service.ts`
|
||
- `backend/src/assets/assets.controller.ts`
|
||
- `backend/src/main.ts`
|
||
- `user-app/src/api/client.ts`
|
||
- `CODEX_PROGRESS.md`
|
||
|
||
验证:
|
||
|
||
- `npm run test --workspace backend -- providers.service.spec.ts media.service.spec.ts assets.service.spec.ts`
|
||
- 55 tests passed
|
||
- `npm run typecheck --workspace backend`
|
||
- passed
|
||
- `npm run lint --workspace backend`
|
||
- passed
|
||
- `npm run build --workspace backend`
|
||
- passed
|
||
- `npm run typecheck --workspace user-app`
|
||
- passed
|
||
- `npm run test --workspace user-app`
|
||
- passed, no test files
|
||
- MiniMax TTS smoke:
|
||
- `text=测试。`
|
||
- `voice=coral`
|
||
- provider `minimax-tts`
|
||
- status `success`
|
||
- returned `audio/mpeg`
|
||
- audio bytes `18485`
|
||
- 大 body 上传 smoke:
|
||
- 1MB base64 JSON 上传不再返回 413
|
||
- 未登录场景返回正常 `401 Missing bearer token`
|
||
- 后端已重启:
|
||
- `ai-backend.service`
|
||
- PID `4097583`
|
||
- `/api/health` 返回 `ok`
|
||
|
||
注意:
|
||
|
||
- 如果上传通过公网 Nginx/宝塔代理仍报 413,还需要同步调高 Nginx `client_max_body_size`。
|
||
- 当前应用层已经放开到默认 100MB 文件 / 160MB JSON body。
|