From f41a924a2dfba6775a52fba8b29593cd4377d040 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Wed, 29 Apr 2026 11:25:48 +0800 Subject: [PATCH] Add video sources design spec --- .../specs/2026-04-29-video-sources-design.md | 323 ++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-29-video-sources-design.md diff --git a/docs/superpowers/specs/2026-04-29-video-sources-design.md b/docs/superpowers/specs/2026-04-29-video-sources-design.md new file mode 100644 index 0000000..aa9f225 --- /dev/null +++ b/docs/superpowers/specs/2026-04-29-video-sources-design.md @@ -0,0 +1,323 @@ +# 视频源结构化设计 + +## 背景 + +当前后台已经将配置体系逐步拆分为两层: + +- `场景配置`:定义一个最终要运行的业务场景 +- `基础配置`:承载可被场景配置复用的公共配置 + +第三方服务已经明确要作为一类可复用的基础配置存在。视频输入端也具有相同特征: + +- 由客户现场提供 +- 生命周期通常长于单个场景配置 +- 多个场景可能复用同一路输入流 +- 修改地址或元信息时,不应该逐个修改场景配置 + +因此,视频输入不应继续散落在场景配置实例的 `rtsp_url` 等字段中,而应独立为一类基础配置。 + +## 核心定义 + +本设计中的**一个视频源 = 一路输入流**。 + +它不是一台物理摄像机设备,也不是一台 NVR,而是一条能够被场景配置直接引用的输入流。 + +例如: + +- 一台摄像机只有一路 RTSP,则对应一个视频源 +- 一个 NVR 下有 8 路通道,则应建 8 个视频源 + +这个定义与当前识别链路最匹配,也最利于场景配置引用和后续维护。 + +## 目标 + +本次设计要解决以下问题: + +1. 为视频源建立统一、结构化的数据模型 +2. 在 `基础配置` 中增加独立的 `视频源` 管理页面 +3. 让 `场景配置` 通过引用视频源,而不是直接填写 `rtsp_url` +4. 在不破坏现有配置链路的前提下,为后续逐步替换场景内联输入字段打基础 + +## 非目标 + +本次不包含以下内容: + +- 不做完整的摄像机资产台账 +- 不引入厂商、型号、采购信息、维护记录等固定资产字段 +- 不做视频源在线探测或取流连通性检测 +- 不做自动读取码流元信息 +- 不处理多通道设备实体模型 + +## 设计原则 + +1. 一个视频源只表示一路可引用输入流 +2. 识别相关字段优先,现场安装字段作为可选补充 +3. 表单默认保持简洁,非必要字段不阻塞创建 +4. 页面交互和第三方服务保持一致,降低认知成本 + +## 字段设计 + +推荐将视频源字段分为三组。 + +### 1. 基本信息 + +- `name`:视频源名称,唯一标识 +- `source_type`:视频源类型 +- `area`:区域 +- `description`:描述 + +说明: + +- `name` 用于被场景配置引用 +- `area` 用于表达现场语义,例如“东门入口”“1号产线”“仓库西侧” +- `description` 用于补充说明 + +### 2. 输入参数 + +- `url`:输入地址 +- `resolution`:分辨率,例如 `1920x1080` +- `fps`:帧率 +- `video_format`:视频格式,例如 `h264`、`h265`、`mjpeg` + +说明: + +- `url` 必填 +- `resolution`、`fps`、`video_format` 可选 + +### 3. 安装信息 + +- `focal_length`:焦距 +- `mount_height`:安装高度 +- `mount_angle`:安装角度 + +说明: + +- 三个字段均为可选 +- 它们主要用于表达现场安装条件,不应阻塞视频源创建 + +## 类型设计 + +第一版推荐支持以下视频源类型: + +- `rtsp` +- `rtmp` +- `file` +- `usb_camera` + +当前主路径仍然是 `rtsp`,但枚举应预先保留扩展空间。 + +页面文案可使用: + +- RTSP +- RTMP +- 文件流 +- USB 摄像头 + +## 数据结构 + +视频源建议使用与第三方服务类似的“顶层基础字段 + config 承载详细参数”的方式。 + +推荐结构: + +```json +{ + "name": "gate_cam_01", + "source_type": "rtsp", + "area": "东门入口", + "description": "东门主入口摄像头", + "config": { + "url": "rtsp://10.0.0.1/live", + "resolution": "1920x1080", + "fps": 25, + "video_format": "h264", + "focal_length": "4mm", + "mount_height": "3.2m", + "mount_angle": "15deg" + } +} +``` + +说明: + +- 顶层保持对象识别字段 +- `config` 用于承载输入参数和安装信息 +- 第一版不再继续向下拆分成多层嵌套,避免结构过重 + +## 与现有配置字段的关系 + +当前场景配置实例中已存在: + +- `display_name` +- `site_name` +- `rtsp_url` +- `channel_no` + +在新结构下: + +- `rtsp_url` 应逐步由视频源 `config.url` 替代 +- `display_name` 仍属于场景实例显示语义,不属于视频源本身 +- `site_name` 仍偏场景/站点上下文,不建议塞进视频源 +- `channel_no` 如果表达的是输入流标识,可保留在场景实例或后续再决定是否并入视频源 + +## 场景配置中的引用方式 + +场景配置不应长期继续直接持有 `rtsp_url`,而应改为引用视频源。 + +由于当前场景配置是多实例结构,推荐按实例增加引用字段: + +- `video_source_ref` + +示例: + +```json +{ + "instances": [ + { + "name": "cam1", + "template": "std_workshop_face_recognition_shoe_alarm", + "video_source_ref": "gate_cam_01", + "params": { + "display_name": "东门入口" + } + } + ] +} +``` + +这比把视频源引用放在整个场景顶层更合理,因为一个场景通常会包含多路输入。 + +## 兼容策略 + +第一阶段建议采用兼容式落地: + +1. 新建视频源资产 +2. 场景配置实例开始支持 `video_source_ref` +3. 若实例中存在 `video_source_ref`,则预览和下发时优先使用视频源中的 `url` +4. 若不存在 `video_source_ref`,仍兼容现有 `rtsp_url` + +这样可以逐步迁移,而不需要一次性改完所有历史配置。 + +## UI 设计 + +入口: + +- `基础配置 -> 视频源` + +页面交互与第三方服务保持一致: + +- 顶部按钮:`新增视频源`、`编辑`、`删除` +- 列表区:视频源列表 +- 详情区:默认只读 +- 点击 `编辑` 后进入编辑态 +- 点击 `新增视频源` 后清空详情并聚焦名称输入框 + +## 列表页字段 + +推荐列表列: + +- 视频源名称 +- 类型 +- 区域 +- URL 摘要 +- 分辨率 +- 帧率 + +说明: + +- 列表优先展示能帮助快速识别和定位的视频信息 +- 焦距、安装高度、安装角度不放在列表里 + +## 详情页字段分组 + +### 基本信息 + +- 视频源名称 +- 类型 +- 区域 +- 描述 + +### 输入参数 + +- URL +- 分辨率 +- 帧率 +- 视频格式 + +### 安装信息 + +- 焦距 +- 安装高度 +- 安装角度 + +## 校验规则 + +### 必填 + +- `name` +- `source_type` +- `config.url` + +### 可选 + +- `area` +- `description` +- `config.resolution` +- `config.fps` +- `config.video_format` +- `config.focal_length` +- `config.mount_height` +- `config.mount_angle` + +### 基本格式建议 + +- `name` 必须唯一 +- `fps` 如填写,应可解析为数值 +- `resolution` 第一版可先作为字符串保存,不强制拆成宽高 + +## 删除约束 + +如果某个视频源已被场景配置实例引用,则不允许直接删除。 + +删除前应检查: + +- 是否存在场景实例的 `video_source_ref` 指向该视频源 + +如果存在引用,应提示: + +- 当前视频源已被某些场景配置使用,不能删除 + +## 存储建议 + +建议沿用现有 SQLite 基础配置仓储模式,新增一类 `video_sources` 存储对象。 + +每条记录至少包含: + +- `name` +- `source_type` +- `area` +- `description` +- `body_json` +- `created_at` +- `updated_at` + +## 第一阶段实施范围 + +第一阶段只实现以下内容: + +1. 视频源的数据结构与存储 +2. `基础配置 -> 视频源` 列表和详情维护页 +3. 场景配置实例支持 `video_source_ref` +4. 预览/下发时优先用视频源 URL 展开 +5. 删除前引用检查 + +## 结论 + +视频源应被定义为**一路可被场景配置引用的输入流**。 + +采用“基础识别字段 + 输入参数 + 可选安装信息”的结构最适合当前系统阶段: + +- 比单纯只存 URL 更完整 +- 比完整摄像机资产台账更轻 +- 既能服务识别配置,又能保留现场语义 + +第一版推荐按 `video_source_ref` 的方式逐步替换场景配置中的内联 `rtsp_url`,从而让视频源真正成为可复用、可维护的基础配置对象。