# 视频源结构化设计

## 背景

当前后台已经将配置体系逐步拆分为两层：

- `场景配置`：定义一个最终要运行的业务场景
- `基础配置`：承载可被场景配置复用的公共配置

第三方服务已经明确要作为一类可复用的基础配置存在。视频输入端也具有相同特征：

- 由客户现场提供
- 生命周期通常长于单个场景配置
- 多个场景可能复用同一路输入流
- 修改地址或元信息时，不应该逐个修改场景配置

因此，视频输入不应继续散落在场景配置实例的 `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`：标准分辨率等级，例如 `720p`、`1080p`、`1440p`、`4k`
- `frame_size`：像素尺寸，例如 `1280x720`、`1920x1080`
- `fps`：帧率
- `video_format`：视频格式，例如 `h264`、`h265`、`mjpeg`

说明：

- `url` 必填
- `resolution`、`frame_size`、`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": "1080p",
    "frame_size": "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 摘要
- 分辨率
- 帧率

说明：

- 列表中的“分辨率”优先显示 `resolution` 这类标准等级
- `frame_size` 作为详情中的技术补充字段，不默认放在列表里
- 焦距、安装高度、安装角度不放在列表里

## 详情页字段分组

### 基本信息

- 视频源名称
- 类型
- 区域
- 描述

### 输入参数

- URL
- 分辨率
- 像素尺寸
- 帧率
- 视频格式

### 安装信息

- 焦距
- 安装高度
- 安装角度

## 校验规则

### 必填

- `name`
- `source_type`
- `config.url`

### 可选

- `area`
- `description`
- `config.resolution`
- `config.frame_size`
- `config.fps`
- `config.video_format`
- `config.focal_length`
- `config.mount_height`
- `config.mount_angle`

### 基本格式建议

- `name` 必须唯一
- `fps` 如填写，应可解析为数值
- `resolution` 使用标准分辨率等级表达，例如 `720p`、`1080p`
- `frame_size` 第一版可先作为字符串保存，不强制拆成宽高整数

## 删除约束

如果某个视频源已被场景配置实例引用，则不允许直接删除。

删除前应检查：

- 是否存在场景实例的 `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`，从而让视频源真正成为可复用、可维护的基础配置对象。
