312 lines
8.6 KiB
Markdown
312 lines
8.6 KiB
Markdown
# 火山引擎视频主子模型验证文档
|
||
|
||
## ✅ 验证时间:2025-12-09
|
||
## ✅ 验证状态:所有流程验证通过
|
||
|
||
---
|
||
|
||
## 📋 主子模型架构设计
|
||
|
||
### 1. 数据库Schema ✅
|
||
**文件**:`lib/db/schema.ts`
|
||
|
||
```typescript
|
||
// AiModel表新增字段
|
||
isSubModel: boolean("is_sub_model").notNull().default(false)
|
||
parentModelId: uuid("parent_model_id")
|
||
```
|
||
|
||
- **主模型**:`isSubModel = false`, `parentModelId = null`
|
||
- **子模型**:`isSubModel = true`, `parentModelId = 主模型ID`
|
||
|
||
---
|
||
|
||
### 2. 模型预设配置 ✅
|
||
**文件**:`lib/ai/volcano-video-models.ts`
|
||
|
||
#### 主模型(1个)
|
||
```typescript
|
||
{
|
||
modelId: 'volcano-video-master',
|
||
displayName: '🎬 火山引擎视频',
|
||
description: '支持文生视频、图生视频等多种模式,自动选择最佳模型',
|
||
isSubModel: false, // 主模型标记
|
||
capabilities: {
|
||
supportedModes: ['text-to-video', 'first-frame', 'first-last-frame', 'reference-images'],
|
||
supportedResolutions: ['480p', '720p', '1080p'],
|
||
supportedRatios: ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9', 'adaptive'],
|
||
durationRange: { min: 2, max: 12 },
|
||
supportWatermark: true,
|
||
supportCameraFixed: true,
|
||
supportSeed: true,
|
||
supportReturnLastFrame: true,
|
||
maxReferenceImages: 4,
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 子模型(4个)
|
||
1. **doubao-seedance-1-0-pro-250528** - Pro版(全功能)
|
||
- `isSubModel: true`
|
||
- `parentModelId: 'volcano-video-master'`
|
||
- 支持:文生视频、图生首帧、首尾帧
|
||
|
||
2. **doubao-seedance-1-0-pro-fast-251015** - Pro Fast版(快速)
|
||
- `isSubModel: true`
|
||
- `parentModelId: 'volcano-video-master'`
|
||
- 支持:文生视频、图生首帧
|
||
|
||
3. **doubao-seedance-1-0-lite-i2v-250428** - Lite I2V版(图生视频)
|
||
- `isSubModel: true`
|
||
- `parentModelId: 'volcano-video-master'`
|
||
- 支持:图生首帧、首尾帧、参考图
|
||
|
||
4. **doubao-seedance-1-0-lite-t2v-250428** - Lite T2V版(文生视频)
|
||
- `isSubModel: true`
|
||
- `parentModelId: 'volcano-video-master'`
|
||
- 支持:文生视频
|
||
|
||
---
|
||
|
||
## 🔄 完整业务流程验证
|
||
|
||
### 步骤1:管理员添加模型 ✅
|
||
|
||
#### 前端UI(`admin-settings-client.tsx`)
|
||
```typescript
|
||
// 只显示主模型配置界面
|
||
const masterModel = data.presets.find(p => p.modelId === 'volcano-video-master');
|
||
setVolcanoVideoModels([masterModel]); // 只显示1个主模型配置
|
||
```
|
||
|
||
**用户看到**:
|
||
- ✅ 模型配置对话框只显示1个模型
|
||
- ✅ 模型ID:`volcano-video-master`
|
||
- ✅ 显示名称:`🎬 火山引擎视频`(可修改)
|
||
- ✅ 描述:支持文生视频、图生视频等(可修改)
|
||
|
||
#### 后端API(`/api/admin/volcano-video-models`)
|
||
```typescript
|
||
// 检测到只传了主模型,自动补充子模型
|
||
if (hasMasterOnly) {
|
||
const masterModel = {...}; // 主模型配置
|
||
const subModels = VOLCANO_VIDEO_MODEL_PRESETS.filter(p => p.isSubModel); // 4个子模型
|
||
modelsToAdd = [masterModel, ...subModels]; // 1个主模型 + 4个子模型
|
||
}
|
||
```
|
||
|
||
**实际添加**:
|
||
- ✅ 插入5条数据库记录
|
||
- ✅ 1个主模型:`isSubModel=false`
|
||
- ✅ 4个子模型:`isSubModel=true`, `parentModelId=主模型ID`
|
||
- ✅ 通过UPDATE语句关联子模型到主模型
|
||
|
||
---
|
||
|
||
### 步骤2:前端模型选择 ✅
|
||
|
||
#### 查询逻辑(`lib/db/queries.ts::getEnabledAiModelsWithProvider`)
|
||
```typescript
|
||
.where(
|
||
and(
|
||
eq(aiModel.isEnabled, true),
|
||
eq(aiProvider.isEnabled, true),
|
||
eq(aiModel.isSubModel, false) // ⭐ 只返回主模型
|
||
)
|
||
)
|
||
```
|
||
|
||
**用户看到**:
|
||
- ✅ 模型下拉列表只显示:`🎬 火山引擎视频`
|
||
- ✅ 不显示4个子模型(doubao-seedance-xxx)
|
||
|
||
---
|
||
|
||
### 步骤3:视频参数配置 ✅
|
||
|
||
#### 参数面板(`components/video-params-bar.tsx`)
|
||
```typescript
|
||
// 当选择火山引擎视频模型时,显示参数配置面板
|
||
{selectedModel?.type === 'volcano-video' && (
|
||
<VideoParamsBar
|
||
modelName="视频 3.0"
|
||
onParamsChange={handleParamsChange}
|
||
/>
|
||
)}
|
||
```
|
||
|
||
**用户操作**:
|
||
- ✅ 选择生成模式:首尾帧/文生视频/智能多帧/主体参考
|
||
- ✅ 调整分辨率:480p/720p/1080p
|
||
- ✅ 调整宽高比:21:9 ~ 9:16
|
||
- ✅ 设置时长:5s/10s
|
||
- ✅ 选择运镜:16种运镜效果(环绕/推进/拉远等)
|
||
- ✅ 高级选项:水印、种子、返回尾帧
|
||
|
||
**参数传递**:
|
||
```typescript
|
||
{
|
||
mode: "first-last-frame",
|
||
resolution: "720p",
|
||
ratio: "16:9",
|
||
duration: 5,
|
||
cameraMove: "orbit", // 环绕运镜
|
||
watermark: true,
|
||
seed: 12345
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 步骤4:智能子模型选择 ✅
|
||
|
||
#### 后端逻辑(`lib/ai/tools/generate-video.ts::selectBestSubModel`)
|
||
|
||
**流程**:
|
||
```typescript
|
||
// 1. 查询所有子模型
|
||
const subModels = await getSubModelsByParentModelId('主模型ID');
|
||
// 返回:4个子模型(isSubModel=true, parentModelId=主模型ID)
|
||
|
||
// 2. 筛选支持用户选择模式的子模型
|
||
const compatibleModels = subModels.filter(m => {
|
||
const caps = m.model.capabilities;
|
||
return caps.supportedModes.includes('first-last-frame') &&
|
||
caps.supportedResolutions.includes('720p');
|
||
});
|
||
|
||
// 3. 智能优先级排序
|
||
const priority = {
|
||
"doubao-seedance-1-0-pro-250528": 10, // 最高优先级
|
||
"doubao-seedance-1-0-pro-fast-251015": 8,
|
||
"doubao-seedance-1-0-lite-i2v-250428": 6,
|
||
"doubao-seedance-1-0-lite-t2v-250428": 5,
|
||
};
|
||
|
||
// 4. 选择最佳模型
|
||
const bestModel = compatibleModels.sort((a, b) =>
|
||
priority[b.model.modelId] - priority[a.model.modelId]
|
||
)[0];
|
||
```
|
||
|
||
**示例1:首尾帧模式 + 720p**
|
||
- 筛选结果:Pro, Lite I2V(2个支持首尾帧)
|
||
- 选择:`doubao-seedance-1-0-pro-250528`(优先级10)
|
||
|
||
**示例2:文生视频 + 1080p**
|
||
- 筛选结果:Pro, Pro Fast, Lite T2V(3个支持文生)
|
||
- 选择:`doubao-seedance-1-0-pro-250528`(优先级10)
|
||
|
||
**示例3:参考图 + 720p**
|
||
- 筛选结果:Lite I2V(唯一支持参考图)
|
||
- 选择:`doubao-seedance-1-0-lite-i2v-250428`
|
||
|
||
---
|
||
|
||
### 步骤5:API调用 ✅
|
||
|
||
#### 提示词构建(`lib/ai/providers/volcano-video.ts::buildFullPrompt`)
|
||
```typescript
|
||
// 1. 用户提示词
|
||
"一个3D形象的小男孩,在公园滑滑板"
|
||
|
||
// 2. 运镜描述(转换为自然语言)
|
||
+ "360度环绕运镜"
|
||
|
||
// 3. API参数
|
||
+ "--rt 16:9 --dur 5 --rs 720p --cf false --wm true"
|
||
|
||
// 最终提示词
|
||
"一个3D形象的小男孩,在公园滑滑板 360度环绕运镜 --rt 16:9 --dur 5 --rs 720p --cf false --wm true"
|
||
```
|
||
|
||
#### 火山引擎API请求
|
||
```json
|
||
{
|
||
"model": "doubao-seedance-1-0-pro-250528",
|
||
"content": [
|
||
{
|
||
"type": "text",
|
||
"text": "一个3D形象的小男孩,在公园滑滑板 360度环绕运镜 --rt 16:9 --dur 5 --rs 720p --cf false --wm true"
|
||
},
|
||
{
|
||
"type": "image_url",
|
||
"image_url": { "url": "data:image/jpeg;base64,..." },
|
||
"role": "first_frame"
|
||
},
|
||
{
|
||
"type": "image_url",
|
||
"image_url": { "url": "data:image/jpeg;base64,..." },
|
||
"role": "last_frame"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 关键验证点总结
|
||
|
||
| 验证项 | 状态 | 说明 |
|
||
|--------|------|------|
|
||
| ✅ 数据库Schema | 通过 | isSubModel + parentModelId 字段已添加 |
|
||
| ✅ 模型预设配置 | 通过 | 1个主模型 + 4个子模型,关系正确 |
|
||
| ✅ 管理员UI | 通过 | 只显示1个主模型配置 |
|
||
| ✅ 批量添加API | 通过 | 自动添加主模型+4个子模型 |
|
||
| ✅ 前端模型列表 | 通过 | 只显示主模型(子模型被过滤) |
|
||
| ✅ 参数配置面板 | 通过 | 所有参数完整可配置 |
|
||
| ✅ 子模型查询 | 通过 | getSubModelsByParentModelId 正确实现 |
|
||
| ✅ 智能模型选择 | 通过 | 根据模式+参数智能匹配最佳子模型 |
|
||
| ✅ 运镜模式转换 | 通过 | 转换为自然语言提示词 |
|
||
| ✅ API请求格式 | 通过 | 符合火山引擎API规范 |
|
||
|
||
---
|
||
|
||
## 📊 数据流图
|
||
|
||
```
|
||
用户操作
|
||
↓
|
||
[选择:🎬 火山引擎视频] ← 前端只显示主模型
|
||
↓
|
||
[配置参数面板]
|
||
├─ 模式:首尾帧
|
||
├─ 分辨率:720p
|
||
├─ 宽高比:16:9
|
||
├─ 时长:5s
|
||
├─ 运镜:环绕
|
||
└─ 高级选项...
|
||
↓
|
||
[提交生成请求]
|
||
↓
|
||
后端智能选择
|
||
├─ 查询主模型ID:volcano-video-master
|
||
├─ 查询子模型:4个模型
|
||
├─ 筛选兼容:支持首尾帧+720p
|
||
├─ 优先级排序:Pro > Pro Fast > Lite
|
||
└─ 选择:doubao-seedance-1-0-pro-250528
|
||
↓
|
||
[构建API请求]
|
||
├─ 提示词 + 运镜描述 + 参数
|
||
├─ 图片处理(Base64 + S3存储)
|
||
└─ 调用火山引擎API
|
||
↓
|
||
[返回生成结果]
|
||
└─ 视频URL + 元数据
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ 最终结论
|
||
|
||
**所有主子模型关系和前端功能串联已验证通过!**
|
||
|
||
- ✅ 管理员:只配置1个主模型
|
||
- ✅ 前端:只显示1个主模型
|
||
- ✅ 后端:智能选择4个子模型之一
|
||
- ✅ API:正确调用选中的子模型
|
||
- ✅ 参数:完整传递并转换
|
||
|
||
**无任何遗漏或错误!** 🎉
|
||
|