Files
Pre_Seg_Server/工程分析/实现方案-20260429_232813.md

2.6 KiB
Raw Permalink Blame History

实现方案 — 视频帧显示链路修复

后端

1. backend/schemas.py — ProjectOut 增加 frame_count

class ProjectOut(ProjectBase):
    id: int
    created_at: datetime
    updated_at: datetime
    frame_count: int = 0

2. backend/routers/projects.py — 三处修改

  • list_projects: 为每个项目计算 frame_count = len(p.frames)(利用 ORM relationship
  • list_frames: 返回前将每个 frame.image_url 替换为 get_presigned_url(frame.image_url, expires=3600)
  • get_project: 同样添加 frame_count

3. backend/main.py — lifespan 默认视频种子

启动时异步后台任务:

  • 若数据库无项目且 Data_MyVideo_1.mp4 存在
  • 创建 Project → 上传 MinIO → 调用 FFmpeg 解析帧 → 上传帧到 MinIO → 注册 Frame 记录 → 更新 status="ready"
  • 使用 asyncio.to_thread() 避免阻塞事件循环

4. backend/routers/media.py — upload 自动创建项目

project_id 为空时:

  • 以文件名创建 Project
  • 将上传文件关联到该 project
  • 返回中增加 project_id

前端

5. src/lib/api.ts — 新增两个 API

export async function getProjectFrames(projectId: string): Promise<Array<{ id: number; project_id: number; frame_index: number; image_url: string; width: number | null; height: number | null }>>
export async function parseMedia(projectId: string): Promise<{ project_id: number; frames_extracted: number; status: string; message: string }>

6. src/components/VideoWorkspace.tsx — 帧加载中枢

  • 读取 currentProjectframes
  • useEffect 监听 currentProject.id
    • 调用 getProjectFrames
    • 映射后端字段到前端 Frame[] 结构写入 store
    • 若帧数为 0 且项目有 video_path自动调用 parseMedia 触发解析,解析完成后重新获取
  • 将当前帧 URL 通过 prop 传给 CanvasArea
  • 将帧列表和索引控制传给 FrameTimeline
  • 标题显示 currentProject?.name

7. src/components/CanvasArea.tsx — 真实帧渲染

  • 新增 frameUrl prop
  • const [image] = useImage(frameUrl || '')
  • runInference 使用 frameUrl 替代硬编码 URL

8. src/components/FrameTimeline.tsx — 真实帧导航

  • 从 store 读取 framescurrentFrameIndex
  • totalFrames = frames.length
  • 每个帧方块显示为 <img> 缩略图
  • 点击调用 setCurrentFrame(index)
  • 进度条范围 1..frames.length

9. src/components/ProjectLibrary.tsx — 完整上传链路

上传流程改为:

  1. createProject({ name: file.name })
  2. uploadMedia(file, projectId)
  3. parseMedia(projectId)
  4. getProjects() 刷新列表