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

67 lines
2.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实现方案 — 视频帧显示链路修复
## 后端
### 1. `backend/schemas.py` — ProjectOut 增加 frame_count
```python
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
```ts
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` — 帧加载中枢
- 读取 `currentProject``frames`
- `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 读取 `frames``currentFrameIndex`
- `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()` 刷新列表