103 lines
7.2 KiB
Markdown
103 lines
7.2 KiB
Markdown
# Sense 单实机与五路混合源集成记录
|
||||
|
|
|
|||
|
|
> 执行日期:2026-08-07
|
|||
|
|
>
|
|||
|
|
> 结论:PASS(M1 实验室集成 smoke)
|
|||
|
|
|
|||
|
|
## 1. 验收范围与结论
|
|||
|
|
|
|||
|
|
本轮使用 T-001 已批准的 1 台真实 HIKVISION `DS-2CD3321FD-IW1-T`(硬件 `0x0`、固件 `V5.5.61 build 180929`)和 4 个可独立启停的 FFmpeg 合成 RTSP publisher,完成 5 路期望态、MediaMTX path、运行态探活和自动恢复闭环。
|
|||
|
|
|
|||
|
|
正式观察持续 `1806.6` 秒,共读取 `180` 个脱敏收敛快照;`maximum_unconverged = 0`、`final_unconverged = 0`。真实摄像头网络路径、单个合成 publisher、Sense 进程和 MediaMTX 进程四类恢复均通过,无需人工改 MediaMTX 配置或重建 SQLite。
|
|||
|
|
|
|||
|
|
该结论只证明“一台已准入实机 + 四条无人物合成源”的 M1 软件闭环,不证明五台真实设备兼容、故障隔离、默认 16 路或最大 128 路容量,也不构成生产 SLA。五条独立真实上游仍由 T-007 验收。
|
|||
|
|
|
|||
|
|
## 2. 实测架构
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
真实摄像头 -- RTSP/TCP -- 故障代理 :10554 --+
|
|||
|
|
|
|
|||
|
|
4 × FFmpeg -- publisher --> 源 MediaMTX :8555 +--> 生产 MediaMTX :8554
|
|||
|
|
^
|
|||
|
|
SQLite 期望态 --> Sense reconcile --> ONVIF/router ----+ API :9997
|
|||
|
|
^ |
|
|||
|
|
+---- Sense probe +---- 运行态反馈/重新对账
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- SQLite 是期望态真相源;设备台账只保存 `env://camera` 凭据引用。
|
|||
|
|
- HTTP/HTTPS endpoint 进入标准 ONVIF SOAP 1.2 + WS-Security PasswordDigest adapter;合成 `rtsp://` endpoint 由 router 直接映射,不伪装 ONVIF。
|
|||
|
|
- ONVIF adapter 获取设备信息、服务、profile 和 stream URI,在内存中注入 RTSP 凭据,并支持显式 NAT 主机/端口重写。错误不回显 endpoint、URI 或凭据。
|
|||
|
|
- 生产 MediaMTX path 只能由 Sense 对账通过 API 创建;`sense-lab` 只负责实验室播种和读取脱敏状态,不是冻结的公共设备管理 API。
|
|||
|
|
- probe 发现 MediaMTX path 丢失时使已观察代失效,触发重新对账,因此 MediaMTX 空配置重启后能从 SQLite 自动恢复五条 path。
|
|||
|
|
- 真实网络故障由本地 TCP 代理进程启停注入;不修改摄像头配置,也不继承 T-001 的物理断网豁免。
|
|||
|
|
|
|||
|
|
## 3. 固定版本与产物
|
|||
|
|
|
|||
|
|
| 组件 | 实测版本 / 摘要 |
|
|||
|
|
|---|---|
|
|||
|
|
| Sense | `dev`,Go `1.23.0 windows/amd64`;同源重建 `sense-api.exe` SHA-256 `5d49b91ff6c76802da3096e9155f6496187059a6a97114fbeb4e9b5a39128983` |
|
|||
|
|
| MediaMTX | `v1.19.3`,Windows amd64 发布包 SHA-256 `5d82148d1032a6a190d9909a2997d9989457aaadf49af87dd02cd4512d31bebe` |
|
|||
|
|
| FFmpeg | `8.1.2-full_build-www.gyan.dev`,4 个独立 `libx264` publisher |
|
|||
|
|
| SQLite driver | `modernc.org/sqlite v1.38.2`,随 Sense module 锁定 |
|
|||
|
|
|
|||
|
|
二进制、数据库、临时清单、日志和媒体都位于系统临时目录并在运行后删除;仓库不保存摄像头主机、内网地址、账号、密码、完整 RTSP/ONVIF URI、人物画面或可复用 token。
|
|||
|
|
|
|||
|
|
## 4. 可重复步骤
|
|||
|
|
|
|||
|
|
1. 将 T-001 格式的 `ip_camera.env` 放在仓库外或 Git 忽略路径;字段为 `host`、`username`、`password`、`rtspport`、`onvif`、`onvifuser`、`onvifpwd`。
|
|||
|
|
2. 确保本机 `8554`、`8555`、`9997`、`10554`、`18080` 未被占用,并安装 Go 1.23 与带 `libx264` 的 FFmpeg。
|
|||
|
|
3. 执行正式脚本;默认观察 30 分钟:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
./Sense/scripts/t006-integration.ps1 -CameraEnv D:\path\to\ip_camera.env
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. 脚本校验 MediaMTX 发布包 SHA-256,构建三个 Go 命令,启动两套 MediaMTX 和四个独立 publisher,播种一条真实设备和四条合成设备,再依次执行四类故障。
|
|||
|
|
5. 成功输出必须同时满足:`source_count = 5`、`synthetic_publishers = 4`、`configured_paths = 5`、每类恢复 `unconverged = 0`、观察至少 1800 秒、`maximum_unconverged = 0`、`final_unconverged = 0`。
|
|||
|
|
|
|||
|
|
调试时可加 `-ObservationMinutes 1`,但短窗口不能替代正式证据。本轮先完成 `60.6` 秒、6 次采样的 smoke,随后才执行正式窗口。
|
|||
|
|
|
|||
|
|
## 5. 正式结果
|
|||
|
|
|
|||
|
|
| 项目 | 结果 | 实测值 |
|
|||
|
|
|---|---|---:|
|
|||
|
|
| 初始五路自动收敛 | PASS | `8.2 s` |
|
|||
|
|
| 真实摄像头网络路径离线探测 | PASS | `1.0 s` |
|
|||
|
|
| 真实摄像头网络路径恢复 | PASS | `5.1 s` |
|
|||
|
|
| 单个合成 publisher 离线探测 | PASS | `1.0 s` |
|
|||
|
|
| 单个合成 publisher 恢复 | PASS | `5.1 s` |
|
|||
|
|
| Sense 重启到健康 | PASS | `0.5 s` |
|
|||
|
|
| Sense 重启后重新收敛 | PASS | `0.0 s`(SQLite 已保持一致) |
|
|||
|
|
| MediaMTX 空配置重启后恢复 | PASS | `2.1 s` |
|
|||
|
|
| 自动配置 path 数 | PASS | `5` |
|
|||
|
|
| 连续观察 | PASS | `1806.6 s` / `180` 次采样 |
|
|||
|
|
| 观察期最大 / 最终未收敛数 | PASS | `0 / 0` |
|
|||
|
|
|
|||
|
|
一分钟 smoke 的恢复值为:初始 `5.1 s`、真实网络 `5.1 s`、合成 publisher `5.1 s`、Sense `0.0 s`、MediaMTX `3.1 s`,观察 `60.6 s` / 6 次采样,最大和最终未收敛数均为 0。
|
|||
|
|
|
|||
|
|
## 6. 实机兼容发现与裁决
|
|||
|
|
|
|||
|
|
该旧固件通过 ONVIF 返回的主码流路径正确,但 URI 携带 `transportmode/profile` 查询串;使用正确 RTSP 账号请求该完整 URI仍返回 `401 Unauthorized`。相同凭据、主机、端口和通道路径仅移除查询串后,可立即解码 H.264 1920×1080。
|
|||
|
|
|
|||
|
|
因此实现增加 `SENSE_ONVIF_RTSP_STRIP_QUERY`,默认 `false`,仅对已经实测需要该兼容行为的部署显式设为 `true`。默认仍保留 ONVIF URI 查询语义;代码不按厂商名或型号硬编码,也不把该发现外推到其他海康型号、固件或品牌。
|
|||
|
|
|
|||
|
|
## 7. 失败记录与修正
|
|||
|
|
|
|||
|
|
| 现象 | 原因 | 修正与防回归 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 第二套 MediaMTX API 未启动 | 合成实例同时占用默认 UDP、RTMP/HLS/WebRTC/SRT/MoQ 端口 | 合成 fixture 限制为 RTSP over TCP,并关闭无关协议 |
|
|||
|
|
| Sense 已监听但 PowerShell 健康检查超时 | 测试机配置全局 HTTP 代理,本地请求未显式绕过 | 本地 `Invoke-RestMethod` 使用 `-NoProxy` |
|
|||
|
|
| Sense 未读取实验环境变量 | PowerShell 空数组位置参数被省略,哈希表错绑为命令参数 | `Start-ManagedProcess` 改用显式命名参数 |
|
|||
|
|
| 真实 path 长期 offline | 准入旧固件返回的 RTSP 查询串触发 401 | 增加默认关闭、按部署启用的 strip-query 兼容开关和单测 |
|
|||
|
|
| 观察期一次状态读取非零 | 独立状态进程与单写者 SQLite 短暂竞争 | 状态读取增加 5 次、250 ms 有界重试;持续失败仍终止验收 |
|
|||
|
|
|
|||
|
|
失败样本未从矩阵删除;每次修正后均从头重跑四类故障。正式结果来自最终完整运行,不拼接前序成功片段。
|
|||
|
|
|
|||
|
|
## 8. 限制与后续
|
|||
|
|
|
|||
|
|
- 公网/NAT 样机只用于受控开发验证;生产环境必须使用 VPN、专网或来源白名单,不应长期裸露 ONVIF/RTSP。
|
|||
|
|
- 单台精确固件基线不能证明批次差异、多品牌兼容或五台真实设备的并发故障隔离。
|
|||
|
|
- 合成流是 640×360、10 fps、H.264 无音频测试图案,不代表真实码率、音频、夜视、弱网、存储或 AI 负载。
|
|||
|
|
- 本任务没有验证 16/64/128 路容量;默认 16、单站点最大 128 的产品配额语义保持不变,容量与 GPU 承诺需独立压测。
|
|||
|
|
- `/healthz` 只表示 Sense 进程存活;设备收敛必须继续查看脱敏快照/指标,不能把进程健康等同于业务健康。
|