feat: 优化功能

This commit is contained in:
2025-12-22 00:15:02 +08:00
parent b80de78d7c
commit 8d7bc0d47f
12 changed files with 2513 additions and 595 deletions

View File

@@ -0,0 +1,385 @@
# 混剪场景编排功能重新设计提案
## 变更概述
**变更ID** refactor-mix-scene编排
**日期:** 2025-12-21
**优先级:**
## Why (为什么需要这个变更)
当前混剪功能的单一场景模式导致批量生成视频时内容高度相似,无法满足用户对视频多样性的需求。通过引入多候选场景模式,用户可以为每个场景准备多个候选素材,系统在批量混剪时从每个场景的候选中随机选择,从而生成内容差异显著的多个视频。这将显著提升用户体验,满足内容创作者对多样性的追求。
## 问题背景
当前的混剪场景编排功能存在以下限制:
1. **场景素材单一性**:每个场景只能选择一个视频素材,导致批量混剪时视频内容相似度极高
2. **多样性不足**:虽然后端通过随机起点实现差异化,但本质上仍使用相同的素材池
3. **用户需求未满足**:用户希望一次混剪能生成内容差异更大的多个视频
## 解决方案
### 核心设计理念
重新设计场景编排为**"多候选场景模式"**
- 每个场景包含**多个候选视频**(每个场景内视频不重复)
- 批量混剪时,**从每个场景的候选中随机选择一个**视频
- 仍然使用**随机起点**对选中的素材进行二次随机处理
- **两层随机性**(候选选择 + 随机起点)极大增加最终视频的多样性
### 关键特性
1. **场景多候选**:每个场景可以添加多个候选视频素材
2. **防重复机制**:同一场景内的候选视频不能重复
3. **智能填充**
- 一键自动为每个场景添加多个候选
- 支持从素材库快速选择
4. **随机生成**:批量混剪时从每个场景的候选中随机选择
5. **可视化展示**:清晰展示每个场景的候选数量和使用状态
## 技术架构调整
### 前端变更
**文件位置:** `frontend/app/web-gold/src/views/material/Mix.vue`
**主要改动:**
#### 1. 数据结构重构
```javascript
// 原有结构(单一素材)
const scene = {
fileId: 123,
fileUrl: 'xxx.mp4'
}
// 新结构(多候选)
const scene = {
index: 0,
duration: 3,
candidates: [
{fileId: 123, fileUrl: 'xxx1.mp4', fileDuration: 60},
{fileId: 124, fileUrl: 'xxx2.mp4', fileDuration: 45},
{fileId: 125, fileUrl: 'xxx3.mp4', fileDuration: 55}
]
}
```
#### 2. 场景格子 UI 更新
- **候选数量标签**:在场景格子上方显示 `候选 3/10`
- **候选列表预览**:悬停时显示候选素材的缩略图列表
- **状态指示**
- 空场景:虚线边框,提示"点击选择"
- 已填充:实线边框,显示候选数量徽标
- 部分填充:不同颜色标识
- **移除按钮**:每个候选右上角显示删除按钮
#### 3. 交互流程优化
- **点击场景格子** → 打开候选选择弹窗
- **弹窗内容**
- 顶部显示:`场景1 - 已选择 3/10 个候选`
- 主体区域:素材库网格(支持多选)
- 底部操作:`全选` `反选` `确定` `取消`
- **批量操作**
- 支持 Ctrl+Click 多选
- 支持 Shift+Click 范围选择
- 一键全选/清空
#### 4. 一键填充增强(核心优化)
**功能描述:**
一键填充功能从原有的"随机填充空场景"升级为"智能多候选填充",能够自动为每个场景分配多个不重复的候选素材。
**填充策略选择:**
```javascript
// 提供三种填充模式
const FILL_STRATEGIES = {
EMPTY_ONLY: 'empty_only', // 仅填充空场景(默认)
SUPPLEMENT: 'supplement', // 补充不足场景到3个候选
FULL_FILL: 'full_fill' // 全量重新填充所有场景
}
```
**智能分配算法:**
```javascript
/**
* 优化后的一键填充逻辑
* @param strategy 填充策略
* @param targetCount 目标候选数量默认3-5个
*/
const autoFillScenes = (strategy = 'empty_only', targetCount = 3) => {
// 1. 收集所有可用的素材
const availableMaterials = [...groupFiles.value];
// 2. 统计当前已使用的素材(避免重复)
const usedMaterialIds = new Set();
scenes.value.forEach(scene => {
scene.candidates.forEach(candidate => {
usedMaterialIds.add(candidate.fileId);
});
});
// 3. 过滤可用素材(排除已使用的)
const unusedMaterials = availableMaterials.filter(
material => !usedMaterialIds.has(material.id)
);
// 4. 根据策略执行填充
scenes.value.forEach((scene, sceneIndex) => {
const currentCount = scene.candidates.length;
let needFill = false;
let fillCount = targetCount;
// 判断是否需要填充
switch (strategy) {
case 'empty_only':
needFill = currentCount === 0;
break;
case 'supplement':
needFill = currentCount < targetCount;
fillCount = targetCount - currentCount;
break;
case 'full_fill':
needFill = true;
fillCount = targetCount;
break;
}
if (needFill && unusedMaterials.length > 0) {
// 5. 为当前场景随机选择素材(确保不重复)
const selectedMaterials = randomlySelectMaterials(
fillCount,
unusedMaterials,
sceneIndex // 使用场景索引作为随机种子的一部分
);
// 6. 添加到场景候选列表
scene.candidates.push(...selectedMaterials);
// 7. 从可用素材中移除已选择的(避免分配给其他场景)
selectedMaterials.forEach(selected => {
const index = unusedMaterials.findIndex(m => m.id === selected.id);
if (index > -1) {
unusedMaterials.splice(index, 1);
}
});
}
});
// 8. 显示填充结果提示
showFillResultNotification();
}
/**
* 随机选择素材工具函数
* @param count 需要选择的数量
* @param materials 素材池
* @param seed 随机种子(基于场景索引)
* @returns 选中的素材数组
*/
const randomlySelectMaterials = (count, materials, seed) => {
// 使用Fisher-Yates洗牌算法确保随机性
const shuffled = [...materials];
// 基于种子创建确定性随机(同一场景索引结果一致)
const random = createDeterministicRandom(seed);
// 洗牌
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
// 返回前N个
return shuffled.slice(0, Math.min(count, shuffled.length));
}
```
**防重复机制(优化):**
1. **场景内去重**:确保同一场景内的候选素材不重复(必须)
2. **跨场景复用**(可选):允许同一素材在不同场景中出现
- 优点:提高素材利用率,适合素材库不足的场景
- 缺点:可能降低视频差异性
- 配置项:用户可选择"严格模式"(禁止跨场景重复)或"宽松模式"(允许跨场景重复)
3. **实时更新**:每次填充后立即更新已使用素材列表
4. **视觉反馈**
- 严格模式:已使用素材显示禁用状态
- 宽松模式:已使用素材显示使用次数标记(如"已使用 2 次"
**数量控制逻辑:**
- **默认数量**:每个场景填充 3 个候选
- **自适应调整**:根据素材库总量动态调整
- 素材库 < 10个每个场景 1-2个候选
- 素材库 10-50个每个场景 3-4个候选
- 素材库 > 50个每个场景 4-5个候选
- **上限保护**:单个场景最多 10 个候选
**用户体验优化:**
- **进度提示**:填充过程中显示进度条
- **结果反馈**:填充完成后显示"已为X个场景填充Y个候选"
- **撤销操作**:支持一键撤销最近的填充操作
- **智能建议**:根据素材库情况建议最佳填充策略
**边界情况处理:**
1. **素材库不足场景**
```javascript
// 场景5个场景每个需要3个候选但素材库只有10个素材
// 解决方案:
// 1. 自动切换到"宽松模式",允许跨场景复用
// 2. 调整目标数量:根据素材库/场景数计算最优分配
// 3. 提示用户:"素材库不足,已自动调整为宽松模式"
```
2. **素材库为空**
- 提示"素材库为空,请先上传素材"
- 禁用一键填充按钮
- 提供快速跳转链接到素材上传页
3. **场景数过多**
- 当场景数 × 目标候选数 > 素材库数量时
- 自动建议减少场景数或增加素材库
- 提供"智能合并场景"建议
4. **批量操作确认**
- 全选/清空等操作前显示确认对话框
- 显示影响范围:如"将影响 5 个场景,共 15 个候选"
- 提供预览功能
5. **数据一致性检查**
- 页面刷新后自动恢复场景配置
- 检测并修复损坏的场景数据
- 提示用户进行数据同步
**示例场景:**
```
素材库:[A, B, C, D, E, F, G, H, I, J] (10个素材)
场景数3个场景
目标每个场景3个候选
填充结果:
- 场景1[A, D, G]
- 场景2[B, E, H]
- 场景3[C, F, I]
剩余素材:[J] (未使用,避免浪费)
```
#### 5. 候选管理功能
- **添加候选**:从素材库选择 → 检查重复 → 添加到候选列表
- **移除候选**:点击候选右上角 × → 从列表中移除
- **查看候选详情**:点击场景格子 → 弹窗显示所有候选详情
- **清空场景**:点击"清空"按钮 → 移除所有候选
#### 6. 防重复验证
- **前端实时检查**:选择素材时检查是否已存在于候选列表
- **视觉反馈**:已选择的素材显示禁用状态或"已选择"标记
- **提示信息**:尝试添加重复素材时显示提示"该素材已在候选列表中"
#### 7. 数据提交调整
```javascript
// 修改 handleSubmit 中的数据结构
const submitData = {
title: formData.value.title,
scenes: scenes.value.map(scene => ({
duration: scene.duration,
candidates: scene.candidates
})),
produceCount: formData.value.produceCount,
cropMode: formData.value.cropMode
};
```
### 后端变更
**文件位置:**
- `yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/vo/MixTaskSaveReqVO.java`
- `yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/service/MixTaskServiceImpl.java`
- `yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/media/BatchProduceAlignment.java`
**主要改动:**
1. 修改 API 数据结构:支持场景多候选
2. 更新批量混剪逻辑:从每个场景候选中随机选择素材,然后使用随机起点
3. 实现两层随机算法:第一层从候选中选择,第二层使用随机起点
### 数据库变更
**影响范围:** 无需数据库结构变更
- 前端本地存储场景配置
- 后端通过 JSON 传递候选数据
## 预期效果
### 用户体验提升
1. **多样性提升**:批量混剪的视频内容差异显著增大
2. **操作便捷性**:一键填充和批量选择功能
3. **可视化体验**:清晰的场景候选展示
### 技术收益
1. **代码复用**:保持现有框架结构
2. **性能优化**:随机选择算法高效
3. **向后兼容**:可选模式,不影响现有功能
## 风险评估
### 技术风险
- **中等风险**:需要修改前后端多个文件
- **兼容性**:需要确保现有功能不受影响
### 缓解措施
1. 渐进式迁移:保留现有模式作为备选
2. 充分测试:覆盖各种使用场景
3. 回滚方案:保留现有代码分支
## 实施计划
### 阶段一:数据结构设计
- [ ] 设计新的前后端数据结构
- [ ] 定义 API 接口规范
### 阶段二:前端实现
- [ ] 修改 Mix.vue 组件
- [ ] 更新数据处理逻辑
- [ ] 优化用户界面
### 阶段三:后端实现
- [ ] 更新 VO 对象
- [ ] 修改混剪服务逻辑
- [ ] 调整随机算法
### 阶段四:测试验证
- [ ] 单元测试
- [ ] 集成测试
- [ ] 用户验收测试
## 成功标准
1. **功能完整性**:所有设计功能正常工作
2. **性能指标**:批量混剪性能无明显下降
3. **用户体验**:操作流程顺畅,界面直观
4. **代码质量**:代码结构清晰,有充分注释
## 相关资源
- **前端代码:** `frontend/app/web-gold/src/views/material/Mix.vue`
- **后端 API** `yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/`
- **混剪服务:** `yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/service/MixTaskServiceImpl.java`
- **批量处理:** `yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/media/BatchProduceAlignment.java`
## 决策点
1. **默认候选数量**建议每个场景默认3-5个候选
2. **最大候选限制**建议每个场景最多10个候选
3. **随机算法**基于文件ID和场景索引的确定性随机
4. **UI 展示方式**:采用标签页或下拉列表展示候选
## 后续优化
1. **智能推荐**:基于视频相似度推荐候选
2. **场景模板**:保存和复用场景配置
3. **批量编辑**:支持跨场景批量操作