13 KiB
13 KiB
混剪场景编排功能重新设计提案
变更概述
变更ID: refactor-mix-scene编排 日期: 2025-12-21 优先级: 高
Why (为什么需要这个变更)
当前混剪功能的单一场景模式导致批量生成视频时内容高度相似,无法满足用户对视频多样性的需求。通过引入多候选场景模式,用户可以为每个场景准备多个候选素材,系统在批量混剪时从每个场景的候选中随机选择,从而生成内容差异显著的多个视频。这将显著提升用户体验,满足内容创作者对多样性的追求。
问题背景
当前的混剪场景编排功能存在以下限制:
- 场景素材单一性:每个场景只能选择一个视频素材,导致批量混剪时视频内容相似度极高
- 多样性不足:虽然后端通过随机起点实现差异化,但本质上仍使用相同的素材池
- 用户需求未满足:用户希望一次混剪能生成内容差异更大的多个视频
解决方案
核心设计理念
重新设计场景编排为**"多候选场景模式"**:
- 每个场景包含多个候选视频(每个场景内视频不重复)
- 批量混剪时,从每个场景的候选中随机选择一个视频
- 仍然使用随机起点对选中的素材进行二次随机处理
- 两层随机性(候选选择 + 随机起点)极大增加最终视频的多样性
关键特性
- 场景多候选:每个场景可以添加多个候选视频素材
- 防重复机制:同一场景内的候选视频不能重复
- 智能填充:
- 一键自动为每个场景添加多个候选
- 支持从素材库快速选择
- 随机生成:批量混剪时从每个场景的候选中随机选择
- 可视化展示:清晰展示每个场景的候选数量和使用状态
技术架构调整
前端变更
文件位置: frontend/app/web-gold/src/views/material/Mix.vue
主要改动:
1. 数据结构重构
// 原有结构(单一素材)
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. 一键填充增强(核心优化)
功能描述: 一键填充功能从原有的"随机填充空场景"升级为"智能多候选填充",能够自动为每个场景分配多个不重复的候选素材。
填充策略选择:
// 提供三种填充模式
const FILL_STRATEGIES = {
EMPTY_ONLY: 'empty_only', // 仅填充空场景(默认)
SUPPLEMENT: 'supplement', // 补充不足场景到3个候选
FULL_FILL: 'full_fill' // 全量重新填充所有场景
}
智能分配算法:
/**
* 优化后的一键填充逻辑
* @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));
}
防重复机制(优化):
- 场景内去重:确保同一场景内的候选素材不重复(必须)
- 跨场景复用(可选):允许同一素材在不同场景中出现
- 优点:提高素材利用率,适合素材库不足的场景
- 缺点:可能降低视频差异性
- 配置项:用户可选择"严格模式"(禁止跨场景重复)或"宽松模式"(允许跨场景重复)
- 实时更新:每次填充后立即更新已使用素材列表
- 视觉反馈:
- 严格模式:已使用素材显示禁用状态
- 宽松模式:已使用素材显示使用次数标记(如"已使用 2 次")
数量控制逻辑:
- 默认数量:每个场景填充 3 个候选
- 自适应调整:根据素材库总量动态调整
- 素材库 < 10个:每个场景 1-2个候选
- 素材库 10-50个:每个场景 3-4个候选
- 素材库 > 50个:每个场景 4-5个候选
- 上限保护:单个场景最多 10 个候选
用户体验优化:
- 进度提示:填充过程中显示进度条
- 结果反馈:填充完成后显示"已为X个场景填充Y个候选"
- 撤销操作:支持一键撤销最近的填充操作
- 智能建议:根据素材库情况建议最佳填充策略
边界情况处理:
-
素材库不足场景:
// 场景:5个场景,每个需要3个候选,但素材库只有10个素材 // 解决方案: // 1. 自动切换到"宽松模式",允许跨场景复用 // 2. 调整目标数量:根据素材库/场景数计算最优分配 // 3. 提示用户:"素材库不足,已自动调整为宽松模式" -
素材库为空:
- 提示"素材库为空,请先上传素材"
- 禁用一键填充按钮
- 提供快速跳转链接到素材上传页
-
场景数过多:
- 当场景数 × 目标候选数 > 素材库数量时
- 自动建议减少场景数或增加素材库
- 提供"智能合并场景"建议
-
批量操作确认:
- 全选/清空等操作前显示确认对话框
- 显示影响范围:如"将影响 5 个场景,共 15 个候选"
- 提供预览功能
-
数据一致性检查:
- 页面刷新后自动恢复场景配置
- 检测并修复损坏的场景数据
- 提示用户进行数据同步
示例场景:
素材库:[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. 数据提交调整
// 修改 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.javayudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/service/MixTaskServiceImpl.javayudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/media/BatchProduceAlignment.java
主要改动:
- 修改 API 数据结构:支持场景多候选
- 更新批量混剪逻辑:从每个场景候选中随机选择素材,然后使用随机起点
- 实现两层随机算法:第一层从候选中选择,第二层使用随机起点
数据库变更
影响范围: 无需数据库结构变更
- 前端本地存储场景配置
- 后端通过 JSON 传递候选数据
预期效果
用户体验提升
- 多样性提升:批量混剪的视频内容差异显著增大
- 操作便捷性:一键填充和批量选择功能
- 可视化体验:清晰的场景候选展示
技术收益
- 代码复用:保持现有框架结构
- 性能优化:随机选择算法高效
- 向后兼容:可选模式,不影响现有功能
风险评估
技术风险
- 中等风险:需要修改前后端多个文件
- 兼容性:需要确保现有功能不受影响
缓解措施
- 渐进式迁移:保留现有模式作为备选
- 充分测试:覆盖各种使用场景
- 回滚方案:保留现有代码分支
实施计划
阶段一:数据结构设计
- 设计新的前后端数据结构
- 定义 API 接口规范
阶段二:前端实现
- 修改 Mix.vue 组件
- 更新数据处理逻辑
- 优化用户界面
阶段三:后端实现
- 更新 VO 对象
- 修改混剪服务逻辑
- 调整随机算法
阶段四:测试验证
- 单元测试
- 集成测试
- 用户验收测试
成功标准
- 功能完整性:所有设计功能正常工作
- 性能指标:批量混剪性能无明显下降
- 用户体验:操作流程顺畅,界面直观
- 代码质量:代码结构清晰,有充分注释
相关资源
- 前端代码:
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
决策点
- 默认候选数量:建议每个场景默认3-5个候选
- 最大候选限制:建议每个场景最多10个候选
- 随机算法:基于文件ID和场景索引的确定性随机
- UI 展示方式:采用标签页或下拉列表展示候选
后续优化
- 智能推荐:基于视频相似度推荐候选
- 场景模板:保存和复用场景配置
- 批量编辑:支持跨场景批量操作