# #1197 预览生成接口技术方案(v2) > 更新说明:v2 新增「多版本预览生成」能力,支持一个模板生成多个不重复的预览视频,左侧列表展示,用户可挑选满意的版本转正式生成。 ## 1. 背景与目标 **现状**:智能剪辑「一键生成」第3步预览生成被跳过,用户直接进入正式生成,缺少效果预览环节。 **目标**: 1. ✅ 实现真正的预览生成(低分辨率快速出片) 2. ✅ **支持生成 1~N 个不重复的预览版本**(默认 3 个),左侧列表展示 3. ✅ 预览满意后可一键转正式生成(复用素材下载缓存) 4. ✅ 不计入用户配额,不占用正式生成次数 --- ## 2. 现有生成链路分析 ### 2.1 链路总览 ``` API 触发生成 → GenerationTask入库 → Celery异步任务 → 下载素材 → 构建plan/clips → UnifiedRenderService渲染 → 混音后处理 → OSS上传 + 查重 → 更新状态 ``` ### 2.2 决定视频差异的变量 要做"多个不重复版本",先分析哪些环节可以引入变化: | 变量 | 当前行为 | 能否引入变化 | 影响程度 | |------|---------|------------|---------| | 素材选择 | 按 asset_ids 顺序全用 | ✅ 可随机选择子集/不同组合 | 大 | | 素材排序 | 按 asset_ids 顺序 | ✅ 可 shuffle 重排 | 大 | | 配音选择 | 固定 voice_library_id | ✅ 可选不同音色 | 中 | | 标题选择 | 固定 title_ids 或随机选 | ✅ 可选不同标题 | 中 | | BGM | 固定 bgm_config | ✅ 可选不同BGM | 小 | | 转场效果 | 模板固定 | ✅ 可随机化转场类型 | 小 | | 播放速度 | 模板固定 | ✅ 可微调速度 | 小 | | 分辨率/码率 | 固定 | ✅ 预览可降级 | 不影响内容 | ### 2.3 可复用能力 - 任务创建与状态管理:`GenerationTask` + `CreateGenerationTaskUseCase` - 素材下载与预处理:`_download_all_assets` - 统一渲染引擎:`UnifiedRenderService` - 分辨率配置:`resolution` 字段已支持 - 批量任务:`batch_id` 字段已存在(可用于预览组) --- ## 3. 总体方案:复用现有链路 + 多变体引擎 **核心思路**:沿用 v1 的"复用现有生成链路 + is_preview 标记"方案,在此基础上增加「多版本生成」能力。 **架构**: ``` 预览生成请求(count=N) ↓ 创建预览批次(preview_batch) ↓ 变体引擎生成 N 个变体参数(variation seed + 参数组合) ↓ 为每个变体创建 1 个 GenerationTask(is_preview=true) ↓ N 个 Celery 任务并行执行(走现有生成链路,参数降级) ↓ N 个结果汇聚,前端左侧列表展示 ``` --- ## 4. 详细设计 ### 4.1 数据模型变更 #### 4.1.1 GenerationTask 新增字段 ```python # 现有字段保留,新增: is_preview: bool = False """是否为预览生成""" preview_batch_id: str = "" """预览批次 ID(同批次的 N 个预览共享一个 batch)""" variant_seed: int = 0 """变体种子,用于控制随机化行为(素材选择、排序、转场等)""" variant_params: dict = field(default_factory=dict) """变体参数快照(记录本次使用了哪些素材、标题、配音等,可追溯) { "asset_ids": [...], # 实际选用的素材子集 "title_id": "", # 选用的标题 "voice_id": "", # 选用的配音 "transition_style": "", # 转场风格 "bgm_track": "", # BGM 音轨 } """ ``` #### 4.1.2 GeneratedVideo 新增字段 ```python is_preview: bool = False """是否为预览视频""" preview_batch_id: str = "" """所属预览批次""" variant_index: int = 0 """在批次中的序号(0, 1, 2...)""" ``` #### 4.1.3 迁移方案 alembic 新增 migration,两个表各加 4 个字段,默认值为空/false,无数据回填成本。 --- ### 4.2 变体引擎(Variant Engine) **核心组件**:根据 count 和 seed,生成 N 组互不相同的生成参数。 #### 4.2.1 变纬度设计 | 维度 | 策略 | 说明 | |------|------|------| | **素材子集选择** | 从素材池中随机选 M 个(M=min(素材数, 模板clip数*2)) | 版本差异最大的来源 | | **素材排序** | 随机打乱顺序 | 影响叙事节奏 | | **标题选择** | 从 title_ids 中随机选 1 个 | 影响文案内容 | | **配音选择** | 从 voice_ids 中随机选 1 个(如有多个) | 影响听觉体验 | | **转场风格** | 从预设转场池中随机选 1 种 | 影响视觉过渡 | | **BGM 选择** | 从 bgm 列表中随机选 1 首(如有配置) | 影响氛围 | #### 4.2.2 去重机制 - 同一批次内,变体参数必须两两不同(至少素材组合或排序不同) - 使用 `variant_seed` 保证可复现(相同 seed → 相同变体) - 如果素材数量不足导致无法生成 N 个不同版本,按实际能生成的数量返回 #### 4.2.3 接口设计 ```python def generate_variants( count: int, seed: int, asset_pool: list[str], # 可用素材 ID 列表 title_pool: list[str] = [], # 可用标题 ID 列表 voice_pool: list[str] = [], # 可用配音 ID 列表 template_id: str = "", ) -> list[dict]: """ 生成 count 组变体参数。 每组参数包含:asset_ids(选用的素材+排序)、title_id、voice_id、 transition_style 等,确保两两不同。 """ ``` --- ### 4.3 API 层设计 #### 4.3.1 预览生成接口 ``` POST /api/v1/templates/{template_id}/generate-preview ``` **请求体**: ```json { "asset_library_id": "lib_xxx", "asset_ids": ["asset_1", "asset_2", ...], "title_ids": ["title_1", "title_2"], "voice_ids": ["voice_1", "voice_2"], "bgm_config": {}, "count": 3, "seed": 0 } ``` | 参数 | 类型 | 必填 | 默认 | 说明 | |------|------|------|------|------| | template_id | path | ✅ | - | 模板 ID | | asset_library_id | body | ✅ | - | 素材库 ID | | asset_ids | body | ✅ | - | 素材池(从中选子集/排序) | | title_ids | body | - | [] | 标题池(可选,不传则不用标题) | | voice_ids | body | - | [] | 配音池(可选) | | bgm_config | body | - | {} | BGM 配置 | | count | body | - | 3 | 生成几个预览版本(1~10) | | seed | body | - | 0 | 随机种子,0 表示随机 | **响应**: ```json { "preview_batch_id": "pb_xxx", "count": 3, "tasks": [ { "task_id": "gen_xxx_0", "variant_index": 0, "status": "processing" }, { "task_id": "gen_xxx_1", "variant_index": 1, "status": "processing" }, ... ] } ``` #### 4.3.2 预览批次查询接口 ``` GET /api/v1/preview-batches/{batch_id} ``` 返回批次内所有预览任务的状态、结果(已完成的带 video_url)。 **响应**: ```json { "preview_batch_id": "pb_xxx", "count": 3, "completed_count": 2, "tasks": [ { "task_id": "gen_xxx_0", "variant_index": 0, "status": "completed", "video_url": "https://oss.xxx/preview/xxx.mp4", "duration": 15.5, "thumbnail_url": "https://oss.xxx/preview/xxx.jpg" }, ... ] } ``` #### 4.3.3 预览转正式生成 ``` POST /api/v1/preview-batches/{batch_id}/tasks/{task_id}/promote ``` 将某个预览版本升级为正式生成(复用素材缓存,重新全分辨率渲染)。 --- ### 4.4 渲染参数降级 预览模式下自动调整以下参数: | 参数 | 正式生成 | 预览生成 | |------|---------|---------| | 分辨率 | 720p (1280x720) | 480p (854x480) | | 码率 | 4 Mbps | 1.5 Mbps | | 帧率 | 30 fps | 24 fps | | 时长 | 完整时长 | 前 15 秒(或第一段完整clip) | | 转场效果 | 完整转场 | 仅淡入淡出 | | 高级特效 | 全部启用 | 跳过粒子/光效等 | | 字幕 | 完整渲染 | 正常渲染 | | 配音 | 完整混音 | 正常混音 | | 输出质量 | high | medium | **实现位置**:`_render_video` 函数入口处,根据 `is_preview` 标记调整渲染配置。 --- ### 4.5 任务调度 - **并行执行**:N 个预览任务并行提交到 Celery,不排队等待 - **低优先级**:预览任务走独立队列(`preview_queue`),不抢占正式生成资源 - **超时控制**:预览任务超时时间 5 分钟(正式 30 分钟) - **自动清理**:预览视频 7 天后自动从 OSS 删除,任务记录标记为 archived --- ## 5. 前端对接要点 ### 5.1 交互流程 ``` 第2步选素材 → 第3步点击"生成预览" → 显示 loading + 进度 → 预览陆续完成,左侧列表逐张出现 → 用户点击左侧不同版本,右侧预览区切换 → 用户选中满意版本 → 点击"正式生成" ``` ### 5.2 需要对齐的接口 1. **预览创建**:`POST /templates/{id}/generate-preview` 2. **批次状态轮询**:`GET /preview-batches/{id}`(建议 2s 轮询,或走 SSE) 3. **预览转正式**:`POST /preview-batches/{id}/tasks/{task_id}/promote` ### 5.3 数据格式对齐 预览视频条目结构: ```json { "id": "gen_xxx", "variant_index": 0, "status": "completed", "video_url": "https://...", "duration": 15.5, "file_size": 2850000, "thumbnail_url": "https://...", "is_preview": true } ``` --- ## 6. 配额与计费 - 预览生成**不计入**用户配额 - 同一模板 + 同一素材池,每天最多生成 3 次多版本预览(防滥用) - 单个预览批次最多 10 个版本 --- ## 7. 实施步骤 ### Phase 1:单版本预览(MVP,2 天) 1. 数据模型 + 迁移(is_preview 字段) 2. API 层支持 is_preview 参数 3. 渲染分辨率降级(480p) 4. 不计入配额 5. 基础测试 ### Phase 2:多版本预览(3 天) 1. 变体引擎实现(素材随机选择 + 排序 + 去重) 2. preview_batch 批次管理 3. 批量创建 N 个预览任务 4. 批次查询接口 5. 前端联调 ### Phase 3:预览转正式 + 优化(2 天) 1. 预览转正式生成接口(promote) 2. 素材下载缓存复用 3. 独立预览队列(低优先级) 4. 自动清理机制 5. 完整测试 + 压测 --- ## 8. 风险与注意事项 | 风险 | 影响 | 应对 | |------|------|------| | 并发预览任务过多打满 worker | 正式生成被阻塞 | 独立预览队列 + 限流 | | 变体生成的视频差异不够大 | 用户觉得"都一样" | 优先素材子集+排序差异,保证视觉差异 | | 预览视频占用 OSS 存储 | 存储成本上升 | 7 天自动清理 + 低码率 | | N 个版本同时下载重复素材 | 带宽浪费 | 批次内共享一次下载(Phase 3 优化) | | 用户预期管理 | 以为预览就是最终效果 | 明确标注"预览版",说明分辨率差异 | --- ## 9. 开发量估算 | 阶段 | 后端 | 前端 | 合计 | |------|------|------|------| | Phase 1 单版本预览 | 2 天 | 1 天 | 3 天 | | Phase 2 多版本预览 | 3 天 | 2 天 | 5 天 | | Phase 3 转正式+优化 | 2 天 | 1 天 | 3 天 | | **总计** | **7 天** | **4 天** | **~7 天(并行)** | --- ## 10. 与 v1 方案的差异总结 1. **新增多版本能力**:从"生成1个预览"升级为"生成N个不重复预览" 2. **新增变体引擎**:负责素材选择/排序/配音/标题的随机化 3. **新增批次概念**:preview_batch 管理一组预览任务 4. **新增 promote 接口**:预览转正式生成 5. **独立队列**:预览不抢占正式生成资源 6. **开发量**:从 2-3 天增加到约 7 天(后端)