8.6 KiB
8.6 KiB
火山引擎视频主子模型验证文档
✅ 验证时间:2025-12-09
✅ 验证状态:所有流程验证通过
📋 主子模型架构设计
1. 数据库Schema ✅
文件:lib/db/schema.ts
// 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个)
{
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个)
-
doubao-seedance-1-0-pro-250528 - Pro版(全功能)
isSubModel: trueparentModelId: 'volcano-video-master'- 支持:文生视频、图生首帧、首尾帧
-
doubao-seedance-1-0-pro-fast-251015 - Pro Fast版(快速)
isSubModel: trueparentModelId: 'volcano-video-master'- 支持:文生视频、图生首帧
-
doubao-seedance-1-0-lite-i2v-250428 - Lite I2V版(图生视频)
isSubModel: trueparentModelId: 'volcano-video-master'- 支持:图生首帧、首尾帧、参考图
-
doubao-seedance-1-0-lite-t2v-250428 - Lite T2V版(文生视频)
isSubModel: trueparentModelId: 'volcano-video-master'- 支持:文生视频
🔄 完整业务流程验证
步骤1:管理员添加模型 ✅
前端UI(admin-settings-client.tsx)
// 只显示主模型配置界面
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)
// 检测到只传了主模型,自动补充子模型
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)
.where(
and(
eq(aiModel.isEnabled, true),
eq(aiProvider.isEnabled, true),
eq(aiModel.isSubModel, false) // ⭐ 只返回主模型
)
)
用户看到:
- ✅ 模型下拉列表只显示:
🎬 火山引擎视频 - ✅ 不显示4个子模型(doubao-seedance-xxx)
步骤3:视频参数配置 ✅
参数面板(components/video-params-bar.tsx)
// 当选择火山引擎视频模型时,显示参数配置面板
{selectedModel?.type === 'volcano-video' && (
<VideoParamsBar
modelName="视频 3.0"
onParamsChange={handleParamsChange}
/>
)}
用户操作:
- ✅ 选择生成模式:首尾帧/文生视频/智能多帧/主体参考
- ✅ 调整分辨率:480p/720p/1080p
- ✅ 调整宽高比:21:9 ~ 9:16
- ✅ 设置时长:5s/10s
- ✅ 选择运镜:16种运镜效果(环绕/推进/拉远等)
- ✅ 高级选项:水印、种子、返回尾帧
参数传递:
{
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)
流程:
// 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)
// 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请求
{
"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:正确调用选中的子模型
- ✅ 参数:完整传递并转换
无任何遗漏或错误! 🎉