20260429_232813-fix: video frame display pipeline — default project seed, presigned URLs, Canvas/FrameTimeline real frames, upload-parse flow

This commit is contained in:
2026-04-29 23:42:18 +08:00
parent 51f1a60216
commit 35d6e1503c
16 changed files with 454 additions and 56 deletions

View File

@@ -5,6 +5,39 @@
---
## 2026-04-29-23-28-13 — 视频帧显示链路全修复
### A. 具体问题
1. 项目库中没有默认视频 `Data_MyVideo_1.mp4`
2. 分割工作区点击视频后画面一片黑(无影像)
3. 导入新视频后进入工作区同样看不到视频帧
### B. 产生原因
1. 后端 lifespan 没有任何自动扫描/注册本地视频的逻辑;`server.ts` 的硬编码项目对前端不可见
2. `CanvasArea.tsx` 硬编码了一张 Unsplash 外链,没有从 Zustand store 读取帧数据;进入工作区时不调用帧列表 API
3. 上传流程不完整:未先创建项目再带 project_id 上传,上传后未触发 `/api/media/parse` 帧提取;后端 `/frames` 返回的是 MinIO 对象名而非可访问的 presigned URLMinIO presigned URL 的 host 为 `localhost:9000`,浏览器端无法访问
4. 系统磁盘空间24GB紧张MinIO 在提取大量高清 PNG 帧时触发 `XMinioStorageFull`,导致帧上传失败
### C. 解决方案
1. **后端默认视频种子**`main.py` lifespan 中启动后台线程,自动检测 `Data_MyVideo_1.mp4`,创建 Project → 上传 MinIO → 调用 FFmpeg 解析帧 → 注册 Frame 记录
2. **后端帧 URL 修复**`projects.py``list_frames` 在返回前为每个 `frame.image_url` 调用 `get_presigned_url()` 生成带签名的可访问 URL
3. **后端 presigned URL host 修复**`.env``MINIO_ENDPOINT``localhost:9000` 改为 `192.168.3.11:9000`,确保浏览器端可访问
4. **后端 ProjectOut 增强**`schemas.py` 添加 `frame_count``projects.py` 在查询时计算 `len(p.frames)`,供前端显示帧数
5. **后端 upload 自动创建项目**`media.py``upload_media` 在不传 `project_id` 时自动以文件名创建 Project 并关联视频
6. **前端帧加载中枢**`VideoWorkspace.tsx``currentProject` 变化时调用 `getProjectFrames`,若帧数为 0 则自动触发 `parseMedia`,获取后映射写入 Zustand store
7. **前端 Canvas 真实渲染**`CanvasArea.tsx` 接收 `frameUrl` prop使用 `useImage(frameUrl)` 加载真实帧AI 推理也使用当前帧 URL
8. **前端时间轴真实帧**`FrameTimeline.tsx` 从 store 读取 `frames``currentFrameIndex`,渲染真实帧缩略图 `<img>`,点击切换当前帧
9. **前端上传链路完善**`ProjectLibrary.tsx` 上传流程改为:创建项目 → `uploadMedia(file, projectId)``parseMedia(projectId)` → 刷新列表
10. **磁盘空间优化**:将 `frame_parser.py` 的 FFmpeg 输出从 PNG (1920px, ~3MB/张) 改为 JPEG (640px, ~30KB/张),并限制默认视频只提取 100 帧,避免 MinIO 存储溢出
### D. 后续如何避免问题
1. **MinIO endpoint 必须使用服务器 IP**:任何生成外部可访问 URL 的服务MinIO presigned、后端 baseURL、WebSocket都必须使用服务器 LAN IP禁止 localhost
2. **大文件/视频处理必须考虑磁盘预算**:提取帧前估算总大小(帧数 × 单帧大小),必要时降低分辨率、改格式为 JPEG、限制 max_frames
3. **前后端数据字段必须显式映射**:后端 snake_case 与前端 camelCase 不一致时API 层必须做转换,不能依赖隐式兼容
4. **上传-解析-显示链路必须闭环测试**:任何涉及文件上传的功能,测试用例必须覆盖:上传 → 后端存储 → 解析 → 前端获取 → 前端渲染 的全流程
---
## 2026-04-29-23-15-26 — 上传/WS/项目库三 Bug 联修
### A. 具体问题