Initial TrueGrowth source import
This commit is contained in:
384
docs/features/sora-character-feature.md
Normal file
384
docs/features/sora-character-feature.md
Normal file
@@ -0,0 +1,384 @@
|
||||
# Sora-2 角色创建功能开发计划
|
||||
|
||||
## 功能概述
|
||||
|
||||
为 Sora-2 视频模型添加角色创建和复用功能,用户可以从已完成的视频任务中提取角色,并在后续视频生成中通过 `@username` 方式引用该角色。
|
||||
|
||||
## API 接口说明
|
||||
|
||||
### 1. 创建角色接口
|
||||
|
||||
- **URL**: `POST https://api.tu-zi.com/v1/videos`
|
||||
- **Content-Type**: `multipart/form-data`
|
||||
|
||||
| 参数 | 类型 | 必需 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `character_from_task` | string | 是 | 源视频任务ID,格式: `sora-2:task_xxx` |
|
||||
| `model` | string | 是 | 固定值: `sora-2-character` |
|
||||
| `character_timestamps` | string | 否 | 时间范围,格式: `start,end`,差值需在1-3秒内 |
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"id": "sora-2-character:ch_6944ed3a51888191bd1ac40c763620fb"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 查询角色接口
|
||||
|
||||
- **URL**: `GET https://api.tu-zi.com/v1/videos/{id}`
|
||||
- **认证**: Bearer Token
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"id": "sora-2-character:ch_6944ed3a51888191bd1ac40c763620fb",
|
||||
"username": "xscjkajd.lunaradian",
|
||||
"permalink": "https://sora.chatgpt.com/profile/xscjkajd.lunaradian",
|
||||
"profile_picture_url": "https://filesystem.site/cdn/xxx.jpg"
|
||||
}
|
||||
```
|
||||
|
||||
## 开发任务清单
|
||||
|
||||
### 阶段一:基础架构(预计 2-3 天)
|
||||
|
||||
#### Task 1: 创建角色类型定义
|
||||
- **文件**: `packages/drawnix/src/types/character.types.ts`
|
||||
- **内容**:
|
||||
- `SoraCharacter` 接口(角色完整信息)
|
||||
- `CharacterStatus` 枚举(pending/processing/completed/failed)
|
||||
- `CreateCharacterParams` 接口(创建参数)
|
||||
- `CharacterQueryResponse` 接口(查询响应)
|
||||
|
||||
#### Task 2: 实现角色 API 服务
|
||||
- **文件**: `packages/drawnix/src/services/character-api-service.ts`
|
||||
- **功能**:
|
||||
- `createCharacter()` - 提交角色创建请求
|
||||
- `queryCharacter()` - 查询角色状态
|
||||
- `createCharacterWithPolling()` - 创建并轮询直到完成
|
||||
- **依赖**: Task 1
|
||||
|
||||
#### Task 3: 实现角色存储服务
|
||||
- **文件**: `packages/drawnix/src/services/character-storage-service.ts`
|
||||
- **功能**:
|
||||
- IndexedDB 存储(使用 localforage)
|
||||
- `saveCharacter()` - 保存角色
|
||||
- `getCharacters()` - 获取所有角色
|
||||
- `getCharacterById()` - 按ID获取
|
||||
- `deleteCharacter()` - 删除角色
|
||||
- `updateCharacter()` - 更新角色状态
|
||||
- **存储键**: `sora-characters`
|
||||
- **依赖**: Task 1
|
||||
|
||||
#### Task 4: 创建角色状态管理 Hook
|
||||
- **文件**: `packages/drawnix/src/hooks/useCharacters.ts`
|
||||
- **功能**:
|
||||
- 角色列表状态管理(RxJS BehaviorSubject)
|
||||
- `characters` - 角色列表
|
||||
- `pendingCharacters` - 处理中的角色
|
||||
- `createCharacter()` - 创建角色(带状态更新)
|
||||
- `deleteCharacter()` - 删除角色
|
||||
- `refreshCharacters()` - 刷新列表
|
||||
- **依赖**: Task 2, Task 3
|
||||
|
||||
### 阶段二:UI 组件(预计 2-3 天)
|
||||
|
||||
#### Task 5: 实现角色创建对话框
|
||||
- **文件**: `packages/drawnix/src/components/character/CharacterCreateDialog.tsx`
|
||||
- **功能**:
|
||||
- 显示源视频信息
|
||||
- 时间范围选择器(滑块或输入框)
|
||||
- 时间约束验证(1-3秒)
|
||||
- 提交/取消按钮
|
||||
- 创建中状态显示
|
||||
- **UI**: 使用 TDesign Dialog + Slider/InputNumber
|
||||
- **依赖**: Task 4
|
||||
|
||||
#### Task 6: 在 TaskItem 中添加「提取角色」按钮
|
||||
- **文件**: `packages/drawnix/src/components/task-queue/TaskItem.tsx`
|
||||
- **修改**:
|
||||
- 添加「提取角色」按钮(仅对 sora-2 已完成任务显示)
|
||||
- 添加 `onExtractCharacter` 回调
|
||||
- 按钮条件判断逻辑
|
||||
- **依赖**: Task 5
|
||||
|
||||
#### Task 7: 实现角色卡片组件
|
||||
- **文件**: `packages/drawnix/src/components/character/CharacterCard.tsx`
|
||||
- **功能**:
|
||||
- 显示头像(profile_picture_url)
|
||||
- 显示 @username
|
||||
- 复制按钮(复制 @username)
|
||||
- 删除按钮
|
||||
- 处理中状态(loading)
|
||||
- **样式**: `character.scss`
|
||||
- **依赖**: Task 1
|
||||
|
||||
#### Task 8: 实现角色列表/选择器组件
|
||||
- **文件**: `packages/drawnix/src/components/character/CharacterList.tsx`
|
||||
- **功能**:
|
||||
- 显示所有已创建的角色
|
||||
- 支持选择角色(用于插入提示词)
|
||||
- 空状态提示
|
||||
- 可选:搜索过滤
|
||||
- **依赖**: Task 4, Task 7
|
||||
|
||||
### 阶段三:提示词集成(预计 1-2 天)
|
||||
|
||||
#### Task 9: 在 PromptInput 中集成 @ 提及功能
|
||||
- **文件**: `packages/drawnix/src/components/ttd-dialog/shared/PromptInput.tsx`
|
||||
- **修改**:
|
||||
- 监听 `@` 输入
|
||||
- 弹出角色选择器(Popup/Dropdown)
|
||||
- 选择后插入 `@username`
|
||||
- 支持键盘导航(上下选择,回车确认)
|
||||
- **新文件**: `CharacterMentionPopup.tsx`
|
||||
- **依赖**: Task 4, Task 8
|
||||
|
||||
### 阶段四:状态同步与优化(预计 1 天)
|
||||
|
||||
#### Task 10: 页面刷新恢复
|
||||
- 从 IndexedDB 恢复角色列表
|
||||
- 恢复处理中的角色创建任务
|
||||
- 继续轮询未完成的角色
|
||||
|
||||
#### Task 11: 错误处理与用户反馈
|
||||
- API 错误提示(网络错误、超时、服务器错误)
|
||||
- 角色创建失败处理
|
||||
- 重试机制
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
packages/drawnix/src/
|
||||
├── types/
|
||||
│ └── character.types.ts # 角色类型定义
|
||||
├── services/
|
||||
│ ├── character-api-service.ts # 角色 API 服务
|
||||
│ └── character-storage-service.ts # 角色存储服务
|
||||
├── hooks/
|
||||
│ └── useCharacters.ts # 角色状态管理 Hook
|
||||
├── components/
|
||||
│ ├── character/
|
||||
│ │ ├── index.ts
|
||||
│ │ ├── CharacterCreateDialog.tsx
|
||||
│ │ ├── CharacterCard.tsx
|
||||
│ │ ├── CharacterList.tsx
|
||||
│ │ ├── CharacterMentionPopup.tsx
|
||||
│ │ └── character.scss
|
||||
│ └── task-queue/
|
||||
│ └── TaskItem.tsx # 修改:添加提取角色按钮
|
||||
└── components/ttd-dialog/shared/
|
||||
└── PromptInput.tsx # 修改:添加 @ 提及功能
|
||||
```
|
||||
|
||||
## 数据流
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 用户交互流程 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 1. 用户点击「提取角色」 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 2. CharacterCreateDialog 弹出 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 3. 用户选择时间范围 → 点击创建 │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 4. useCharacters.createCharacter() │
|
||||
│ │ │
|
||||
│ ├──► characterApiService.createCharacter() │
|
||||
│ │ │ │
|
||||
│ │ ▼ │
|
||||
│ │ POST /v1/videos (character_from_task, model) │
|
||||
│ │ │ │
|
||||
│ │ ▼ │
|
||||
│ │ 返回 character_id │
|
||||
│ │ │
|
||||
│ ├──► characterStorageService.saveCharacter(pending) │
|
||||
│ │ │
|
||||
│ └──► 开始轮询 queryCharacter() │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ GET /v1/videos/{id} │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 返回 username, profile_picture_url │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 5. characterStorageService.updateCharacter(completed) │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ 6. UI 更新显示角色卡片 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## UI 设计参考
|
||||
|
||||
### 1. 提取角色按钮位置
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ TaskItem (sora-2 已完成任务) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 🎬 [prompt text...] │
|
||||
│ │
|
||||
│ sora-2 | 10秒 | 1920x1080 | ✅ 已完成 │
|
||||
│ │
|
||||
│ [预览图] │
|
||||
│ │
|
||||
│ [删除] [下载] [插入] [缓存] [编辑] [👤 提取角色] │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2. 角色创建对话框
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 提取角色 [X] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 从视频中提取角色,创建后可在后续视频中通过 @username 引用 │
|
||||
│ │
|
||||
│ 源视频: 一只白色的猫在花园里玩耍... │
|
||||
│ 任务ID: sora-2:task_01kbh21pg... │
|
||||
│ │
|
||||
│ ───────────────────────────────────────────────────────────── │
|
||||
│ │
|
||||
│ 时间范围 (角色在视频中出现的位置) │
|
||||
│ │
|
||||
│ 开始时间: [0 ] 秒 结束时间: [3 ] 秒 │
|
||||
│ │
|
||||
│ ⓘ 时间范围需在 1-3 秒之间 │
|
||||
│ │
|
||||
│ ───────────────────────────────────────────────────────────── │
|
||||
│ │
|
||||
│ [取消] [创建角色] │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3. 角色卡片
|
||||
|
||||
```
|
||||
┌──────────────────────────────────┐
|
||||
│ ┌────────┐ │
|
||||
│ │ 头像 │ @xscjkajd.lunar... │
|
||||
│ │ 64x64 │ │
|
||||
│ └────────┘ [📋 复制] [🗑 删除] │
|
||||
│ │
|
||||
│ 来源: 白猫视频任务 │
|
||||
│ 创建于: 2024-01-15 14:30 │
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 4. @ 提及弹窗
|
||||
|
||||
```
|
||||
提示词输入框:
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 一只猫在追逐 @| │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────┐
|
||||
│ 📷 @xscjkajd.lunaradian │ ← 选中
|
||||
│ 📷 @abc123.character │
|
||||
│ ─────────────────────────────── │
|
||||
│ + 从视频提取新角色... │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 技术要点
|
||||
|
||||
### 1. 模型判断逻辑
|
||||
|
||||
```typescript
|
||||
// 判断是否可以提取角色
|
||||
const canExtractCharacter = (task: Task): boolean => {
|
||||
return (
|
||||
task.status === TaskStatus.COMPLETED &&
|
||||
task.type === TaskType.VIDEO &&
|
||||
task.remoteId?.startsWith('sora-2:') &&
|
||||
['sora-2', 'sora-2-pro'].includes(task.params.model || '')
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### 2. 时间范围验证
|
||||
|
||||
```typescript
|
||||
const validateTimestamps = (start: number, end: number, videoDuration: number): boolean => {
|
||||
const duration = end - start;
|
||||
return (
|
||||
start >= 0 &&
|
||||
end <= videoDuration &&
|
||||
duration >= 1 &&
|
||||
duration <= 3
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### 3. IndexedDB 存储结构
|
||||
|
||||
```typescript
|
||||
// 存储键: 'sora-characters'
|
||||
// 数据结构: SoraCharacter[]
|
||||
{
|
||||
id: 'sora-2-character:ch_xxx',
|
||||
username: 'xscjkajd.lunaradian',
|
||||
profilePictureUrl: 'https://...',
|
||||
permalink: 'https://...',
|
||||
sourceTaskId: 'local-task-uuid',
|
||||
sourceVideoId: 'sora-2:task_xxx',
|
||||
characterTimestamps: '0,3',
|
||||
status: 'completed',
|
||||
createdAt: 1705312200000,
|
||||
completedAt: 1705312260000,
|
||||
}
|
||||
```
|
||||
|
||||
## 测试要点
|
||||
|
||||
1. **API 集成测试**
|
||||
- 角色创建请求格式正确
|
||||
- 轮询查询正常工作
|
||||
- 错误响应处理
|
||||
|
||||
2. **UI 交互测试**
|
||||
- 提取角色按钮仅对符合条件的任务显示
|
||||
- 时间范围选择器约束正确
|
||||
- 角色创建状态实时更新
|
||||
- @ 提及弹窗正确显示和选择
|
||||
|
||||
3. **数据持久化测试**
|
||||
- 刷新页面后角色列表恢复
|
||||
- 角色删除后正确移除
|
||||
- 处理中任务恢复轮询
|
||||
|
||||
## 开发顺序建议
|
||||
|
||||
```
|
||||
Week 1:
|
||||
├── Day 1-2: Task 1-3 (类型定义 + API服务 + 存储服务)
|
||||
├── Day 3: Task 4 (状态管理 Hook)
|
||||
└── Day 4-5: Task 5-6 (创建对话框 + TaskItem按钮)
|
||||
|
||||
Week 2:
|
||||
├── Day 1-2: Task 7-8 (角色卡片 + 列表组件)
|
||||
├── Day 3-4: Task 9 (@ 提及功能)
|
||||
└── Day 5: Task 10-11 (状态同步 + 错误处理)
|
||||
```
|
||||
|
||||
## 后续扩展
|
||||
|
||||
1. **角色库面板** - 独立的角色管理界面
|
||||
2. **角色分组/标签** - 组织和筛选角色
|
||||
3. **角色使用统计** - 追踪角色使用频率
|
||||
4. **批量导出** - 导出角色数据备份
|
||||
5. **角色分享** - 跨设备同步角色(需后端支持)
|
||||
Reference in New Issue
Block a user