feat(v2): add reconnecting FFmpeg stream source

This commit is contained in:
ila
2026-07-22 21:15:25 +08:00
parent 70d9c5c73e
commit 3edda4fb62
5 changed files with 388 additions and 9 deletions
+1 -1
View File
@@ -24,7 +24,7 @@
| 语言 | Go | 已定 | 面向长时间 RTSP 运行、并发控制和单一交付物。 |
| 模型工件 | 固定输入尺寸的 ONNX Pose 模型 | 已定 | Go 不直接加载 `.pt`;模型由已验收 V1 权重导出并记录哈希。 |
| 推理运行时 | `github.com/yalue/onnxruntime_go` v1.31.0 + ONNX Runtime CPU DLL | Spike 已验证 | Windows 上以显式 DLL 路径加载锁定的 1×3×640×640 Pose ONNX,已完成一次真实录像首帧推理;该包装器的 C API 为 26,V2 构建必须启用 CGO/MinGW,并在发布包锁定匹配 DLL 的来源与 SHA-256。 |
| 视频输入 | 受控的 `ffmpeg.exe` 子进程输出 `bgr24` 原始帧 | 回放已验证 | Go 回归命令已完整读取 317 帧本地录像;避免未配置的 GoCV/OpenCV 开发绑定。T-304 必须随应用锁定 FFmpeg/FFprobe 的版本、哈希与 RTSP 重连行为。 |
| 视频输入 | 受控的 `ffmpeg.exe` 子进程输出 `bgr24` 原始帧 | 回放已验证;RTSP 源单元测试已覆盖 | Go 回归命令已完整读取 317 帧本地录像;`internal/source` 已实现 FFprobe 元数据探测、FFmpeg 解码、有界重连、取消与最新帧投递,且错误状态不含 RTSP URL。避免未配置的 GoCV/OpenCV 开发绑定。T-304 仍须随应用锁定 FFmpeg/FFprobe 的版本、哈希,并在现场验证真实流重连。 |
| 图像预处理与 Pose 解析 | Go 实现的 BGR→RGB、CHW、640 letterbox、NMS、17 点及坐标还原 | 合成契约与本机漏检回放已验证 | 采用 Ultralytics 的 114 补边、双线性缩放后转 uint8 的语义;Go 首帧输出两个人,与 V1 对应结果的 box 坐标差在已记录的 6 像素容差内。`demo/1.mp4` 是真实摔倒但在现有 V1 配置下漏检,不能称为“无报警反例”;仍需经同意、符合固定俯视大厅/走廊边界的正例录像完成事件级确认。 |
| 演示 UI | `github.com/lxn/walk`(Windows 原生控件) | Spike 已验证 | 双 Tab 骨架可在 `CGO_ENABLED=0` 编译,避免 Fyne/OpenGL 首次编译的高复杂度;正式版仍须实现浅灰蓝底、白色卡片,红色仅表示确认摔倒。 |
| 测试 | `go test ./...` + V1 回归录像 | 已定 | V2 行为必须与 V1 基线对照。 |
+1
View File
@@ -54,6 +54,7 @@ V2 对应模块的当前落实与 T-304 目标如下:
| --- | --- | --- | --- |
| 回放解码器 | `v2/cmd/regression` | 用受控 FFmpeg 顺序读取 BGR 帧,供本机录像回归 | RTSP 重连、UI 绘制 |
| 运行配置 | `v2/internal/config` | 校验公开 JSON、仅从环境变量解析 RTSP URL、生成非敏感配置版本 | 保存或显示 URL、账号、密码 |
| 实时视频源 | `v2/internal/source` | 用 FFprobe 获取尺寸/FPS,以 FFmpeg 输出 BGR 帧;有界重连、取消、来源状态和单槽最新帧投递 | ONNX、事件判定、UI 绘制;错误状态不得含 URL |
| ONNX Pose | `v2/internal/pose` | 114 letterbox、RGB/CHW、NMS、关键点及坐标还原 | 人员 ID、摔倒结论 |
| 事件引擎 | `v2/internal/fall` | 复现 V1 的跟踪、证据、四态状态机和 `FallEvent` | 视频解码、声音、文件 |
| Windows UI | `v2/internal/ui` | Walk 顶部“监控/设置”Tab、渲染最新帧和已计算状态 | 直接读 RTSP、执行 ONNX 或事件规则 |
@@ -98,7 +98,7 @@ git commit -m "feat(v2): add safe runtime configuration"
- Create: `v2/internal/source/stream_test.go`
- Modify: `docs/04-architecture.md`
- [ ] **Step 1: Write deterministic source tests before subprocess integration**
- [x] **Step 1: Write deterministic source tests before subprocess integration**
```go
func TestLatestFrameDropsStaleFrame(t *testing.T) {
@@ -114,12 +114,12 @@ func TestBackoffIsBoundedAndCancellationStopsRetry(t *testing.T) {
}
```
- [ ] **Step 2: Verify the tests fail**
- [x] **Step 2: Verify the tests fail**
Run: `Set-Location v2; go test ./internal/source -run 'Test(Latest|Backoff)' -v`
Expected: FAIL because `internal/source` does not exist.
- [ ] **Step 3: Implement probe and worker ownership**
- [x] **Step 3: Implement probe and worker ownership**
```go
type Status string
@@ -136,14 +136,12 @@ func Start(ctx context.Context, cfg Config, commands CommandFactory) (Stream, er
Use `-rtsp_transport`, `-rw_timeout`, low-latency FFmpeg input flags when configured, and `-f rawvideo -pix_fmt bgr24 -` output. Capture stderr internally but publish only a generic status code/message such as `视频流已断开,正在重连`; it must never contain command arguments or the RTSP URL. Cancellation kills the current process and closes channels exactly once.
- [ ] **Step 4: Run source tests and a safe invalid-source smoke**
- [x] **Step 4: Run source tests**
Run: `Set-Location v2; go test ./internal/source -v`
Expected: PASS.
Run: `go run ./cmd/silver-pose --config config.example.json`
Expected: clean missing-environment configuration error without an RTSP address.
Expected: PASS. The production command's missing-environment smoke is performed in Task 6 after `cmd/silver-pose` exists.
- [ ] **Step 5: Commit the source slice**
- [x] **Step 5: Commit the source slice**
```powershell
git add v2/internal/source docs/04-architecture.md