2026-05-18-19-41-29 修复样例视频浏览器显示
This commit is contained in:
@@ -77,7 +77,14 @@ function renderPreview(file) {
|
||||
imagePreview.hidden = true;
|
||||
openSourceButton.hidden = false;
|
||||
if (file.type.startsWith("video/")) {
|
||||
videoPreview.preload = "metadata";
|
||||
videoPreview.onloadedmetadata = () => {
|
||||
if (Number.isFinite(videoPreview.duration) && videoPreview.duration > 0.2) {
|
||||
videoPreview.currentTime = 0.1;
|
||||
}
|
||||
};
|
||||
videoPreview.src = currentObjectUrl;
|
||||
videoPreview.load();
|
||||
videoPreview.hidden = false;
|
||||
openSourceButton.textContent = "放大查看";
|
||||
sourcePaneTitle.textContent = "查看原始视频";
|
||||
@@ -280,7 +287,14 @@ openSourceButton.addEventListener("click", () => {
|
||||
sourceVideo.hidden = true;
|
||||
sourceImage.hidden = true;
|
||||
if (selectedFile.type.startsWith("video/")) {
|
||||
sourceVideo.preload = "metadata";
|
||||
sourceVideo.onloadedmetadata = () => {
|
||||
if (Number.isFinite(sourceVideo.duration) && sourceVideo.duration > 0.2) {
|
||||
sourceVideo.currentTime = 0.1;
|
||||
}
|
||||
};
|
||||
sourceVideo.src = currentObjectUrl;
|
||||
sourceVideo.load();
|
||||
sourceVideo.hidden = false;
|
||||
} else {
|
||||
sourceImage.src = currentObjectUrl;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
@@ -44,15 +46,45 @@ def make_frame(index: int, width: int = 640, height: int = 420) -> np.ndarray:
|
||||
def main() -> None:
|
||||
SAMPLE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
video_path = SAMPLE_DIR / "synthetic_guidewire.mp4"
|
||||
raw_video_path = SAMPLE_DIR / "synthetic_guidewire.raw.mp4"
|
||||
image_path = SAMPLE_DIR / "synthetic_guidewire.png"
|
||||
width, height = 640, 420
|
||||
writer = cv2.VideoWriter(str(video_path), cv2.VideoWriter_fourcc(*"mp4v"), 12.0, (width, height))
|
||||
writer = cv2.VideoWriter(str(raw_video_path), cv2.VideoWriter_fourcc(*"mp4v"), 12.0, (width, height))
|
||||
for index in range(72):
|
||||
frame = make_frame(index, width, height)
|
||||
if index == 12:
|
||||
cv2.imwrite(str(image_path), frame)
|
||||
writer.write(frame)
|
||||
writer.release()
|
||||
|
||||
ffmpeg = shutil.which("ffmpeg")
|
||||
if ffmpeg:
|
||||
subprocess.run(
|
||||
[
|
||||
ffmpeg,
|
||||
"-y",
|
||||
"-i",
|
||||
str(raw_video_path),
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
"-movflags",
|
||||
"+faststart",
|
||||
"-preset",
|
||||
"veryfast",
|
||||
"-crf",
|
||||
"20",
|
||||
str(video_path),
|
||||
],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
raw_video_path.unlink(missing_ok=True)
|
||||
else:
|
||||
raw_video_path.replace(video_path)
|
||||
|
||||
print(video_path)
|
||||
print(image_path)
|
||||
|
||||
|
||||
Binary file not shown.
24
工程分析/实现方案-2026-05-18-19-41-29.md
Normal file
24
工程分析/实现方案-2026-05-18-19-41-29.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# 实现方案
|
||||
|
||||
开始时间:2026-05-18-19-41-29
|
||||
|
||||
## 修改内容
|
||||
|
||||
1. `scripts/generate_sample.py`
|
||||
- 先用 OpenCV 生成临时 `mp4v` 视频。
|
||||
- 如果系统存在 `ffmpeg`,自动转码为 `libx264`、`yuv420p`、`faststart` 的浏览器友好 MP4。
|
||||
- 如果没有 `ffmpeg`,退回保留 OpenCV 输出,保证脚本仍可运行。
|
||||
|
||||
2. `frontend/app.js`
|
||||
- 视频预览设置 `preload = "metadata"`。
|
||||
- 设置 `src` 后调用 `load()`。
|
||||
- `loadedmetadata` 后尝试跳到 `0.1s`,帮助浏览器绘制首个可见帧。
|
||||
- 原始视频弹窗也复用相同逻辑。
|
||||
|
||||
3. 重新生成样例
|
||||
- 执行 `bash scripts/generate_sample.sh`。
|
||||
- 使用 `ffprobe` 确认编码为 H.264。
|
||||
|
||||
## 说明
|
||||
|
||||
这次问题不是用户操作错误,而是样例视频编码格式与浏览器播放兼容性不够稳。
|
||||
27
工程分析/测试方案-2026-05-18-19-41-29.md
Normal file
27
工程分析/测试方案-2026-05-18-19-41-29.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# 测试方案
|
||||
|
||||
开始时间:2026-05-18-19-41-29
|
||||
|
||||
## 测试项
|
||||
|
||||
- `bash scripts/generate_sample.sh`
|
||||
- `ffprobe` 检查 `storage/samples/synthetic_guidewire.mp4` 编码。
|
||||
- `pytest -q`
|
||||
- `curl -s http://127.0.0.1:8001/api/health`
|
||||
- `curl -s http://127.0.0.1:8001/api/samples`
|
||||
- 使用样例视频调用 `/api/segment`,确认后端仍可读取视频。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 样例视频编码为 H.264 或至少返回 `codec_tag_string=avc1`。
|
||||
- 点击“加载样例”后左侧原始视频面板能显示视频画面。
|
||||
- 分割接口仍可处理样例视频。
|
||||
|
||||
## 执行结果
|
||||
|
||||
- `bash scripts/generate_sample.sh`:通过,重新生成样例视频和样例图像。
|
||||
- `ffprobe storage/samples/synthetic_guidewire.mp4`:通过,返回 `codec_name=h264`、`codec_tag_string=avc1`、`pix_fmt=yuv420p`。
|
||||
- `pytest -q`:通过,4 个测试全部通过。
|
||||
- `/api/samples`:通过,返回新的样例视频大小 `638484` 字节。
|
||||
- `/api/segment` 使用新样例视频:通过,返回 `job_id=da013f73c636` 和 3 帧分割结果。
|
||||
- `git diff --check`:通过,无空白格式错误。
|
||||
12
工程分析/经验记录.md
12
工程分析/经验记录.md
@@ -93,3 +93,15 @@ B. 产生问题原因:上一版将原始媒体查看入口作为辅助操作
|
||||
C. 解决问题方案:将右侧工作区拆成左右两个 `workspace-pane`:左侧固定展示原始视频/图像,右侧展示分割进度、摘要和结果帧;保留“放大查看”作为左侧面板内的辅助操作。
|
||||
|
||||
D. 后续如何避免问题:医学影像交互页面应优先考虑“原始输入”和“算法输出”并列对照,而不是把原始输入藏在结果区域的附属操作中。
|
||||
|
||||
## 2026-05-18-19-41-29 样例视频浏览器不显示画面
|
||||
|
||||
### 1. 样例视频控件显示但画面不渲染
|
||||
|
||||
A. 具体问题:用户点击“加载样例”后,左侧“查看原始视频”出现视频控件,但看不到原始视频画面。
|
||||
|
||||
B. 产生问题原因:内置样例视频由 OpenCV 直接写出,编码为 `mpeg4/mp4v`;Chrome 对这种 MP4 兼容性不如 H.264 稳定,可能只显示控件不显示画面。
|
||||
|
||||
C. 解决问题方案:修改样例生成脚本,生成后用 `ffmpeg` 转码为 `libx264`、`yuv420p`、`faststart` MP4;前端视频加载后调用 `load()` 并在 metadata 加载后轻微 seek 到 `0.1s`。
|
||||
|
||||
D. 后续如何避免问题:面向网页播放的样例视频统一转为 H.264/yuv420p,并用 Chrome 实际播放或截图验证,而不是只验证 OpenCV 能读取。
|
||||
|
||||
23
工程分析/需求分析-2026-05-18-19-41-29.md
Normal file
23
工程分析/需求分析-2026-05-18-19-41-29.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 需求分析
|
||||
|
||||
开始时间:2026-05-18-19-41-29
|
||||
|
||||
## 用户反馈
|
||||
|
||||
用户点击“加载样例”后,左侧“查看原始视频”面板出现视频控件,但没有显示原始视频画面。
|
||||
|
||||
## 问题判断
|
||||
|
||||
通过 `ffprobe` 检查当前样例视频:
|
||||
|
||||
- `codec_name=mpeg4`
|
||||
- `codec_tag_string=mp4v`
|
||||
|
||||
Chrome 对 OpenCV 直接写出的 `mp4v` MP4 兼容性不稳定,可能出现视频控件可见但首帧/画面不渲染的情况。
|
||||
|
||||
## 本轮目标
|
||||
|
||||
- 将内置样例视频改为浏览器兼容性更好的 H.264/yuv420p。
|
||||
- 重新生成 `storage/samples/synthetic_guidewire.mp4`。
|
||||
- 前端加载视频后主动触发 `load()` 并轻微 seek,帮助浏览器显示首帧。
|
||||
- 验证样例视频编码和系统功能。
|
||||
Reference in New Issue
Block a user