# 火山引擎视频主子模型验证文档 ## ✅ 验证时间: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' && ( )} ``` **用户操作**: - ✅ 选择生成模式:首尾帧/文生视频/智能多帧/主体参考 - ✅ 调整分辨率: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:正确调用选中的子模型 - ✅ 参数:完整传递并转换 **无任何遗漏或错误!** 🎉