feat(#1677): 批量预览改纯前端Canvas实时预览 + 固定6步流程 + 第5步独立渲染进度 #1711
Reference in New Issue
Block a user
Delete Branch "feat/1677-canvas-batch-preview"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
PR #1704 的批量预览错误地调后端
POST /generation/preview?preview_count=N真渲染,导致预览卡死、429、容器重启。预览不需要渲染——本次按实测反馈修正。改动
1. 固定 6 步流程(单视频与批量完全一致)
1 选择模板(下一步弹数量弹窗)→ 2 选择素材 → 3 选择配音 → 4 选择标题 → 5 确认生成 → 6 选择封面
2. 第4步:纯前端 Canvas 实时预览(不调任何后端渲染接口)
FrontendPreviewPlayer(与旧版一致,零回归)CanvasPreviewGrid),新增variantSeed:mulberry32 可复现随机,素材轮换+交换、片段起始点偏移,N 个变体画面有可见差异;seed=0 走旧逻辑3. 第4步右侧:批量标题补 AI / 标题库
4. 第4步底部:「✨ 确认生成视频 / 确认生成 N 个视频」
5. 第5步「确认生成」:正式渲染实时进度
BatchGenerationGrid:每任务独立进度/成片播放/失败原因+「重试此视频」POST /tasks/{id}/retry后重新轮询;重试成功自动聚合进成片列表6. 清理
useBatchPreview、ServerPreviewGrid及 preview 渲染接口的所有前端调用(后端接口保留不删)验收
Closes #1677
- 预览纯前端化:N 个 FrontendPreviewPlayer 网格(CanvasPreviewGrid),variantSeed 让素材排布/起始点不同、画面有差异;不调任何后端渲染接口,秒开不占 worker; seed=0 走旧逻辑保证 N=1 零回归 - 固定 6 步(单视频与批量一致):模板(弹数量) → 素材 → 配音 → 标题 → 确认生成 → 封面 - 第4步右侧批量标题:N 个独立输入框(AutoComplete 接标题库)+ AI 一键生成 N 个标题 (本地模板池同源)+ 主题词补填空标题;标题样式全局共用 - 第4步底部「✨ 确认生成 N 个视频」:按 PR#1701 契约提交 count + titles[]/voice_library_ids[]/cover_urls[],成功后跳第5步 - 第5步「确认生成」:正式渲染实时进度,批量逐任务独立状态(BatchGenerationGrid, 部分失败不阻塞、失败卡片单独「重试此视频」走 POST /tasks/{id}/retry), 全部有终态后可进封面;单视频进度/失败/成功卡 + 右侧成片播放器 - 删除 useBatchPreview、ServerPreviewGrid 及 preview 渲染接口的所有前端调用 (后端接口保留);E2E 适配回 6 步断言🚀 预览环境已部署
CI全绿,自动审批通过。
CI全绿,自动审批通过。
【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
handleConfirmGenerate函数中,单视频模式的标题校验逻辑为!titleSettings.aiAutoSelect && !titleSettings.title?.trim()。这意味着如果用户开启了“AI 自动选择标题”(aiAutoSelect为 true),代码会跳过标题非空校验。如果此时 AI 标题尚未生成完成(title为空字符串),用户点击确认将导致提交空标题给后端,生成无标题的视频或导致后端报错。if (!titleSettings.title?.trim()) { message.warning("请先选择或输入标题"); return; }。💡 改进建议(不阻塞合并)
[apps/web/src/pages/generate/GeneratePage.tsx: 143] TTS 预览依赖项可能导致不必要的请求
useEffect中,依赖数组包含了整个previewTitles数组。在批量模式下,实际只使用了previewTitles[0]。当用户修改第 2、3 个视频的标题时,previewTitles引用变化会导致该 effect 重新执行,触发不必要的previewTtsAPI 请求。建议提取previewTitles[0]或使用 useMemo 优化依赖项。[apps/web/src/pages/generate/components/BatchGenerationGrid.tsx: 34] 数组排序的健壮性
tasks.sort((a, b) => a.variantIndex - b.variantIndex)假设variantIndex始终存在且为数字。如果后端数据异常导致variantIndex为undefined,计算结果为NaN,可能导致排序不稳定或报错。建议增加默认值处理:(a.variantIndex || 0) - (b.variantIndex || 0)。[apps/web/src/pages/generate/components/CanvasPreviewGrid.tsx: 60] 批量预览性能风险
count渲染对应数量的FrontendPreviewPlayer组件(包含<canvas>和<video>)。如果count数值较大(例如超过 20-50),浏览器可能因同时渲染过多媒体上下文而卡顿或崩溃。虽然PreviewCountModal可能有限制,但建议在CanvasPreviewGrid内部增加硬编码上限保护(如Math.min(count, 20)),或确保上游输入有严格校验。✅ 良好实践
BatchGenerationGrid对每个生成任务进行独立的进度和错误处理展示,用户体验更加清晰。✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能
🤖 由 AI 代码审查机器人自动生成 | 2026-09-05 04:29:09 | 模型:
🗑️ 预览环境已清理
PR #1711 已关闭或合并,对应的预览环境已被清理。