Files
meijiaka-zy/docs/material-matching-plan.md
T
小鱼开发 4e06f4abe2 feat: 空镜素材配置后端化,视频生成流程重构
- 后端: 空镜素材迁移到 config/materials.json,duration从文件名_{N}s_自动解析
- 后端: 新增 POST /api/v1/materials/match 接口,后端做关键词匹配
- 前端: VideoGeneration 空镜匹配改为调用后端接口
- 前端: 人物出镜素材改为本地文件选择器直接选取,不走素材库
- 前端: 视频生成流程简化,移除Vidu对口型和七牛云上传
- Rust: 视频合成支持从随机起始时间截取人物素材片段
- Rust: 修复ffprobe参数错误(添加-show_entries format=duration)
2026-04-22 18:49:20 +08:00

13 KiB
Raw Blame History

空镜素材智能匹配方案

文档版本:v1.0 创建时间:2026-04-22 状态:待实现

一、需求背景

1.1 业务场景

在视频创作流程中,脚本生成阶段会产生分镜脚本,每个分镜包含:

  • 画面描述:AI 生成的口播场景描述(如 "厨房台面特写")
  • 配音文字:该分镜的口播文案

当前痛点:画面描述只是文字,没有对应的空镜素材,每个分镜只能配音,无法展示实际画面。

1.2 解决思路

建立空镜素材库AI 生成脚本时同时输出标签,根据标签从素材库匹配对应视频素材,实现:

  • 口播 + 空镜画面 的完整分镜效果
  • 自动替换/拼接空镜素材,减少人工选材工作量

二、功能需求

2.1 标签体系

层级 示例 说明
父标签 室内 大场景分类
子标签 客厅厨房卫生间卧室书房 具体房间
扩展标签 台面特写整体空间角落细节 拍摄角度/风格

标签格式父标签/子标签父标签/子标签/扩展标签

示例

室内/客厅
室内/厨房/开放式
室内/卫生间/干湿分离
室外/阳台

2.2 素材管理

需求 描述
素材上传 运营人员上传空镜视频到七牛云
标签标注 上传时指定素材的标签(支持多标签)
素材索引 本地维护标签 → 素材文件 的映射关系
素材检索 根据标签快速查找匹配素材

2.3 脚本生成增强

需求 描述
标签输出 AI 生成脚本时,在画面描述后输出对应标签
标签格式 统一使用 【标签】室内/客厅 格式
兼容旧格式 已有脚本无需修改,缺失标签的分镜跳过素材匹配

示例输出

{
  "segments": [
    {
      "id": "seg_001",
      "scene": "开场:展示整洁的厨房整体空间",
      "voiceover": "大家好,今天我们来聊聊厨房装修的注意事项...",
      "duration": 15,
      "tag": "室内/厨房/整体空间"
    },
    {
      "id": "seg_002",
      "scene": "特写:台面材质细节",
      "voiceover": "首先,台面的材质选择非常重要...",
      "duration": 12,
      "tag": "室内/厨房/台面特写"
    }
  ]
}

2.4 素材匹配流程

步骤 操作 说明
1 解析标签 从分镜数据中提取 tag 字段
2 查询索引 在本地索引中查找对应标签的素材列表
3 随机选择 从匹配素材中随机选择一个
4 获取 URL 拼接七牛云访问 URL
5 下载素材 下载到本地 shots/ 目录
6 记录关联 videoPath 写入分镜数据

2.5 素材路径设计

七牛云存储结构(使用英文路径):

materials/
├── indoor/
│   ├── living_room/
│   │   ├── vid_001.mp4
│   │   ├── vid_002.mp4
│   │   └── ...
│   ├── kitchen/
│   │   ├── open/
│   │   │   ├── vid_010.mp4
│   │   │   └── ...
│   │   └── closed/
│   └── bathroom/
├── outdoor/
│   ├── balcony/
│   └── garden/
└── ...

本地索引结构materials_index.json):

{
  "version": "1.0",
  "lastUpdated": "2026-04-22T10:00:00Z",
  "tags": {
    "室内/客厅": {
      "displayName": "室内/客厅",
      "qiniuDir": "materials/indoor/living_room",
      "videos": [
        {
          "id": "vid_001",
          "filename": "vid_001.mp4",
          "qiniuKey": "materials/indoor/living_room/vid_001.mp4",
          "duration": 8.5,
          "size": 1024000,
          "uploadedAt": "2026-04-20T08:30:00Z"
        }
      ]
    },
    "室内/厨房/开放式": {
      "displayName": "室内/厨房/开放式",
      "qiniuDir": "materials/indoor/kitchen/open",
      "videos": [...]
    }
  }
}

三、技术方案

3.1 架构概览

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│   脚本生成      │────▶│   素材匹配服务    │────▶│   七牛云存储     │
│   (AI 输出标签) │     │   (本地索引查询)  │     │   (英文路径)     │
└─────────────────┘     └──────────────────┘     └─────────────────┘
                                │
                                ▼
                        ┌──────────────────┐
                        │   本地素材索引     │
                        │ (materials_index) │
                        └──────────────────┘

3.2 核心模块

模块 位置 职责
MaterialIndex python-api/app/services/material_index.py 素材索引管理(加载/查询/更新)
MaterialMatcher python-api/app/services/material_matcher.py 素材匹配逻辑
QiniuMaterialService python-api/app/services/qiniu_material.py 七牛云素材相关操作
material_router python-api/app/api/v1/material.py 素材管理 API

3.3 关键设计决策

决策 方案 理由
标签中文,路径英文 中文标签映射到英文目录 URL 可读性、FFmpeg 兼容性
本地索引 + 七牛云 双层架构 减少 API 调用、快速检索
随机选择素材 random.choice() 避免每次生成视频都用相同素材
索引热更新 定时刷新 + 手动刷新 支持运营动态增删素材

四、数据模型

4.1 分镜数据扩展

// 前端 types.ts
interface Segment {
  id: string;
  type: "segment" | "empty_shot";
  scene: string;           // 画面描述
  voiceover: string;       // 配音文案
  duration: number;       // 预估时长(秒)
  tag?: string;           // 【新增】素材标签,如 "室内/客厅"
  videoPath?: string;     // 【新增】匹配到的素材本地路径
  videoUrl?: string;      // 【新增】七牛云原 URL
  status: "pending" | "matched" | "downloaded" | "failed";
}

4.2 素材索引 Schema

// materials_index.json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["version", "lastUpdated", "tags"],
  "properties": {
    "version": {
      "type": "string",
      "description": "索引文件版本"
    },
    "lastUpdated": {
      "type": "string",
      "format": "date-time",
      "description": "最后更新时间"
    },
    "tags": {
      "type": "object",
      "description": "标签到素材的映射",
      "additionalProperties": {
        "type": "object",
        "required": ["displayName", "qiniuDir", "videos"],
        "properties": {
          "displayName": {"type": "string"},
          "qiniuDir": {"type": "string"},
          "videos": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["id", "filename", "qiniuKey"],
              "properties": {
                "id": {"type": "string"},
                "filename": {"type": "string"},
                "qiniuKey": {"type": "string"},
                "duration": {"type": "number"},
                "size": {"type": "integer"},
                "uploadedAt": {"type": "string"}
              }
            }
          }
        }
      }
    }
  }
}

五、API 设计

5.1 素材管理 API

方法 路径 描述
GET /api/v1/materials 获取素材索引
GET /api/v1/materials/tags 获取所有标签列表
GET /api/v1/materials/match?tag=室内/客厅 根据标签匹配素材
POST /api/v1/materials/sync 同步/刷新素材索引(管理员)
POST /api/v1/materials/upload 上传新素材并标注标签

5.2 匹配流程 API

方法 路径 描述
POST /api/v1/materials/batch-match 批量匹配分镜素材
GET /api/v1/materials/download/{id} 下载素材到本地

批量匹配请求

POST /api/v1/materials/batch-match
{
  "segments": [
    {"id": "seg_001", "tag": "室内/客厅"},
    {"id": "seg_002", "tag": "室内/厨房/台面特写"}
  ]
}

批量匹配响应

{
  "matched": [
    {"segmentId": "seg_001", "videoId": "vid_001", "url": "https://..."},
    {"segmentId": "seg_002", "videoId": "vid_015", "url": "https://..."}
  ],
  "unmatched": ["seg_003"],
  "summary": {
    "total": 3,
    "matched": 2,
    "unmatched": 1
  }
}

六、实施步骤

Phase 1:基础设施(1天)

  • 创建 python-api/app/services/material_index.py
  • 创建 python-api/app/services/material_matcher.py
  • 创建 python-api/app/services/qiniu_material.py
  • 初始化示例 materials_index.json

Phase 2API 层(1天)

  • 创建 python-api/app/api/v1/material.py 路由
  • 注册路由到 router.py
  • 编写 API 文档和单元测试

Phase 3:脚本生成集成(1天)

  • 更新 python-api/app/ai/prompts/system/script.txt 添加标签输出要求
  • 更新 python-api/app/services/script_service.py 支持素材匹配
  • 测试端到端流程

Phase 4:前端集成(1天)

  • 更新 tauri-app/src/api/types.ts 添加 tag 字段
  • 更新 SegmentAdapter 支持 tag 映射
  • 前端显示素材匹配状态

Phase 5:运营工具(待定)

  • 开发素材上传 + 标签标注 Web 页面
  • 开发素材索引管理后台

七、文件结构

meijiaka-zj/
├── python-api/
│   └── app/
│       ├── services/
│       │   ├── material_index.py      # 【新建】素材索引管理
│       │   ├── material_matcher.py    # 【新建】素材匹配器
│       │   └── qiniu_material.py      # 【新建】七牛云素材操作
│       ├── api/v1/
│       │   ├── material.py            # 【新建】素材管理 API
│       │   └── router.py              # 【修改】注册 material 路由
│       └── schemas/
│           └── material.py             # 【新建】Pydantic 模型
│
├── tauri-app/
│   └── src/
│       ├── api/
│       │   ├── modules/
│       │   │   └── material.ts         # 【新建】素材 API 模块
│       │   └── types.ts                # 【修改】添加 Segment.tag
│       └── pages/
│           └── VideoCreation/
│               └── ScriptCreation.tsx  # 【修改】显示标签
│
├── docs/
│   └── material-matching-plan.md       # 【新建】本文档
│
└── materials/
    └── materials_index.json            # 【新建】素材索引文件

八、配置项

8.1 环境变量

# .env 添加
QINIU_MATERIALS_ENABLED=true                    # 是否启用素材匹配
QINIU_MATERIALS_DOMAIN=https://materials.xxx.com # 素材专用域名
MATERIALS_INDEX_PATH=./materials_index.json      # 本地索引文件路径

8.2 标签-目录映射表

中文标签 七牛云目录 英文路径
室内/客厅 materials/indoor/living_room materials/indoor/living_room
室内/厨房 materials/indoor/kitchen materials/indoor/kitchen
室内/厨房/开放式 materials/indoor/kitchen/open materials/indoor/kitchen/open
室内/卫生间 materials/indoor/bathroom materials/indoor/bathroom
室内/卧室 materials/indoor/bedroom materials/indoor/bedroom
室外/阳台 materials/outdoor/balcony materials/outdoor/balcony

九、注意事项

9.1 编码问题

  • 七牛云 Key:使用 UTF-8 编码,中文 key 技术上支持但建议避免
  • 本地路径:下载后确保路径处理兼容中文文件名
  • FFmpeg:操作本地文件时优先使用绝对路径和引号包裹

9.2 容错处理

场景 处理方式
标签无匹配素材 记录 unmatched,不影响后续分镜
七牛云下载失败 标记状态为 failed,允许重试
索引文件缺失 自动重建或返回空列表

9.3 性能考虑

  • 素材索引加载到内存,避免每次请求都读文件
  • 使用 LRU 缓存最近访问的素材 URL
  • 下载操作异步执行,不阻塞主流程

十、附录

10.1 七牛云 Bucket 配置建议

Bucket 名称:media-materials
存储区域:华东 zone
访问域名:materials.xxx.comCDN 加速)

10.2 素材上传规范

字段 要求
格式 MP4、H.264 编码
时长 5-30 秒
分辨率 1920x1080 或 1280x720
文件名 vid_{序号}.mp4
标签 上传后填写,支持多标签

10.3 参考文档