From 14c97760a7c8dee37d360f2641f0b90bccbc93cd Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Thu, 13 Aug 2026 22:05:15 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E8=AE=B0=E5=BD=95MediaMTX=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E6=81=A2=E5=A4=8D=20(#54)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/02-architecture-and-code-map.md | 6 +++--- docs/03-business-rules-and-glossary.md | 6 +++--- docs/06-troubleshooting.md | 5 +++-- ...¿®复实时监看按需拉流循环等待.md | 17 +++++++++++++---- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/02-architecture-and-code-map.md b/docs/02-architecture-and-code-map.md index 4d23df8..b53b5bd 100644 --- a/docs/02-architecture-and-code-map.md +++ b/docs/02-architecture-and-code-map.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Architecture-and-Code-Map wiki_url: https://git.ilapage.cn/ila/yovision/wiki/Architecture-and-Code-Map.- -wiki_revision: ebc61370932f51d51742c904e85c4f3ca6426a81 -synchronized_at: 2026-08-13T13:32:00Z +wiki_revision: e6bb3132a752cd8036cab29429cbf3f49e85bfbf +synchronized_at: 2026-08-13T14:06:00Z # 架构与代码地图 @@ -102,7 +102,7 @@ Sense 后端功能以 `Sense/server/app/sense/` 为根,并通过 `Sense/server - `identity/`:Sense 独立账户、bcrypt 密码、会话、四角色 RBAC 与统一审计;签发者和受众只属于 Sense。 - `device/`:Device 台账、状态、分页和 AES-256-GCM 凭据保险箱;ONVIF 与 RTSP 凭据可分离或显式复用,读取模型只返回两组凭据是否已配置。 - `adapters/onvif/`、`adapters/rtsp/`、`admission/`:获准网卡上的受控发现、手工 ONVIF 接入、Media 服务发现、Basic/Digest 认证、Profile/StreamUri 读取和 RTSP 验证。跨主机 Media 地址固定回用户已授权的 Device Service origin;跨主机 RTSP URI 只替换为授权主机并保留报告端口与路径。接入结果和脱敏 Profile 持久化到 PostgreSQL,重启后可恢复。 -- `adapters/mediamtx/`、`media/`:外部 MediaMTX 进程所有权、localhost Control API、媒体期望态与实际态对账;接入验证出可用 Profile 后自动按 Device/Profile 幂等建立并对账媒体路径。 +- `adapters/mediamtx/`、`media/`:外部 MediaMTX 进程所有权、localhost Control API、媒体期望态与实际态对账;接入验证出可用 Profile 后自动按 Device/Profile 幂等建立并对账媒体路径。首次路径使用 add、已有路径使用 replace,控制 API 启动竞态在限定时间内重试;Sense 完成数据库迁移后自动恢复 `desired=running` 路径。路径不存在必须报告配置失败,不能伪装为 waiting。 - `liveview/`:绑定当前用户、最长两分钟的单路播放会话;列表投影设备名称、位置、码流名称与用途,只在内部保留 ID,不暴露源 URI 或摄像机秘密。`waiting` 会话立即加载播放器以触发 MediaMTX 按需拉流,会话轮询只读刷新媒体实际状态。播放器包装页仅允许被 Sense 同源页面嵌入(`SAMEORIGIN` 与 `frame-ancestors 'self'`),其他页面继续使用全局 `DENY`。iframe 导航使用有效 Sense 会话 Cookie、媒体读取权限及同源 iframe Fetch Metadata 认证,不依赖浏览器导航无法附加的 `X-Product` 请求头;普通 API 仍要求产品头。 - `area/`:归一化多边形/方向警戒线、不可变版本、并发版本校验和分辨率变化后的重新校准。 diff --git a/docs/03-business-rules-and-glossary.md b/docs/03-business-rules-and-glossary.md index dfc1be3..f6f780e 100644 --- a/docs/03-business-rules-and-glossary.md +++ b/docs/03-business-rules-and-glossary.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Business-Rules-and-Glossary wiki_url: https://git.ilapage.cn/ila/yovision/wiki/Business-Rules-and-Glossary.- -wiki_revision: 1128d39385dd84192b0f93e428f5df2ae6026a4c -synchronized_at: 2026-08-13T13:32:00Z +wiki_revision: 06b68d16bf907decdaf85a813d417896f7920f4c +synchronized_at: 2026-08-13T14:06:00Z # 业务规则与术语 @@ -76,7 +76,7 @@ synchronized_at: 2026-08-13T13:32:00Z - **摄像机凭据**:ONVIF 与 RTSP 可使用不同账号,也可显式复用;两组均只写不读,使用仓库外 32 字节密钥分别加密。密码不得进入 URL、日志、审计、工单或响应。 - **受控发现**:ONVIF Discovery 默认关闭,只有显式设置获准本机 IP 才能发送发现;不得扫描未授权网段。 - **Profile**:主辅码流按分辨率分类并使用 RTSP 凭据分别验证;脱敏 Stream URI、验证状态和时间持久化,重启后保留。至少一个 Profile 验证成功后 Device 进入 `active`;认证失败、不可达、超时与校时问题使用可定位状态。 -- **自动媒体路径**:接入检查中每个验证成功的 Profile 都按 Device/Profile 幂等建立并立即对账媒体路径;MediaMTX 不可用不回滚摄像机接入,接入结果记录“需要处理”并引导到视频服务排错。 +- **自动媒体路径**:接入检查中每个验证成功的 Profile 都按 Device/Profile 幂等建立并立即对账媒体路径;首次配置使用 MediaMTX add、已有配置使用 replace,Sense 启动时从数据库恢复所有 `desired=running` 路径;路径不存在属于配置失败,不属于等待拉流。MediaMTX 不可用不回滚摄像机接入,接入结果记录“需要处理”并引导到视频服务排错。 - **MediaMTX**:保持外部进程。Sense 只停止自己启动并持有句柄的进程,最多自动重启三次;摄像机凭据只在 localhost 控制请求中瞬时组装,不持久化、不返回。 - **播放会话**:由当前 Sense 用户创建,最长两分钟;实时监看以设备名称、位置和主/子码流等业务标签供用户选择,内部 ID 只用于系统关联;`waiting` 表示等待第一个播放器触发按需拉流,不是播放失败,播放器连接后会话轮询刷新为实际状态;播放器导航必须携带有效 Sense 会话 Cookie,且 Fetch Metadata 必须表明是同源 iframe,普通 API 的 `X-Product` 边界不变;设备分页和媒体路径不以 16 路作为硬上限,页面一次只打开一路流。 - **区域版本**:坐标为 0..1 归一化值,并绑定 Device、Profile、宽高。每次发布或停用形成新版本;范围、点数、自交、退化、方向和期望版本由后端校验。Profile 分辨率变化后旧版本必须标记为需要重新校准。 diff --git a/docs/06-troubleshooting.md b/docs/06-troubleshooting.md index d83e494..6c7a623 100644 --- a/docs/06-troubleshooting.md +++ b/docs/06-troubleshooting.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Troubleshooting wiki_url: https://git.ilapage.cn/ila/yovision/wiki/Troubleshooting -wiki_revision: fb34dfc3c1a8963f4edbd578733d1c1f5238c021 -synchronized_at: 2026-08-13T13:32:00Z +wiki_revision: b70e92180546609cb9b3b05b2c13c1a49676c03b +synchronized_at: 2026-08-13T14:05:00Z # 故障排查 @@ -56,6 +56,7 @@ synchronized_at: 2026-08-13T13:32:00Z | `apply_failed` / `unconverged` | 检查 localhost Control API 是否启用并为 v3;确认媒体路径和外部进程状态。 | | 实时监看没有设备 | 先在视频接入完成一次检查;系统会自动建立媒体路径。若已接入仍为空,检查接入结果的媒体状态和视频服务对账。 | | 实时监看提示“127.0.0.1 拒绝了我们的连接请求” | 先确认播放器接口响应头;该接口必须是 `X-Frame-Options: SAMEORIGIN` 且 CSP 包含 `frame-ancestors 'self'`,普通页面仍应为 `DENY`。播放器接口还必须允许不带 `X-Product`、但带有效 Sense Cookie 和同源 iframe Fetch Metadata 的浏览器导航;普通 API 仍应拒绝缺少产品头的请求。旧运行包会在响应头或认证中间件处阻止 iframe,需重新打包并重启 Sense。 | +| 播放器提示 `stream not found` | MediaMTX 中没有对应配置路径。检查 Control API 配置列表是否包含 Sense 路径;新版本会在 Sense 启动时自动恢复 `desired=running` 路径,并在控制端口尚未就绪时限时重试。路径缺失必须显示配置失败,不能仅显示等待拉流。 | | 实时监看持续“等待拉流” | `waiting` 会话应立即加载播放器以触发按需拉流。若连接后仍等待,检查 MediaMTX 路径 readers 和源状态;`401 Unauthorized` 表示摄像机拒绝当前 RTSP 凭据,应在设备管理修正凭据后重新执行视频接入,不能把凭据写入日志或地址。 | | 画面等待、断开或会话过期 | 查看实时监看中的业务设备名和码流状态;会话轮询会只读刷新 MediaMTX 实际状态,无需手工对账。播放会话最长两分钟。 | | 区域提示需要重新校准 | Profile 分辨率已变化,按新画面重新绘制并发布新版本,不能静默复用旧坐标。 | diff --git a/docs/task/54-修复实时监看按需拉流循环等待.md b/docs/task/54-修复实时监看按需拉流循环等待.md index fce32fc..c021d94 100644 --- a/docs/task/54-修复实时监看按需拉流循环等待.md +++ b/docs/task/54-修复实时监看按需拉流循环等待.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Task-54-修复实时监看按需拉流循环等待 wiki_url: https://git.ilapage.cn/ila/yovision/wiki/Task-54-%E4%BF%AE%E5%A4%8D%E5%AE%9E%E6%97%B6%E7%9B%91%E7%9C%8B%E6%8C%89%E9%9C%80%E6%8B%89%E6%B5%81%E5%BE%AA%E7%8E%AF%E7%AD%89%E5%BE%85.- -wiki_revision: bdeca60040f62df75a8138491cb30939172b6b73 -synchronized_at: 2026-08-13T13:32:00Z +wiki_revision: ff79f9dbc718ae570b01dace25304379124a99b4 +synchronized_at: 2026-08-13T14:05:00Z # 54 修复实时监看按需拉流循环等待 @@ -27,12 +27,16 @@ MediaMTX 使用按需拉流时,必须先有播放器读取路径才会连接 - 会话查询通过只读媒体端口刷新控制器状态,把等待状态安全收敛为可播放或需要处理,不重新应用路径配置。 - 播放器包装接口覆盖全局嵌入策略为 `SAMEORIGIN`,并用 CSP `frame-ancestors 'self'` 限制为 Sense 同源页面;其他接口继续保持 `X-Frame-Options: DENY`。 - iframe 导航无法附加 API 客户端的 `X-Product` 头,因此播放器路由改用窄导航认证:有效 Sense 会话 Cookie、媒体读取权限、`Sec-Fetch-Site: same-origin`、`Sec-Fetch-Mode: navigate` 和 `Sec-Fetch-Dest: iframe` 必须同时满足。普通 API 的产品头要求保持不变。 +- MediaMTX 路径首次配置使用 add,已存在时使用 replace;控制 API 刚启动尚未监听时限时等待。 +- Sense 完成数据库迁移后自动恢复所有 `desired=running` 路径;路径不存在显式标记为配置失败,不再误报 waiting。 - 继续保持 `sourceOnDemand`,无人观看时不占用摄像机连接与转码资源。 - 真实环境验证过程中发现已保存的 RTSP 凭据被摄像机拒绝(401);已通过现有 Sense 接口使用本地已获授权配置修正运行数据,未把凭据写入仓库、工单、Wiki 或日志证据。 ## 修改文件 -- `Sense/server/app/sense/media/service.go`、`route_port.go`:增加只读状态刷新能力。 +- `Sense/server/app/sense/media/service.go`、`route_port.go`:增加只读状态刷新、缺失状态和启动恢复能力。 +- `Sense/server/app/sense/adapters/mediamtx/client.go`、`client_test.go`:实现 add/replace 幂等语义并等待控制 API 就绪。 +- `Sense/server/cmd/sense/{modules_media.go,root.go}`、`internal/platform/app.go`:在迁移完成后执行媒体路径恢复。 - `Sense/server/app/sense/media/service_test.go`:验证刷新状态且不重复配置路径。 - `Sense/server/app/sense/liveview/service.go`:查询会话时刷新媒体状态。 - `Sense/server/app/sense/liveview/http.go`、`http_test.go`:允许并验证播放器包装页仅同源嵌入。 @@ -52,6 +56,8 @@ MediaMTX 使用按需拉流时,必须先有播放器读取路径才会连接 | 不泄露摄像机凭据和源地址 | 通过 | | 播放器可被 Sense 同源嵌入且其他页面仍禁止嵌入 | 通过,运行包接口响应头验证通过 | | iframe 不带 `X-Product` 时仍能安全认证 | 通过,同源 iframe + 有效 Cookie 返回 200;跨站返回 401;普通 API 缺少产品头返回 401 | +| MediaMTX 冷启动后恢复 Sense 路径 | 通过,配置列表自动出现 2 条 `sourceOnDemand` 路径,无需手工对账 | +| 两条摄像机路径可实际解码 | 通过,主码流 H.264 1920×1080 + AAC,子码流 H.264,均收到媒体字节 | ## 测试 @@ -61,7 +67,9 @@ MediaMTX 使用按需拉流时,必须先有播放器读取路径才会连接 - Go 1.26.5 Windows 打包:通过。 - 运行包响应头:播放器接口为 `SAMEORIGIN` 且包含 `frame-ancestors 'self'`;首页仍为 `DENY`。 - 运行包浏览器式认证:不带 `X-Product`、带有效 Cookie 和同源 iframe Fetch Metadata 的播放器请求返回 200;跨站播放器与缺少产品头的普通 API 均返回 401。 -- 真实媒体链路:MediaMTX `sourceReady=true`、`readers=1`、收到媒体字节且包含 2 个轨道;Sense 会话由 `waiting` 收敛为 `ready`。 +- 冷启动恢复:MediaMTX 配置列表自动包含两条 Sense `sourceOnDemand` 路径;运行态列表也存在两条路径。 +- 真实媒体链路:主码流 H.264 1920×1080 + AAC,子码流 H.264;两条路径分别通过本机 RTSP 读取并收到媒体字节。 +- 单元测试覆盖路径首次 add、已有 replace、控制 API 启动等待、启动恢复及缺失路径不误报 waiting。 - **未验证部分**:最终浏览器中的可视画面需要用户在当前浏览器验收;自动化已验证媒体源、读取者与会话状态收敛。 ## 遗留问题 @@ -74,3 +82,4 @@ MediaMTX 使用按需拉流时,必须先有播放器读取路径才会连接 - `b3dfd23` 更新按需拉流长期 Wiki 镜像。 - `3696442` 允许播放器包装页仅被 Sense 同源嵌入。 - `8bf9a6d` 支持同源播放器导航认证并保持普通 API 产品边界。 +- `d7cd3a5` 恢复 MediaMTX 按需路径并处理启动竞态。