Files
ViGent2/Docs/DevLogs/Day21.md
Kevin Wong 1a291a03b8 更新
2026-02-08 10:46:08 +08:00

4.4 KiB
Raw Blame History

🐛 缺陷修复:视频生成与持久化回归 (Day 21)

概述

本日修复 Day 20 优化后引入的 3 个回归缺陷Remotion 渲染崩溃容错、首页作品选择持久化、发布页作品选择持久化。


已完成修复

BUG-1: Remotion 渲染进程崩溃导致标题/字幕丢失

  • 现象: 视频生成后没有标题和字幕,回退到纯 FFmpeg 合成。
  • 根因: Remotion Node.js 进程在渲染完成100%)后以 SIGABRT (code -6) 退出Python 端将其视为失败。
  • 修复: remotion_service.py 在进程非零退出时,先检查输出文件是否存在且大小合理(>1KB若存在则视为成功。
  • 文件: backend/app/services/remotion_service.py
if process.returncode != 0:
    output_file = Path(output_path)
    if output_file.exists() and output_file.stat().st_size > 1024:
        logger.warning(
            f"Remotion process exited with code {process.returncode}, "
            f"but output file exists ({output_file.stat().st_size} bytes). Treating as success."
        )
        return output_path
    raise RuntimeError(...)

BUG-2: 首页历史作品选择刷新后不保持

  • 现象: 用户选择某个历史作品后刷新页面,总是回到第一个视频。
  • 根因: fetchGeneratedVideos() 在初始加载时无条件自动选中第一个视频,覆盖了 useHomePersistence 的恢复值。
  • 修复: fetchGeneratedVideos 增加 preferVideoId 参数,仅在明确指定时才自动选中;新增 "__latest__" 哨兵值用于生成完成后选中最新。
  • 文件: frontend/src/features/home/model/useGeneratedVideos.ts, frontend/src/features/home/model/useHomeController.ts
// 任务完成 → 自动选中最新
useEffect(() => {
  if (prevIsGenerating.current && !isGenerating) {
    if (currentTask?.status === "completed") {
      void fetchGeneratedVideos("__latest__");
    } else {
      void fetchGeneratedVideos();
    }
  }
  prevIsGenerating.current = isGenerating;
}, [isGenerating, currentTask, fetchGeneratedVideos]);

BUG-3: 发布页作品选择刷新后不保持(根因:签名 URL 不稳定)

  • 现象: 发布管理页选择视频后刷新,选择丢失(无任何视频被选中)。
  • 根因: 后端 /api/videos/generated 返回的 path 是 Supabase 签名 URL每次请求都会变化。发布页用 path 作为选择标识存入 localStorage刷新后新的 path 与保存值永远不匹配。首页不受影响是因为使用稳定的 video.id
  • 修复: 发布页全面改用 id(稳定标识)替代 path(签名 URL进行选择、持久化和比较。
  • 文件:
    • frontend/src/shared/types/publish.tsPublishVideo 新增 id 字段
    • frontend/src/features/publish/model/usePublishController.tsselectedVideo 存储 id,发布时根据 id 查找 path
    • frontend/src/features/publish/ui/PublishPage.tsxkey/onClick/选中比较改用 v.id
    • frontend/src/features/home/model/useHomeController.ts — 预取缓存加入 id 字段
// 类型定义新增 id
export interface PublishVideo {
    id: string;    // 稳定标识符
    name: string;
    path: string;  // 签名 URL仅用于播放/发布)
}

// 发布时根据 id 查找 path
const video = videos.find(v => v.id === selectedVideo);
await api.post('/api/publish', { video_path: video.path, ... });

涉及文件汇总

文件 变更
backend/app/services/remotion_service.py Remotion 崩溃容错
frontend/src/features/home/model/useGeneratedVideos.ts 首页视频选择不自动覆盖
frontend/src/features/home/model/useHomeController.ts 任务完成监听 + 预取缓存加 id
frontend/src/shared/types/publish.ts PublishVideo 新增 id 字段
frontend/src/features/publish/model/usePublishController.ts 选择/持久化/发布改用 id
frontend/src/features/publish/ui/PublishPage.tsx UI 选择比较改用 id

关键教训

签名 URL 不可作为持久化标识。Supabase Storage 的签名 URL 包含时间戳和签名参数,每次请求都不同。任何需要跨请求/跨刷新保持的标识,必须使用后端返回的稳定 id 字段。

重启要求

pm2 restart vigent2-backend    # Remotion 容错
npm run build && pm2 restart vigent2-frontend  # 前端持久化修复