From 72c96828d5f7fa0501fa55825d1435b7473012d7 Mon Sep 17 00:00:00 2001 From: admin <572701190@qq.com> Date: Mon, 18 May 2026 19:52:24 +0800 Subject: [PATCH] =?UTF-8?q?2026-05-18-19-46-56=20=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E6=A0=B7=E4=BE=8B=E8=A7=86=E9=A2=91=E7=BC=93?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/main.py | 4 +++- frontend/app.js | 4 +++- 工程分析/实现方案-2026-05-18-19-46-56.md | 22 +++++++++++++++++ 工程分析/测试方案-2026-05-18-19-46-56.md | 29 +++++++++++++++++++++++ 工程分析/经验记录.md | 12 ++++++++++ 工程分析/需求分析-2026-05-18-19-46-56.md | 30 ++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 工程分析/实现方案-2026-05-18-19-46-56.md create mode 100644 工程分析/测试方案-2026-05-18-19-46-56.md create mode 100644 工程分析/需求分析-2026-05-18-19-46-56.md diff --git a/backend/main.py b/backend/main.py index 402420d..ae9d61a 100644 --- a/backend/main.py +++ b/backend/main.py @@ -59,12 +59,14 @@ def samples() -> dict[str, Any]: for path in sorted(SAMPLE_DIR.glob("*")): suffix = path.suffix.lower() if suffix in IMAGE_SUFFIXES | VIDEO_SUFFIXES: + version = str(path.stat().st_mtime_ns) items.append( { "name": path.name, - "url": _public(path), + "url": f"{_public(path)}?v={version}", "kind": "image" if suffix in IMAGE_SUFFIXES else "video", "size": path.stat().st_size, + "version": version, } ) return {"samples": items} diff --git a/frontend/app.js b/frontend/app.js index 6c67b1e..478cc7c 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -211,7 +211,9 @@ async function loadSample() { const data = await response.json(); const sample = data.samples.find((item) => item.kind === "video") || data.samples[0]; if (!sample) throw new Error("未找到样例文件"); - const blobResponse = await fetch(sample.url); + const separator = sample.url.includes("?") ? "&" : "?"; + const sampleUrl = `${sample.url}${separator}t=${Date.now()}`; + const blobResponse = await fetch(sampleUrl, { cache: "reload" }); if (!blobResponse.ok) throw new Error("样例文件下载失败"); const blob = await blobResponse.blob(); const file = new File([blob], sample.name, { type: sample.kind === "video" ? "video/mp4" : "image/png" }); diff --git a/工程分析/实现方案-2026-05-18-19-46-56.md b/工程分析/实现方案-2026-05-18-19-46-56.md new file mode 100644 index 0000000..7f2a789 --- /dev/null +++ b/工程分析/实现方案-2026-05-18-19-46-56.md @@ -0,0 +1,22 @@ +# 实现方案 + +开始时间:2026-05-18-19-46-56 + +## 修改内容 + +1. 后端 `/api/samples` + - 返回 `url` 时追加 `?v=`。 + - 增加 `version` 字段,便于前端或调试确认样例版本。 + +2. 前端 `loadSample` + - 从 `/api/samples` 读取版本化 URL。 + - 再追加 `t=`,确保本次点击不会复用旧浏览器缓存。 + - `fetch` 使用 `{ cache: "reload" }`。 + +3. 测试与验证 + - Chrome DevTools Protocol 自动点击“加载样例”并截图。 + - 检查视频元素 `readyState`、`videoWidth` 和 `videoHeight`。 + +## 说明 + +这次不是布局问题,也不是后端接口问题;根因更偏向浏览器缓存旧样例资源。版本化 URL 是面向 Web 端静态媒体更新的稳妥处理。 diff --git a/工程分析/测试方案-2026-05-18-19-46-56.md b/工程分析/测试方案-2026-05-18-19-46-56.md new file mode 100644 index 0000000..b7fbb0a --- /dev/null +++ b/工程分析/测试方案-2026-05-18-19-46-56.md @@ -0,0 +1,29 @@ +# 测试方案 + +开始时间:2026-05-18-19-46-56 + +## 测试项 + +- `curl -s http://127.0.0.1:8001/api/samples`,确认样例 URL 带版本参数。 +- Chrome DevTools Protocol 自动点击“加载样例”。 +- 检查视频元素状态:`readyState`、`error`、`videoWidth`、`videoHeight`。 +- 截图确认画面可见。 +- `pytest -q`。 +- 使用样例视频调用 `/api/segment`。 + +## 验收标准 + +- 用户点击“加载样例”后不会再拿到旧缓存视频。 +- 左侧原始视频面板可见真实画面。 +- 分割流程不受影响。 + +## 执行结果 + +- `/api/samples`:通过,样例 URL 已带 `?v=` 版本参数。 +- Chrome DevTools Protocol 自动点击“加载样例”:通过。 +- 视频元素状态:`readyState=4`、`error=null`、`videoWidth=640`、`videoHeight=420`、`currentTime=0.1`。 +- 点击后截图:`/tmp/isiseg_clicked_sample_after_cachefix.png`,截图中可见样例视频画面。 +- `pytest -q`:通过,4 个测试全部通过。 +- `ffprobe`:通过,样例视频为 `h264 / avc1 / yuv420p`。 +- `/api/segment` 使用样例视频:通过,返回 `job_id=3991537b6102` 和 3 帧结果。 +- `git diff --check`:通过,无空白格式错误。 diff --git a/工程分析/经验记录.md b/工程分析/经验记录.md index 871a714..f9f5053 100644 --- a/工程分析/经验记录.md +++ b/工程分析/经验记录.md @@ -105,3 +105,15 @@ B. 产生问题原因:内置样例视频由 OpenCV 直接写出,编码为 `m C. 解决问题方案:修改样例生成脚本,生成后用 `ffmpeg` 转码为 `libx264`、`yuv420p`、`faststart` MP4;前端视频加载后调用 `load()` 并在 metadata 加载后轻微 seek 到 `0.1s`。 D. 后续如何避免问题:面向网页播放的样例视频统一转为 H.264/yuv420p,并用 Chrome 实际播放或截图验证,而不是只验证 OpenCV 能读取。 + +## 2026-05-18-19-46-56 样例视频旧缓存处理 + +### 1. 修复编码后用户仍看到黑色视频 + +A. 具体问题:样例视频已转为 H.264 后,用户点击“加载样例”仍然反馈左侧原始视频没有画面。 + +B. 产生问题原因:实测 Chrome 自动点击流程可以看到画面,视频元素 `readyState=4` 且 `videoWidth/videoHeight` 正常;用户端仍异常更可能是浏览器继续使用旧 `mp4v` 样例缓存。 + +C. 解决问题方案:后端 `/api/samples` 返回带 `mtime_ns` 的版本化 URL;前端加载样例时追加时间戳,并使用 `fetch(..., { cache: "reload" })` 强制绕过旧缓存。 + +D. 后续如何避免问题:静态样例、模型文件、前端资源发生兼容性修复时,URL 必须版本化,避免用户浏览器继续使用旧缓存。 diff --git a/工程分析/需求分析-2026-05-18-19-46-56.md b/工程分析/需求分析-2026-05-18-19-46-56.md new file mode 100644 index 0000000..787aef7 --- /dev/null +++ b/工程分析/需求分析-2026-05-18-19-46-56.md @@ -0,0 +1,30 @@ +# 需求分析 + +开始时间:2026-05-18-19-46-56 + +## 用户反馈 + +用户访问 `http://192.168.3.11:8001/` 后点击“加载样例”,左侧“查看原始视频”仍然看不到画面,希望我们自己实测并解决。 + +## 实测结果 + +使用 Chrome DevTools Protocol 自动打开页面、点击“加载样例”后,视频元素状态如下: + +- `readyState=4` +- `error=null` +- `videoWidth=640` +- `videoHeight=420` +- `currentTime=0.1` + +截图 `/tmp/isiseg_clicked_sample.png` 中可以看到样例视频画面。 + +## 问题判断 + +服务端样例视频已修为 H.264,但用户浏览器仍可能命中过去的旧 `mp4v` 样例缓存。需要让样例资源 URL 版本化,并让前端加载样例时强制绕过缓存。 + +## 本轮目标 + +- `/api/samples` 返回带版本参数的样例 URL。 +- 前端加载样例时追加时间戳并设置 `cache: "reload"`。 +- 保留 H.264 样例视频。 +- 重新验证点击样例后的真实浏览器显示状态。