增加一些部署脚本和必要的文档
This commit is contained in:
parent
4940926866
commit
02c5dd2f6d
16
Readme.md
16
Readme.md
@ -474,6 +474,7 @@ GraphMgr 负责:
|
||||
```
|
||||
|
||||
> 说明:如果不需要后处理:
|
||||
>
|
||||
> - **推荐**:保留 `pp_cam1` 节点(`enable:true`),并确保其不启用任何处理链(例如:`default.enable=false` 且 `per_class` 为空),此时 `det_post` 会作为轻量透传。
|
||||
> - 若确实要移除该节点:需要**同时删除并重连拓扑**(例如改回 `ai_cam1 -> osd_cam1` 与 `ai_cam1 -> alarm_cam1`),仅设置 `enable=false` 会导致下游节点无输入而构图失败。
|
||||
|
||||
@ -588,6 +589,7 @@ GraphMgr 负责:
|
||||
`det_post` 是一个 **Filter** 节点,位于 `ai_yolo` 之后,负责对 `frame->det->items` 做**按类别可配置**的后处理。
|
||||
|
||||
**设计目标:**
|
||||
|
||||
- 不同类别可以挂不同的处理器链(Processor/Strategy Registry),避免“一个类别一个插件”。
|
||||
- 默认改写 `frame->det`,让 `osd` / `alarm` 读到一致结果。
|
||||
|
||||
@ -634,6 +636,7 @@ GraphMgr 负责:
|
||||
```
|
||||
|
||||
**内置 processors(当前实现):**
|
||||
|
||||
- `conf_gate`:按置信度过滤(`conf_min`)
|
||||
- `bbox_gate`:按框尺寸过滤(`min_w`, `min_h`)
|
||||
- `roi_gate`:按 ROI 过滤(`roi:{x,y,w,h}` 归一化;`mode:center` 使用 bbox 中心点判断)
|
||||
@ -643,6 +646,7 @@ GraphMgr 负责:
|
||||
> 注意:`hsv_ratio/lab_kmeans` 需要 `Frame` 提供可读的像素数据(`frame->data` 可访问)。若上游是纯 DMA-BUF 且未映射到 CPU,这两类处理器会自然退化为“不过滤”。
|
||||
|
||||
**ai_yolo 参数说明:**
|
||||
|
||||
- `model_version`: `"v5"`, `"v8"` 或 `"auto"`(自动检测)
|
||||
- `num_classes`: 模型类别数(默认 80)
|
||||
- `class_filter`: 只检测指定类别 ID 的数组,如 `[0, 1, 2]`
|
||||
@ -671,6 +675,7 @@ GraphMgr 负责:
|
||||
```
|
||||
|
||||
**参数说明:**
|
||||
|
||||
- `model_path`: RetinaFace RKNN 模型路径
|
||||
- `conf`: 置信度阈值(默认 0.6)
|
||||
- `nms`: NMS 阈值(默认 0.4)
|
||||
@ -711,6 +716,7 @@ GraphMgr 负责:
|
||||
```
|
||||
|
||||
**参数说明:**
|
||||
|
||||
- `model_path`: ArcFace/MobileFaceNet RKNN 模型路径(输入 112x112,输出 512D embedding)
|
||||
- `align`: 是否使用 5 点关键点做仿射对齐(推荐开启)
|
||||
- `emit_embedding`: 是否在结果中输出 embedding(调试用,生产关闭以省内存)
|
||||
@ -721,6 +727,7 @@ GraphMgr 负责:
|
||||
- `gallery.expected_dim`: embedding 维度(需与模型匹配)
|
||||
|
||||
**判定规则:**
|
||||
|
||||
- `top1_sim >= accept` 且(可选)`top1_sim - top2_sim >= margin` → 识别为该人
|
||||
- 否则标记为 `unknown`
|
||||
|
||||
@ -779,6 +786,7 @@ CREATE TABLE embedding (
|
||||
```
|
||||
|
||||
**检索实现:**
|
||||
|
||||
- 小库(≤几千人):CPU 暴力点积,无需额外索引
|
||||
- 大库(≥几万人):可扩展 HNSW/Faiss 等 ANN 索引
|
||||
|
||||
@ -795,6 +803,7 @@ CREATE TABLE embedding (
|
||||
> 说明:当前实现中 `publish` 的 `proto:"hls"` 为**落盘生成 m3u8/ts 文件**,`path` 应指向 `index.m3u8` 文件路径;若需要通过网络播放,建议新增 `zlm_http` 节点启动内嵌 HTTP,并将 `root` 指向 HLS 父目录(如 `/data/hls`)。
|
||||
|
||||
**osd 参数说明:**
|
||||
|
||||
- `labels`: 自定义类别标签数组,如 `["cat", "dog", "bird"]`,为空则使用 COCO 默认标签
|
||||
|
||||
### 6.4 alarm 插件详细说明
|
||||
@ -802,6 +811,7 @@ CREATE TABLE embedding (
|
||||
alarm 插件采用**模块化 Actions 架构**,支持多种报警动作的灵活组合:
|
||||
|
||||
**架构设计:**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ AlarmNode │
|
||||
@ -822,6 +832,7 @@ alarm 插件采用**模块化 Actions 架构**,支持多种报警动作的灵
|
||||
```
|
||||
|
||||
**完整配置示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "alarm_cam1",
|
||||
@ -904,11 +915,13 @@ alarm 插件采用**模块化 Actions 架构**,支持多种报警动作的灵
|
||||
- `alarmContent`:若配置中未提供 `alarmContent`,默认使用 `rule_name`。
|
||||
|
||||
**external_api 参数说明:**
|
||||
|
||||
- 必填:`getTokenUrl`, `putMessageUrl`, `tenantCode`, `channelNo`
|
||||
- 常用可选:`timeout_ms`(默认 3000)、`include_media_url`(默认 true)、`token_cache_sec`(默认 600;为 0 时仅在 401/403 时刷新 token)
|
||||
- 其它可选:`token_header`、`token_json_path`、`alarmContent`、`max_queue_size` / `queue_policy`、`max_retries` / `retry_backoff_ms`
|
||||
|
||||
**规则参数说明:**
|
||||
|
||||
- `class_ids`: 要监控的类别 ID 数组(与模型输出对应)
|
||||
- `objects`: 要监控的类别名称数组(需配合 `labels` 使用)
|
||||
- `roi`: 感兴趣区域,归一化坐标 (0-1)
|
||||
@ -917,6 +930,7 @@ alarm 插件采用**模块化 Actions 架构**,支持多种报警动作的灵
|
||||
- `schedule`: 有效时间段,格式 "HH:MM-HH:MM"
|
||||
|
||||
**上传器类型:**
|
||||
|
||||
- `local`: 保存到本地文件系统
|
||||
- `minio`: 上传到 MinIO 对象存储
|
||||
- `s3`: 上传到 AWS S3(兼容 MinIO)
|
||||
@ -926,6 +940,7 @@ alarm 插件采用**模块化 Actions 架构**,支持多种报警动作的灵
|
||||
storage 插件用于**持续录像**(7x24 小时),与 alarm 的事件录像功能互补。
|
||||
|
||||
**配置示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "storage_cam1",
|
||||
@ -943,6 +958,7 @@ storage 插件用于**持续录像**(7x24 小时),与 alarm 的事件录
|
||||
```
|
||||
|
||||
**参数说明:**
|
||||
|
||||
- `mode`: 录像模式,当前支持 `continuous`(持续录像)
|
||||
- `format`: 输出格式,`mp4` 或 `ts`
|
||||
- `segment_sec`: 单个文件时长(秒)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
# PRD ① 设备端(rk3588-agent + media-server)远程管理能力(V1)
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前 `media-server` 已提供 HTTP 控制台与配置热更新能力(`/api/*`、`/api/config/reload`、`/api/config/rollback` 等)。由于 **大文件模型上传** 在现有 C++ 自研 HTTP Server 上实现成本较高(需要流式接收/写盘/校验/限流),本期采用更工程化的拆分:
|
||||
|
||||
- `media-server`:继续专注业务图(推理/推流/报警)与热更新。
|
||||
@ -9,18 +10,21 @@
|
||||
> 本 PRD 覆盖“轻量热更新/重载/回滚(业务图级)”。systemd/重启系统等运维级操作可作为后续扩展,但不作为 V1 验收项。
|
||||
|
||||
## 2. 目标
|
||||
|
||||
1. 管理端可通过 UDP 广播在 1 秒内发现同网段 10 台设备(由 `rk3588-agent` 响应)。
|
||||
2. 管理端可通过 `rk3588-agent` 上传配置 JSON,设备端原子写入后触发 `media-server` reload 生效。
|
||||
3. 管理端可通过 `rk3588-agent` 上传模型文件到设备固定目录,并返回可直接在配置中引用的 `model_path`。
|
||||
4. 所有对外写操作必须鉴权(Token),读操作默认可不鉴权(可配置)。
|
||||
|
||||
## 3. 非目标(V1 不做)
|
||||
|
||||
- systemd start/stop/restart `media-server`(可在 agent 后续扩展)
|
||||
- 设备重启/固件升级/插件升级
|
||||
- 跨网段发现(保留后端可做网段扫描 fallback)
|
||||
- 完整 RBAC/用户体系
|
||||
|
||||
## 4. 现状可复用能力(不修改语义)
|
||||
|
||||
- HTTP Server:`src/http_server.cpp`
|
||||
- Graph/热更新:`GraphManager::ReloadFromFile`、`GraphManager::RollbackFromLastGood`
|
||||
- 配置 Expand + Validate:`utils/config_expand.*`、`utils/config_schema.h`
|
||||
@ -29,6 +33,7 @@
|
||||
## 5. 新增功能范围(V1)
|
||||
|
||||
### 5.1 新增进程:rk3588-agent(Go)
|
||||
|
||||
`rk3588-agent` 作为常驻服务,提供:
|
||||
|
||||
- UDP 广播发现(Option A):对管理端 Search 做响应。
|
||||
@ -36,6 +41,7 @@
|
||||
- 本地调用 `media-server`:通过 `http://127.0.0.1:<media_port>/api/...` 触发 reload/rollback/读取 graphs/logs。
|
||||
|
||||
#### 5.1.1 agent 代码目录结构(建议,开发可直接照此建工程)
|
||||
|
||||
建议以 Go module 形式独立工程(可放在同仓库 `agent/` 目录,也可独立仓库)。
|
||||
|
||||
```text
|
||||
@ -56,6 +62,7 @@ agent/
|
||||
```
|
||||
|
||||
### 5.2 media-server 变更范围(V1)
|
||||
|
||||
V1 目标是将大文件上传从 `media-server` 移出,因此 **media-server 可不新增大文件上传接口**。仅要求:
|
||||
|
||||
- 保持现有 `/api/config/reload`、`/api/config/rollback`、`/api/graphs`、`/api/logs/recent` 等接口可用。
|
||||
@ -64,6 +71,7 @@ V1 目标是将大文件上传从 `media-server` 移出,因此 **media-server
|
||||
## 6. 配置与落盘约定
|
||||
|
||||
### 6.1 新增 agent 配置项(建议)
|
||||
|
||||
agent 需要独立配置(例如 `/etc/rk3588-agent/config.json`)。建议:
|
||||
|
||||
```json
|
||||
@ -87,6 +95,7 @@ agent 需要独立配置(例如 `/etc/rk3588-agent/config.json`)。建议:
|
||||
```
|
||||
|
||||
字段说明(V1 关键字段):
|
||||
|
||||
- `config_path`:agent 写入配置文件的目标路径(与 media-server `--config` 一致)。
|
||||
- `device_id_path`:device_id 持久化文件路径(不存在则自动生成并写入)。
|
||||
- `media_server_base_url`:agent 调用 media-server 的本机地址,建议固定 `127.0.0.1`。
|
||||
@ -94,6 +103,7 @@ agent 需要独立配置(例如 `/etc/rk3588-agent/config.json`)。建议:
|
||||
- `media_server_retry`:仅对“控制类请求”(reload/rollback)启用的重试策略。
|
||||
|
||||
### 6.2 设备侧文件系统布局(部署约定)
|
||||
|
||||
为保证权限与可维护性,约定如下路径:
|
||||
|
||||
- 可执行文件:
|
||||
@ -113,6 +123,7 @@ agent 需要独立配置(例如 `/etc/rk3588-agent/config.json`)。建议:
|
||||
### 6.3 systemd service(部署字段,开发/运维可直接照抄)
|
||||
|
||||
#### 6.3.1 rk3588-agent.service
|
||||
|
||||
路径建议:`/etc/systemd/system/rk3588-agent.service`
|
||||
|
||||
```ini
|
||||
@ -142,6 +153,7 @@ WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
#### 6.3.2 media-server.service(建议统一纳入部署约定)
|
||||
|
||||
路径建议:`/etc/systemd/system/media-server.service`
|
||||
|
||||
```ini
|
||||
@ -169,20 +181,24 @@ WantedBy=multi-user.target
|
||||
> V1 不要求 agent 控制 systemd,但要求两服务可开机自启。
|
||||
|
||||
### 6.5 性能调参说明(新增)
|
||||
|
||||
- `RK3588_RKNN_CTX_POOL_SIZE`:同一模型的 RKNN context 池大小(默认 3)。
|
||||
- `RK3588_RGA_MAX_INFLIGHT`:RGA 全局并发上限(默认 2)。
|
||||
|
||||
### 6.4 模型目录结构
|
||||
|
||||
- `${models_dir}/manifest.json`
|
||||
- `${models_dir}/files/<name>__<sha256>.<ext>`(`ext` 默认 `rknn`,白名单控制)
|
||||
|
||||
## 7. 约束与安全
|
||||
|
||||
- agent 对外写接口必须 `X-RK-Token`。
|
||||
- 上传限制:必须 `Content-Length`;大小不得超过 `max_upload_mb`。
|
||||
- agent 写盘采用原子写(临时文件 + rename)。
|
||||
- agent 与 `media-server` 的本地通信固定走 `127.0.0.1`(避免暴露内部控制面)。
|
||||
|
||||
### 7.1 agent 内部调用 media-server 的 URL/超时/重试策略
|
||||
|
||||
agent 只调用 media-server 的既有接口(对内 base URL = `media_server_base_url`):
|
||||
|
||||
- Reload:`POST {base}/api/config/reload`
|
||||
@ -192,27 +208,32 @@ agent 只调用 media-server 的既有接口(对内 base URL = `media_server_b
|
||||
- Logs:`GET {base}/api/logs/recent?limit=...`
|
||||
|
||||
超时策略(建议默认值):
|
||||
|
||||
- 读接口(graphs/logs):总超时 `1000ms`(不重试)
|
||||
- 控制接口(reload/rollback):总超时 `media_server_timeout_ms`(默认 `3000ms`),允许重试
|
||||
|
||||
重试策略(仅控制接口):
|
||||
|
||||
- `max_attempts = 3`(首次 + 2 次重试)
|
||||
- 触发条件:连接失败/超时/5xx(不对 4xx 重试)
|
||||
- backoff:`[200ms, 500ms]`
|
||||
|
||||
配置下发联动策略(`PUT /v1/config`):
|
||||
|
||||
1) agent 原子写入 `config_path`
|
||||
2) 调用 reload(按控制接口重试策略)
|
||||
3) 若 reload 最终失败:调用 rollback(按控制接口重试策略)
|
||||
4) 返回 500,错误消息包含 reload 与 rollback 的结果(便于定位)
|
||||
|
||||
### 7.2 启动顺序与可用性
|
||||
|
||||
- 建议 systemd 启动顺序:两者都 After network-online。
|
||||
- agent 对外可先起来;当 media-server 尚未启动时:
|
||||
- `/v1/graphs`、`/v1/logs/recent` 返回 500(error=connect refused/timeout)
|
||||
- `/v1/config` 返回 500(写盘可成功,但 reload 失败会触发 rollback;错误信息提示 media-server 不可用)
|
||||
|
||||
## 8. 验收标准(Acceptance Criteria)
|
||||
|
||||
1. 同网段 10 台设备,管理端 Search(UDP broadcast)在 1 秒内都能发现;列表包含 `device_id/ip/agent_port/media_port/version/git_sha`。
|
||||
2. agent `PUT /v1/config`:
|
||||
- 发送合法 config,设备写盘并触发 `media-server` reload 成功,graphs 状态正常。
|
||||
@ -221,6 +242,7 @@ agent 只调用 media-server 的既有接口(对内 base URL = `media_server_b
|
||||
4. 无 token 调用写接口返回 401;错误返回 JSON:`{"error":"..."}`。
|
||||
|
||||
## 9. 开发任务拆分(建议)
|
||||
|
||||
- [ ] 新增 `rk3588-agent`:HTTP 服务 + Token 鉴权 + 日志
|
||||
- [ ] UDP discovery:协议解析/回复、device_id 获取与持久化、停止逻辑
|
||||
- [ ] `GET /v1/info`:聚合 device/version/git_sha/ports/uptime
|
||||
@ -1,16 +1,19 @@
|
||||
# PRD ② 管理端前端(React Web UI)V1
|
||||
|
||||
## 1. 产品形态
|
||||
|
||||
- 用户在 PC 上启动 `managerd`(Go 后端),浏览器打开:`http://127.0.0.1:<port>/`。
|
||||
- 前端只与本机 `managerd` 通信(不直连设备),避免跨域与安全复杂度。
|
||||
|
||||
## 2. 目标
|
||||
|
||||
1. 一键 Search 发现设备并展示在线状态。
|
||||
2. 单设备:查看 graphs 状态、查看 logs、执行 reload/rollback。
|
||||
3. 单设备:上传模型、下发配置并生效。
|
||||
4. 多设备:批量下发配置(任务化显示进度与失败原因)。
|
||||
|
||||
## 3. UI 风格(V1)
|
||||
|
||||
- 风格:极简运维控制台(表格 + 抽屉/弹窗 + 表单),信息密度优先。
|
||||
- 主题:浅色默认;无需复杂动效。
|
||||
- 组件库:Ant Design(推荐)。
|
||||
@ -21,6 +24,7 @@
|
||||
- 失败:红色提示 + 可展开错误详情
|
||||
|
||||
## 4. 技术选型与工程要求
|
||||
|
||||
- React 18 + TypeScript + Vite
|
||||
- 路由:React Router
|
||||
- 请求与缓存:React Query(或 SWR)
|
||||
@ -30,13 +34,16 @@
|
||||
## 5. 页面与交互
|
||||
|
||||
### 5.1 设备列表页 `/devices`
|
||||
|
||||
**组件**:表格(可搜索/排序)
|
||||
|
||||
**顶部操作**:
|
||||
|
||||
- `Search`(触发发现)
|
||||
- `Batch Apply Config`(进入批量配置向导/弹窗)
|
||||
|
||||
**表格列**:
|
||||
|
||||
- Status(Online/Offline)
|
||||
- Device Name
|
||||
- IP:AgentPort(可在详情页展示 MediaPort)
|
||||
@ -46,35 +53,43 @@
|
||||
- Actions:Detail / Reload / Rollback
|
||||
|
||||
**交互**:
|
||||
|
||||
- Search 点击后 1~2 秒 loading,完成后刷新列表。
|
||||
- Reload/Rollback:弹确认框;提交后显示 toast;失败显示 error 文本。
|
||||
|
||||
### 5.2 设备详情页 `/devices/:deviceId`
|
||||
|
||||
使用 Tabs:
|
||||
|
||||
1) **Overview**
|
||||
|
||||
- 展示 `info`:device_id、device_name、hostname、ip、version、git_sha、uptime
|
||||
- 展示 graphs 概览(通过后端代理设备 agent 的 graphs 数据)
|
||||
|
||||
2) **Graphs**
|
||||
1) **Graphs**
|
||||
|
||||
- Graph 列表(name/running/fps/alarm_total/publish_clients)
|
||||
- 点击某 graph 展开详情(nodes/edges),按后端数据渲染
|
||||
|
||||
3) **Logs**
|
||||
1) **Logs**
|
||||
|
||||
- 最近日志(默认 200 行)
|
||||
- 刷新按钮;(可选)自动刷新开关
|
||||
|
||||
4) **Models**
|
||||
1) **Models**
|
||||
|
||||
- 已上传模型列表(name/sha256/size/mtime/path)
|
||||
- 上传:选择文件 + 填 name(默认用文件名去扩展名)
|
||||
- 上传进度条;成功后自动刷新列表
|
||||
|
||||
5) **Config**
|
||||
1) **Config**
|
||||
|
||||
- JSON 编辑器(Monaco 或轻量 textarea + 格式化按钮)
|
||||
- `Apply` 按钮(调用后端创建任务或直接 apply)
|
||||
- 失败时展示 error,并提示可执行 rollback
|
||||
|
||||
### 5.3 模板/配置生成 `/templates`
|
||||
|
||||
**目标**:减少手写 JSON。
|
||||
|
||||
- 模板列表(后端提供 templates)
|
||||
@ -84,12 +99,15 @@
|
||||
- 点击 Apply:创建任务,跳转任务详情
|
||||
|
||||
### 5.4 任务中心 `/tasks`
|
||||
|
||||
- 任务列表:类型、创建时间、状态(running/success/failed/partial)
|
||||
- 任务详情:每台设备结果(pending/running/success/failed + error)
|
||||
- 实时更新:SSE(EventSource)订阅 `/api/tasks/:id/events`
|
||||
|
||||
## 6. 前端对接 API(本机 managerd)
|
||||
|
||||
前端只调用以下(具体字段见后端 PRD):
|
||||
|
||||
- `POST /api/discovery/search`
|
||||
- `GET /api/devices`
|
||||
- `GET /api/devices/:id`
|
||||
@ -103,6 +121,7 @@
|
||||
- `POST /api/tasks`、`GET /api/tasks/:id`、`GET /api/tasks/:id/events`
|
||||
|
||||
## 7. 验收标准
|
||||
|
||||
1. 可 Search 并展示设备列表,状态正确。
|
||||
2. 设备详情可查看 graphs、logs,且 reload/rollback 可用。
|
||||
3. 可上传模型并在 Models 列表看到。
|
||||
@ -1,6 +1,7 @@
|
||||
# PRD ③ 管理端后端(Go managerd)V1
|
||||
|
||||
## 1. 目标与运行方式
|
||||
|
||||
- 提供本机 HTTP API 给 React UI 使用。
|
||||
- 负责 UDP 广播发现(Option A),维护设备缓存与在线状态。
|
||||
- 通过设备端 `rk3588-agent` 完成配置/模型等运维操作,并可通过 agent 代理读取 graphs/logs。
|
||||
@ -9,6 +10,7 @@
|
||||
运行:单可执行 `managerd`,默认监听 `127.0.0.1:18080`(可配置)。
|
||||
|
||||
## 2. 外部依赖与约束
|
||||
|
||||
- Go 版本:>= 1.22(建议)
|
||||
- 标准库优先;Web 框架可选 `chi`/`gin`(建议 chi + net/http)。
|
||||
- 不需要数据库(V1 用内存 + 可选本地 JSON 持久化)。
|
||||
@ -16,17 +18,20 @@
|
||||
## 3. 模块划分
|
||||
|
||||
### 3.1 Discovery
|
||||
|
||||
- 向所有可用网卡的广播地址发送 UDP discover。
|
||||
- 监听本地 UDP socket 收集 replies(时间窗默认 1200ms)。
|
||||
- 去重规则:按 `device_id` 去重,以最新 reply 为准。
|
||||
|
||||
### 3.2 Device Registry
|
||||
|
||||
- 内存缓存:
|
||||
- `device_id -> {ip, agent_port, media_port, device_name, version, git_sha, last_seen_ms, online}`
|
||||
- 定时刷新(可配置间隔):对 online 设备拉取 `GET /v1/graphs`(agent 代理),更新摘要。
|
||||
- Offline 规则:超过 `offline_after_ms`(如 10000ms)未见到,则标记离线。
|
||||
|
||||
### 3.3 Device Client
|
||||
|
||||
- 统一超时:connect 1s、overall 3s(可配置)。
|
||||
- 统一错误包装:返回 `error_code + message + device_id`。
|
||||
- Token:
|
||||
@ -34,12 +39,14 @@
|
||||
- 可预留 per-device token(P1)
|
||||
|
||||
### 3.4 Templates/Config Builder
|
||||
|
||||
- 模板库来源:
|
||||
- V1:managerd 内置(embed)或本地 `templates/` 目录读取
|
||||
- 返回前端表单 schema:V1 允许手工维护(避免解析占位符带来的不确定性)。
|
||||
- 生成 root config:基于模板与 params,产出 `{global,templates,instances}`。
|
||||
|
||||
### 3.5 Task Runner
|
||||
|
||||
- 任务类型:
|
||||
- `config_apply`(对 N 台设备下发 config)
|
||||
- `reload`
|
||||
@ -52,28 +59,39 @@
|
||||
## 4. managerd 对前端 API 规格(V1)
|
||||
|
||||
### 4.1 Discovery
|
||||
|
||||
#### `POST /api/discovery/search`
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{ "timeout_ms": 1200 }
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{ "items": [ {"device_id":"...","ip":"...","agent_port":9100,"media_port":9000,"device_name":"...","version":"...","git_sha":"..."} ] }
|
||||
```
|
||||
|
||||
### 4.2 Devices
|
||||
|
||||
#### `GET /api/devices`
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{ "items": [ {"device_id":"...","online":true,"last_seen_ms":0,"ip":"...","agent_port":9100,"media_port":9000,"device_name":"...","version":"...","git_sha":"...","graphs":[...]} ] }
|
||||
```
|
||||
|
||||
#### `GET /api/devices/:id`
|
||||
|
||||
Response:包含 `info`、`graphs_summary`、`last_seen`。
|
||||
|
||||
### 4.3 Device actions(代理调用)
|
||||
|
||||
以下全部通过 agent:
|
||||
|
||||
- `POST /api/devices/:id/reload` → agent `POST /v1/media-server/reload`
|
||||
- `POST /api/devices/:id/rollback` → agent `POST /v1/media-server/rollback`
|
||||
- `GET /api/devices/:id/graphs` → agent `GET /v1/graphs`
|
||||
@ -81,28 +99,39 @@ Response:包含 `info`、`graphs_summary`、`last_seen`。
|
||||
- `GET /api/devices/:id/logs?limit=200` → agent `GET /v1/logs/recent?limit=200`
|
||||
|
||||
### 4.4 Config apply
|
||||
|
||||
#### `POST /api/devices/:id/config/apply`
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{ "config": { } }
|
||||
```
|
||||
|
||||
Behavior:调用 agent `PUT /v1/config`。
|
||||
|
||||
### 4.5 Model upload
|
||||
|
||||
#### `POST /api/devices/:id/models/upload`
|
||||
|
||||
Request:`multipart/form-data`,字段:
|
||||
|
||||
- `name`: string
|
||||
- `file`: binary
|
||||
|
||||
Behavior:读取文件流,转发为 agent `PUT /v1/models/{name}`(raw body)。
|
||||
|
||||
### 4.6 Templates
|
||||
|
||||
- `GET /api/templates`
|
||||
- `GET /api/templates/:name`
|
||||
|
||||
### 4.7 Tasks
|
||||
|
||||
#### `POST /api/tasks`
|
||||
|
||||
Request:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "config_apply",
|
||||
@ -110,25 +139,32 @@ Request:
|
||||
"payload": { "config": {} }
|
||||
}
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{ "task_id": "..." }
|
||||
```
|
||||
|
||||
#### `GET /api/tasks/:id/events` (SSE)
|
||||
|
||||
Event `device_update` data:
|
||||
|
||||
```json
|
||||
{ "device_id":"...","status":"running|success|failed","progress":0.0,"error":"" }
|
||||
```
|
||||
|
||||
## 5. 错误处理规范(managerd → 前端)
|
||||
|
||||
- 成功:2xx + `{"ok":true}` 或正常业务 JSON
|
||||
- 失败:4xx/5xx +
|
||||
|
||||
```json
|
||||
{ "error": { "code": "...", "message": "...", "device_id": "...", "detail": "..." } }
|
||||
```
|
||||
|
||||
建议错误码:
|
||||
|
||||
- `DISCOVERY_FAILED`
|
||||
- `DEVICE_NOT_FOUND`
|
||||
- `DEVICE_OFFLINE`
|
||||
@ -138,7 +174,9 @@ Event `device_update` data:
|
||||
- `VALIDATION_ERROR`
|
||||
|
||||
## 6. 配置文件(managerd)建议
|
||||
|
||||
`managerd.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"listen": "127.0.0.1:18080",
|
||||
@ -151,6 +189,7 @@ Event `device_update` data:
|
||||
```
|
||||
|
||||
## 7. 验收标准
|
||||
|
||||
1. Search 可发现设备并更新 registry;离线判断正确。
|
||||
2. 可通过 agent 读取 graphs/logs(`GET /v1/graphs`、`GET /v1/logs/recent`)。
|
||||
3. 单设备 `config/apply`、`reload`、`rollback` 可用,错误可定位。
|
||||
@ -3,6 +3,7 @@
|
||||
> 适用版本:V1(2026-01)
|
||||
>
|
||||
> 范围:**仅控制端 GUI/managerd 如何调用设备端 rk3588-agent**。
|
||||
>
|
||||
> - 本项目中已在 `agent + media-server` 实现本文档所需能力。
|
||||
> - **不包含**配置程序(前端/后端)具体 UI 代码实现细节。
|
||||
|
||||
@ -36,15 +37,18 @@
|
||||
## 3. 鉴权与错误处理
|
||||
|
||||
### 3.1 鉴权
|
||||
|
||||
- Header:`X-RK-Token: <token>`
|
||||
- 写接口(会写盘/改状态)必须鉴权。
|
||||
- 读接口默认可不鉴权;若设备端配置 `agent.require_token_for_read=true`,则读接口也必须鉴权。
|
||||
|
||||
### 3.2 统一错误返回
|
||||
|
||||
- 成功:`2xx`,一般为 `{"ok":true,...}` 或业务 JSON
|
||||
- 失败:`4xx/5xx`,返回 `{"error":"..."}`
|
||||
|
||||
常见 HTTP:
|
||||
|
||||
- `401`:unauthorized
|
||||
- `400`:validation failed / invalid json
|
||||
- `404`:not found
|
||||
@ -56,6 +60,7 @@
|
||||
## 4. GUI 页面与调用流程
|
||||
|
||||
### 4.1 设备详情页(只读)
|
||||
|
||||
1) 设备信息:`GET /v1/info`
|
||||
2) 运行态通道摘要:`GET /v1/graphs`
|
||||
3) 单通道详情(可选):`GET /v1/graphs/{name}`
|
||||
@ -64,16 +69,20 @@
|
||||
### 4.2 通道配置页(核心:instances)
|
||||
|
||||
#### 4.2.1 初始化
|
||||
|
||||
1) 获取 schema(渲染表单):`GET /v1/config/ui/schema`
|
||||
2) 获取当前 state(回显):`GET /v1/config/ui/state`
|
||||
|
||||
GUI 侧以 `instances[]` 为“通道列表”。
|
||||
|
||||
#### 4.2.2 校验/预览(dry-run)
|
||||
|
||||
用户编辑完成后:
|
||||
|
||||
- `POST /v1/config/ui/plan`
|
||||
|
||||
返回:
|
||||
|
||||
- `generated_config`:生成出来的 root config(可用于预览/导出)
|
||||
- `diff`:added/removed/changed(实例级别)
|
||||
|
||||
@ -81,15 +90,18 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
> 真正的构图/插件/模型加载等校验发生在 apply → media-server reload 阶段。
|
||||
|
||||
#### 4.2.3 应用配置
|
||||
|
||||
- `POST /v1/config/ui/apply`
|
||||
|
||||
行为:
|
||||
|
||||
1) agent 生成新的 root config(只包含 `global/queue/templates/instances`)
|
||||
2) 写盘到 `agent.config_path`
|
||||
3) 调用 media-server reload
|
||||
4) reload 失败则自动 rollback 并返回 500
|
||||
|
||||
#### 4.2.4 回滚(手动)
|
||||
|
||||
- `POST /v1/media-server/rollback`
|
||||
|
||||
> 回滚语义:回滚到“上一次成功的**源配置**”(保留 templates/instances,不会被 expanded 覆盖),便于 GUI 二次编辑。
|
||||
@ -97,6 +109,7 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
### 4.3 人脸库管理页
|
||||
|
||||
#### 4.3.1 上传人脸库
|
||||
|
||||
- `PUT /v1/face-gallery`
|
||||
- Content-Type:`application/octet-stream`
|
||||
- Body:SQLite 文件二进制(`face_gallery.db`)
|
||||
@ -104,9 +117,11 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
保存位置:`<agent.models_dir>/face_gallery.db`
|
||||
|
||||
#### 4.3.2 立即生效(无需重启)
|
||||
|
||||
- `POST /v1/face-gallery/reload`
|
||||
|
||||
行为:
|
||||
|
||||
- agent 遍历所有 graphs,找到 `type==ai_face_recog` 的节点
|
||||
- 对每个节点下发 runtime config patch:bump `gallery.reload_seq`
|
||||
- 节点收到后会重新加载 SQLite db
|
||||
@ -118,49 +133,69 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
> Base:`http://<device_ip>:<agent_port>`(默认 9100)
|
||||
|
||||
### 5.1 设备信息
|
||||
|
||||
#### `GET /v1/info`
|
||||
|
||||
用于设备列表/详情。
|
||||
|
||||
### 5.2 运行态(只读代理)
|
||||
|
||||
#### `GET /v1/graphs`
|
||||
|
||||
#### `GET /v1/graphs/{name}`
|
||||
|
||||
#### `GET /v1/logs/recent?limit=200`
|
||||
|
||||
### 5.3 配置文件(root config)
|
||||
|
||||
#### `GET /v1/config`
|
||||
|
||||
返回 `agent.config_path` 对应 JSON(用于导出/高级查看)。
|
||||
|
||||
#### `PUT /v1/config`
|
||||
|
||||
上传完整 root config JSON(写盘 + reload;失败自动 rollback)。
|
||||
|
||||
### 5.4 语义化配置(GUI 推荐使用)
|
||||
|
||||
#### `GET /v1/config/ui/schema`
|
||||
|
||||
返回:可选模板列表 + 字段 schema(类型/默认/必填)。
|
||||
|
||||
#### `GET /v1/config/ui/state`
|
||||
|
||||
返回:当前 config 映射到 GUI state(主要是 `instances[]`)+ 内置模板列表。
|
||||
|
||||
#### `POST /v1/config/ui/plan`
|
||||
|
||||
输入 desired state(instances 列表),返回生成 config 与 diff。
|
||||
|
||||
#### `POST /v1/config/ui/apply`
|
||||
|
||||
同 plan,但会写盘并 reload(失败自动 rollback)。
|
||||
|
||||
### 5.5 模型管理(可选,但建议 GUI 支持)
|
||||
|
||||
#### `PUT /v1/models/{name}`
|
||||
|
||||
上传模型(.rknn),返回可引用的 `path`。
|
||||
|
||||
#### `GET /v1/models`
|
||||
|
||||
列出已上传模型(包含 `name/path/sha256/mtime_ms`)。
|
||||
|
||||
### 5.6 人脸库
|
||||
|
||||
#### `GET /v1/face-gallery`
|
||||
|
||||
返回当前 db 文件信息(exists/size/mtime/path)。
|
||||
|
||||
#### `PUT /v1/face-gallery`
|
||||
|
||||
上传 `face_gallery.db`。
|
||||
|
||||
#### `POST /v1/face-gallery/reload`
|
||||
|
||||
让所有 `ai_face_recog` 节点热加载新 db。
|
||||
|
||||
---
|
||||
@ -198,6 +233,7 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `global/queue` 可省略:agent 会沿用当前 config 中的值。
|
||||
- `instances` 为全量期望状态:控制端应把当前列表 + 修改后的列表一起提交。
|
||||
- 当前实现会生成新的 root config(只包含 `global/queue/templates/instances`),不会保留 `graphs`。
|
||||
@ -220,20 +256,25 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
> 模板名来自 `GET /v1/config/ui/schema` 的 `templates[]`。
|
||||
|
||||
### 7.1 `transcode_rtsp_hls`
|
||||
|
||||
- 必填:`url`
|
||||
- 常用:`fps,src_w,src_h,gop,bitrate_kbps,rtsp_port,hls_path`
|
||||
|
||||
### 7.2 `yolo_rtsp_hls`
|
||||
|
||||
- 必填:`url, model_path`
|
||||
|
||||
### 7.3 `yolo_alarm_minio`
|
||||
|
||||
- 必填:`url, model_path, minio_endpoint, minio_bucket, minio_ak, minio_sk`
|
||||
- 常用:`cooldown_ms`(默认 3000)
|
||||
|
||||
### 7.4 `face_det_rtsp_hls`
|
||||
|
||||
- 必填:`url, det_model_path`
|
||||
|
||||
### 7.5 `face_det_recog_rtsp_hls`
|
||||
|
||||
- 必填:`url, det_model_path, recog_model_path`
|
||||
- 默认:`gallery_path=./models/face_gallery.db`,`thr_accept=0.45`,`thr_margin=0.05`
|
||||
|
||||
@ -242,6 +283,7 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
## 8. 性能调优参数(可选,建议 GUI 以“高级设置”方式暴露)
|
||||
|
||||
### 8.1 `preprocess`(AI 分支减拷贝 / RGA 并发)
|
||||
|
||||
- `dst_packed`:bool,默认 `false`。
|
||||
- 说明:当 `dst_format` 为 `rgb/bgr` 时,若开启则输出紧凑 packed(`stride = width * 3`),可避免下游(如 `ai_yolo`)对齐 stride 导致的逐行 memcpy。
|
||||
- `rga_max_inflight`:int,默认 `0`(表示不在配置里覆盖全局值)。
|
||||
@ -249,12 +291,14 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
- 备注:也可通过环境变量 `RK3588_RGA_MAX_INFLIGHT` 设置。
|
||||
|
||||
### 8.2 `publish/storage`(一次编码,多处复用)
|
||||
|
||||
- `publish.attach_encoded_meta`:bool,默认 `true`(当 publish 有下游 output_queues 时)。
|
||||
- 说明:将已编码视频包(含 codec extradata/pts/key)挂在 `frame.user_meta`,供下游复用(例如报警 clip、storage 复用码流)。
|
||||
- `storage.reuse_encoded_meta`:bool,默认 `true`。
|
||||
- 说明:若收到 `EncodedVideoFrameMeta`,storage 将直接 remux 写文件(避免再次 MPP 编码);若未收到则保持原逻辑(MPP 编码录制)。
|
||||
|
||||
### 8.3 推理并发(环境变量,部署侧配置)
|
||||
|
||||
- `RK3588_RKNN_CTX_POOL_SIZE`:默认 `3`。
|
||||
- 说明:同一模型创建的 RKNN context 数量(多路同模型推理可并发,避免被单 context 串行化)。
|
||||
|
||||
@ -263,11 +307,13 @@ GUI 侧以 `instances[]` 为“通道列表”。
|
||||
## 9. 人脸库路径对齐建议(避免“上传了但识别不到”)
|
||||
|
||||
1) 默认推荐(最省事):
|
||||
|
||||
- media-server work_dir:`/opt/rk3588sys`
|
||||
- agent.models_dir:`/opt/rk3588sys/models`
|
||||
- ai_face_recog.gallery.path:`./models/face_gallery.db`
|
||||
|
||||
2) 若你们的 work_dir/models_dir 不是这种关系:
|
||||
1) 若你们的 work_dir/models_dir 不是这种关系:
|
||||
|
||||
- 控制端在 instances params 里把 `gallery_path` 设置为**绝对路径**(例如 `/opt/rk3588sys/models/face_gallery.db`)。
|
||||
|
||||
---
|
||||
@ -1,30 +1,37 @@
|
||||
# PRD_05:Device 侧轻量级 Tracker 节点(可插拔)
|
||||
|
||||
## 1. 背景与问题
|
||||
|
||||
当前 Device 侧媒体服务采用“配置驱动 DAG(Graph)+ 插件节点(Node)+ SPSC 队列”的流水线架构:输入(RTSP/文件)→ 预处理 → AI 推理(检测/识别等)→ OSD/推流/告警。
|
||||
|
||||
在实际部署中常见三类痛点:
|
||||
|
||||
1) **重复报警**:同一目标在画面连续出现时,规则可能在采样频率下重复触发。
|
||||
2) **重复上传(MinIO/HTTP 等)**:报警动作触发后在短时间内重复上传同类素材。
|
||||
3) **推理开销过高**:虽然已有 `infer_fps` 等限频,但在低推理频率下希望仍保持事件稳定性与可解释性。
|
||||
|
||||
现有代码中:
|
||||
|
||||
- `Frame::det`(`DetectionResult`)包含 `Detection{cls_id, score, bbox, track_id}`,其中 `track_id` 当前默认 `-1`(未做追踪)。
|
||||
- `alarm` 侧已有 `rules.cooldown_ms`、`min_duration_ms` 与 `actions.*.min_interval_ms` 的时间窗限流,但属于“按规则/动作的时间窗”粒度。
|
||||
|
||||
## 2. 目标(Goals)
|
||||
|
||||
提供一个 **可选、可插拔** 的 `tracker` 插件节点,用于为检测结果补充稳定的 `track_id`,以支持:
|
||||
|
||||
1) **按目标实例去重**(基于 `track_id`):同一目标在持续存在期间不重复触发/上传。
|
||||
2) **稳定性/精准性优先,资源占用尽可能低**:不引入 ReID/特征网络,主要使用几何与置信度关联。
|
||||
3) **按类别选择性追踪**:并非所有类别都追踪,可由配置指定哪些 `cls_id` 参与追踪。
|
||||
4) **架构适配**:完全符合现有 Graph/Node 插件机制,插入与否由 `configs/*.json` 决定;不插入则不改变任何行为。
|
||||
|
||||
## 3. 非目标(Non-Goals)
|
||||
|
||||
1) 不做跨摄像头/跨 Graph 的关联(不做全局 ID)。
|
||||
2) 不做基于外观特征(ReID)的强一致性追踪(如 DeepSORT+ReID)。
|
||||
3) 不保证对极端遮挡/快速运动/密集重叠场景达到 SOTA 跟踪指标;本 PRD 目标是“工程可用+低资源”。
|
||||
|
||||
## 4. 现有架构约束(必须遵守)
|
||||
|
||||
1) Node 单输入、多输出:Graph 当前限制每个节点 **只能有一个 input queue**。
|
||||
2) Node 的 `Process(FramePtr)` 由框架线程调用(`Graph::Start()` 中的 worker loop),Tracker 节点不应引入额外线程(除非明确需求)。
|
||||
3) Tracker 节点不得破坏 `Frame` 上其他元信息(尤其是 `publish` 节点可能写入 `frame->user_meta` 用于 clip)。
|
||||
@ -32,6 +39,7 @@
|
||||
## 5. 功能设计
|
||||
|
||||
### 5.1 节点定义
|
||||
|
||||
- Node type:`tracker`
|
||||
- role:`filter`
|
||||
- 输入:`FramePtr`(读取 `frame->det`)
|
||||
@ -39,43 +47,54 @@
|
||||
- 当 `frame->det == nullptr` 或 `items` 为空:直接透传。
|
||||
|
||||
### 5.2 追踪算法(推荐:ByteTrack-lite + IOU 关联)
|
||||
|
||||
在不引入外观特征的前提下,为提高稳定性,采用“两段式关联”策略:
|
||||
|
||||
**核心思想**:
|
||||
|
||||
1) 将 det 按置信度分成高置信(`score >= high_th`)与低置信(`low_th <= score < high_th`)。
|
||||
2) 优先用高置信 det 去匹配已有 tracks;未匹配的 tracks 再用低置信 det 做二次匹配(减少断轨)。
|
||||
3) 匹配度量使用 IOU(可加入 gating:中心点距离/面积比等轻量约束)。
|
||||
|
||||
**匹配策略**:
|
||||
|
||||
- 为降低资源占用:默认使用 greedy matching(按 IOU 从高到低选择不冲突匹配),不强制使用匈牙利算法。
|
||||
- 允许后续通过配置切换到 Hungarian(可选增强项),但不作为本 PRD 必需。
|
||||
|
||||
**Track 生命周期**:
|
||||
|
||||
- 创建:未匹配到现有 track 的高置信 det → 创建新 track。
|
||||
- 更新:匹配成功 → 更新 bbox、last_seen、hit_streak。
|
||||
- 丢失:超过 `max_age_ms`(或 `max_age_frames`)未匹配 → 删除。
|
||||
|
||||
**分类策略**:
|
||||
|
||||
- 默认按 `cls_id` 分组匹配(避免不同类别互相抢 track)。
|
||||
- 可配置 `per_class=false` 以允许跨类别匹配(默认不建议)。
|
||||
|
||||
### 5.3 按类别选择性追踪
|
||||
|
||||
支持以下配置(至少实现其一,推荐两者都实现):
|
||||
|
||||
- `track_classes`: `int[]`:白名单。非空时仅追踪这些 `cls_id`。
|
||||
- `ignore_classes`: `int[]`:黑名单。用于排除某些 `cls_id`。
|
||||
|
||||
规则:
|
||||
|
||||
- 若 `track_classes` 非空,则优先按白名单过滤。
|
||||
- 否则按 `ignore_classes` 排除。
|
||||
- 未参与追踪的 det 必须保持 `track_id = -1`。
|
||||
|
||||
### 5.4 按模型类型/推理类型启用(可选,但推荐)
|
||||
|
||||
`DetectionResult.model_name` 已存在,Tracker 支持:
|
||||
|
||||
- `allowed_models`: `string[]`:当非空时,仅对 `model_name` 在集合内的帧启用。
|
||||
|
||||
用途:同一 pipeline 可能挂多种推理节点(yolo/face_det/自定义模型),避免对不需要的输出做追踪。
|
||||
|
||||
### 5.5 插入位置建议(不强制)
|
||||
|
||||
1) 仅为“告警去重/上传去重”服务:
|
||||
- 推荐 `publish -> tracker -> alarm`
|
||||
- 原因:不影响推流;不破坏 `publish` 写入的 `frame->user_meta`(clip 仍可用)。
|
||||
@ -83,8 +102,11 @@
|
||||
- 推荐 `ai_* -> tracker -> osd -> ...`
|
||||
|
||||
## 6. 配置(Config Schema)
|
||||
|
||||
### 6.1 tracker 节点配置字段
|
||||
|
||||
节点 JSON 示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "trk_cam1",
|
||||
@ -113,6 +135,7 @@
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
- `mode`:`"off" | "bytetrack_lite"`(最少实现这两种)
|
||||
- `per_class`:默认 `true`。
|
||||
- `track_classes`:白名单;默认空(表示全类别)。
|
||||
@ -125,7 +148,9 @@
|
||||
- `max_tracks`:上限保护,避免极端场景内存增长。
|
||||
|
||||
### 6.2 Graph 接入示例
|
||||
|
||||
在现有 graph 中插入(示例:`pub -> tracker -> alarm`):
|
||||
|
||||
```json
|
||||
"nodes": [
|
||||
{"id":"pub_cam1","type":"publish","role":"filter","enable":true, ...},
|
||||
@ -140,7 +165,9 @@
|
||||
```
|
||||
|
||||
## 7. 对外接口与数据契约
|
||||
|
||||
### 7.1 输入输出契约
|
||||
|
||||
- 输入:`frame->det` 必须由上游检测节点填充;Tracker 不负责生成 det。
|
||||
- 输出:
|
||||
- `frame` 本体不变;
|
||||
@ -148,12 +175,16 @@
|
||||
- 不修改 `frame->user_meta`、不修改 `frame->data/planes`。
|
||||
|
||||
### 7.2 与 alarm/http/minio 的配合
|
||||
|
||||
- `plugins/alarm/actions/http_action.cpp` 已会输出 `track_id` 字段(现有实现),因此 Tracker 生效后 HTTP 报警可以自然携带 `track_id`。
|
||||
- MinIO 上传去重当前依赖 `actions.*.min_interval_ms`;后续可扩展为 per-track 去重(见第 10 节增强建议)。
|
||||
|
||||
## 8. 指标与可观测性
|
||||
|
||||
### 8.1 Custom Metrics
|
||||
|
||||
Tracker 节点建议实现 `GetCustomMetrics()` 输出:
|
||||
|
||||
- `tracks_active`
|
||||
- `tracks_created_total`
|
||||
- `tracks_removed_total`
|
||||
@ -162,15 +193,19 @@ Tracker 节点建议实现 `GetCustomMetrics()` 输出:
|
||||
- `avg_process_time_ms`
|
||||
|
||||
### 8.2 Debug
|
||||
|
||||
- `debug.stats`:周期打印关键统计。
|
||||
- 不输出过多 per-frame 日志,避免影响实时性。
|
||||
|
||||
## 9. 性能与资源约束
|
||||
|
||||
目标(以单路为单位,具体需实测校准):
|
||||
|
||||
- `N_det <= 64` 时,每帧 Tracker 处理耗时应为毫秒级以下(通常 < 1ms,依平台不同)。
|
||||
- 内存:track 状态结构固定上限 `max_tracks`,避免无界增长。
|
||||
|
||||
## 10. 验收标准(Acceptance Criteria)
|
||||
|
||||
1) **可插拔**:不配置 `tracker` 节点时,系统行为与当前版本一致。
|
||||
2) **正确写入 track_id**:配置启用时,目标类别的 det `track_id` 在连续帧中稳定且可复用。
|
||||
3) **按类别控制有效**:不在白名单/在黑名单的 `cls_id` 必须保持 `track_id=-1`。
|
||||
@ -178,6 +213,7 @@ Tracker 节点建议实现 `GetCustomMetrics()` 输出:
|
||||
5) **资源可控**:`max_tracks` 生效;极端场景不会导致内存持续增长。
|
||||
|
||||
## 11. 开发拆解(实现步骤)
|
||||
|
||||
1) 新增插件目录与编译接入:`plugins/tracker/`,更新 `plugins/CMakeLists.txt` 注册编译。
|
||||
2) 实现 `TrackerNode`:
|
||||
- `Init()` 解析配置。
|
||||
@ -187,6 +223,7 @@ Tracker 节点建议实现 `GetCustomMetrics()` 输出:
|
||||
3) 增加一个示例配置(不强制提交到 README):可在现有 `configs/*` 中添加一份测试 json(若产品流程允许)。
|
||||
|
||||
## 12. 增强建议(不属于本 PRD 必做,但推荐路线)
|
||||
|
||||
1) **Alarm 去重升级为 per-track**:在 `alarm` 节点内部维护 `(rule_name, track_id)` 的冷却/状态机(enter/stay/leave)。
|
||||
2) **自适应推理频率**:结合最近 N 秒的命中情况动态调整 `infer_fps`(需与现有热更新机制配合)。
|
||||
3) **Hungarian 可选开关**:当 det 数量大且遮挡多时提升一致性,但要评估 CPU 成本。
|
||||
@ -1,25 +1,31 @@
|
||||
# PRD_06 多硬件解耦计划(RK3588/Atlas/Jetson)
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
当前工程深度绑定 RK3588(RKNN/RGA/MPP/DMA-BUF),限制了 Atlas、Jetson 等平台的接入。目标是在**不破坏现有功能**的前提下,通过接口解耦与默认实现保留现有行为,实现多硬件可插拔支持。
|
||||
|
||||
### 目标
|
||||
|
||||
- 以接口层抽象 **推理、图像处理、编解码、缓冲区** 四个核心模块。
|
||||
- 默认实现保持 RK3588 行为与性能路径(零拷贝/DMA-BUF)。
|
||||
- 逐步迁移现有节点,避免一次性大改。
|
||||
|
||||
### 非目标
|
||||
|
||||
- 不改变业务逻辑(检测/识别流程、RTSP/HLS 业务)。
|
||||
- 不在本阶段引入新 UI/协议或跨平台发布流程。
|
||||
|
||||
## 2. 现状摘要(关键路径)
|
||||
|
||||
- 推理:`include/ai_scheduler.h`, `src/ai_scheduler.cpp`(RKNN + DMA-BUF 输入)
|
||||
- 图像处理:`plugins/preprocess/preprocess_node.cpp`(RGA 或 swscale)
|
||||
- 编解码:`plugins/input_rtsp/*`, `plugins/input_file/*`, `plugins/publish/*`(MPP + FFmpeg 混用)
|
||||
- 缓冲:`include/frame/frame.h`(dma_fd/planes/data_owner)
|
||||
|
||||
## 3. 总体方案
|
||||
|
||||
引入四类接口与默认实现:
|
||||
|
||||
- **IInferBackend**:推理后端抽象(默认 RKNN)
|
||||
- **IImageProcessor**:图像预处理抽象(默认 RGA + swscale 兜底)
|
||||
- **IDecoder / IEncoder**:编解码抽象(默认 MPP,必要时 FFmpeg)
|
||||
@ -30,7 +36,9 @@
|
||||
## 4. 实施步骤、里程碑与单元测试
|
||||
|
||||
### Step 1:建立基础抽象与工厂
|
||||
|
||||
**实施内容**
|
||||
|
||||
- 新建 `include/hw/` 下接口定义:`i_infer_backend.h`, `i_image_processor.h`, `i_decoder.h`, `i_encoder.h`, `frame_buffer.h`
|
||||
- 定义最小能力集:
|
||||
- IInferBackend: `LoadModel`, `Infer`, `InferBorrowed`
|
||||
@ -40,58 +48,72 @@
|
||||
- 新建工厂:`hw_factory.h/cpp`,根据配置返回默认实现
|
||||
|
||||
**关键里程碑**
|
||||
|
||||
- 接口头文件编译通过;工程无行为变化
|
||||
- 工厂默认返回 RK3588 实现(空实现也可先用占位)
|
||||
|
||||
**单元测试(GTest)**
|
||||
|
||||
- `HwFactory_Defaults_ReturnsRk3588Impls`
|
||||
- `FrameBuffer_Metadata_Preserved`(dma_fd/planes 赋值一致性)
|
||||
|
||||
---
|
||||
|
||||
### Step 2:推理模块解耦(RKNN → IInferBackend)
|
||||
|
||||
**实施内容**
|
||||
|
||||
- 将 `AiScheduler` 包装为 `RknnInferBackend` 实现
|
||||
- `ai_*` 节点依赖 `IInferBackend` 接口注入(保留默认行为)
|
||||
- 保留 `InferBorrowed` 以支持零拷贝输入
|
||||
|
||||
**关键里程碑**
|
||||
|
||||
- 现有模型推理链路无回归,性能基准一致(同配置)
|
||||
- RKNN 仍可多上下文并发
|
||||
|
||||
**单元测试(GTest)**
|
||||
|
||||
- `InferBackend_LoadModel_Smoke`(加载模型返回成功)
|
||||
- `InferBackend_BorrowedInput_UsesDmaFd`(检查传入 dma_fd 路径被调用)
|
||||
|
||||
---
|
||||
|
||||
### Step 3:图像预处理解耦(RGA/CPU → IImageProcessor)
|
||||
|
||||
**实施内容**
|
||||
|
||||
- 抽取 RGA 路径为 `RgaImageProcessor`
|
||||
- 抽取 swscale 路径为 `SwscaleImageProcessor`
|
||||
- `preprocess_node` 仅面向接口调用
|
||||
|
||||
**关键里程碑**
|
||||
|
||||
- `use_rga=true/false` 行为完全一致
|
||||
- RGA 限流逻辑(RgaGate)保留
|
||||
|
||||
**单元测试(GTest)**
|
||||
|
||||
- `ImageProcessor_RgaVsSwscale_OutputShape`(输出尺寸一致)
|
||||
- `ImageProcessor_ColorConversion_Nv12ToRgb`(像素格式转换)
|
||||
|
||||
---
|
||||
|
||||
### Step 4:编解码解耦(MPP/FFmpeg → IDecoder/IEncoder)
|
||||
|
||||
**实施内容**
|
||||
|
||||
- `MppDecoder`, `FfmpegDecoder` 实现 `IDecoder`
|
||||
- `MppEncoder`, `FfmpegEncoder` 实现 `IEncoder`
|
||||
- `input_rtsp/input_file/publish/storage` 节点仅面向接口
|
||||
|
||||
**关键里程碑**
|
||||
|
||||
- RTSP 输入与 HLS 输出链路不变
|
||||
- MPP 仍为默认路径,FFmpeg 作为兜底/平台适配
|
||||
|
||||
**单元测试(GTest)**
|
||||
|
||||
- `Decoder_Open_Close_Smoke`
|
||||
- `Encoder_Open_Close_Smoke`
|
||||
- `Codec_Pipeline_EncodeDecode_OneFrame`(小尺寸样例帧)
|
||||
@ -99,47 +121,59 @@
|
||||
---
|
||||
|
||||
### Step 5:缓冲区抽象(Frame → FrameBuffer)
|
||||
|
||||
**实施内容**
|
||||
|
||||
- 新增 `FrameBuffer`,替代直接使用 `Frame` 的 dma_fd/data_owner
|
||||
- `Frame` 保留为业务结构,内部持有 `FrameBuffer`
|
||||
- 统一 DMA 同步接口以便多硬件适配
|
||||
|
||||
**关键里程碑**
|
||||
|
||||
- DMA-BUF 与内存缓冲区均可通过统一接口访问
|
||||
- `Frame` 兼容旧字段,最小侵入替换完成
|
||||
|
||||
**单元测试(GTest)**
|
||||
|
||||
- `FrameBuffer_Sync_NoCrash`
|
||||
- `FrameBuffer_PlaneAccess_Consistent`
|
||||
|
||||
---
|
||||
|
||||
### Step 6:多硬件适配接入(Atlas/Jetson)
|
||||
|
||||
**实施内容**
|
||||
|
||||
- 新增 `AtlasInferBackend/AtlasImageProcessor/AtlasCodec` 实现(占位/实验性)
|
||||
- 新增 `JetsonInferBackend/JetsonImageProcessor/JetsonCodec` 实现
|
||||
- 通过配置切换平台实现
|
||||
|
||||
**关键里程碑**
|
||||
|
||||
- 不影响 RK3588 默认路径
|
||||
- 新平台可在单机完成 smoke 测试
|
||||
|
||||
**单元测试(GTest)**
|
||||
|
||||
- `HwFactory_SelectsBackend_ByConfig`
|
||||
- `PlatformImpls_Smoke_Construct`(构造/释放)
|
||||
|
||||
## 5. 风险与缓解
|
||||
|
||||
- **接口过宽导致迁移成本增加** → 控制最小接口集,逐步扩展
|
||||
- **性能回退** → 保留 RK3588 默认实现与 DMA-BUF 快路径
|
||||
- **迁移破坏现有节点** → 节点逐个替换,保持旧路径可回退
|
||||
|
||||
## 6. 验证与回滚
|
||||
|
||||
### 验证命令
|
||||
|
||||
```
|
||||
scripts/build_host.sh
|
||||
ctest --test-dir build/host --output-on-failure
|
||||
```
|
||||
|
||||
### 回滚策略
|
||||
|
||||
- 以编译开关/配置切换回旧路径
|
||||
- 保留 RK3588 实现作为默认后端
|
||||
2
docs/requirements/deploy_requirements.md
Normal file
2
docs/requirements/deploy_requirements.md
Normal file
@ -0,0 +1,2 @@
|
||||
# 部署环境需求
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
|
||||
# 开发和部署所需的命令
|
||||
|
||||
ffmpeg -f dshow -i video="1080P USB Camera" -c:v libx264 -preset ultrafast -pix_fmt yuv420p -f rtsp rtsp://localhost:8554/cam
|
||||
|
||||
@ -19,9 +19,6 @@
|
||||
|
||||
cmake --build build -j$(nproc)
|
||||
|
||||
|
||||
|
||||
|
||||
//退出
|
||||
pidof media-server
|
||||
|
||||
@ -29,19 +26,16 @@
|
||||
|
||||
ss -lntp | grep ':9000'
|
||||
|
||||
|
||||
http://10.0.0.81:9000/hls/cam1/index.m3u8
|
||||
<http://10.0.0.81:9000/hls/cam1/index.m3u8>
|
||||
|
||||
rtsp://10.0.0.81:8555/live/cam1
|
||||
|
||||
|
||||
D:\minio\bin>minio.exe server D:\minio\data --address ":9000" --console-address ":9001"
|
||||
|
||||
//生成人脸模型
|
||||
|
||||
python build_gallery.py --dataset "D:\App\python\AddFaceTo3588\faces\dataset" --db_out "D:\App\python\AddFaceTo3588\faces\face_gallery.db" --det_model "D:\App\python\AddFaceTo3588\models\RetinaFace_mobile320.onnx" --recog_model "D:\App\python\AddFaceTo3588\models\mobilefacenet_arcface_prenorm.onnx" --det_outputs_config "D:\App\python\AddFaceTo3588\models\retinaface_mobile320_config.json" --det_score_thresh 0.6 --max_imgs_per_person 10 --pick_face largest --min_face_size 80 --expected_dim 512 --fail_on_empty true
|
||||
|
||||
|
||||
编译
|
||||
|
||||
cd /d D:\App\C++\Rk3588Sys\agent
|
||||
@ -101,13 +95,13 @@ ls -l ./rk3588-agent_linux_arm64
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now rk3588-agent
|
||||
|
||||
4) 查看状态与日志
|
||||
1) 查看状态与日志
|
||||
|
||||
sh
|
||||
sudo systemctl status rk3588-agent --no-pager
|
||||
sudo journalctl -u rk3588-agent -f
|
||||
|
||||
5) 停止/重启
|
||||
1) 停止/重启
|
||||
|
||||
sh
|
||||
sudo systemctl stop rk3588-agent
|
||||
@ -116,10 +110,9 @@ ls -l ./rk3588-agent_linux_arm64
|
||||
这样运行后,SSH 断开不会影响进程(由 systemd 托管)。如果你的 agent.config.json 里有相对路径(如 models 目录),记得写成绝对路径,或放到
|
||||
/opt/rk3588-agent/ 并按配置调整。
|
||||
|
||||
## 后端启动命令
|
||||
|
||||
## 后端启动命令
|
||||
go run .\cmd\managerd\main.go .\managerd.json
|
||||
|
||||
|
||||
##查看npu占用
|
||||
sudo watch -n 1 cat /sys/kernel/debug/rknpu/load
|
||||
284
scripts/systemd/Mannual.md
Normal file
284
scripts/systemd/Mannual.md
Normal file
@ -0,0 +1,284 @@
|
||||
# RK3588 Media Server Systemd 集成
|
||||
|
||||
本目录包含 RK3588 Media Server 和 Agent 的 systemd 服务配置和管理脚本。
|
||||
|
||||
## 概述
|
||||
|
||||
| 服务 | 描述 | 默认端口 |
|
||||
|------|------|----------|
|
||||
| `media-server` | C++ 媒体服务器(视频流处理) | 9000 (HTTP), 8554/8555 (RTSP) |
|
||||
| `rk3588-agent` | Go 管理代理(HTTP API) | 9100 |
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 方法一:快速设置(推荐用于开发板)
|
||||
|
||||
如果你已经在 Orange Pi 上编译好项目,直接运行:
|
||||
|
||||
```bash
|
||||
cd /path/to/OrangePi3588Media
|
||||
sudo ./scripts/systemd/quick-setup.sh
|
||||
```
|
||||
|
||||
此脚本会自动:
|
||||
|
||||
1. 检查并编译项目(如需要)
|
||||
2. 安装 systemd 服务
|
||||
3. 启动服务
|
||||
4. 显示访问地址
|
||||
|
||||
### 方法二:手动安装
|
||||
|
||||
```bash
|
||||
cd /path/to/OrangePi3588Media
|
||||
|
||||
# 安装服务
|
||||
sudo ./scripts/systemd/install-systemd.sh
|
||||
|
||||
# 或指定自定义路径
|
||||
sudo ./scripts/systemd/install-systemd.sh \
|
||||
--media-bin ./build/media-server \
|
||||
--media-config ./configs/sample_cam1.json \
|
||||
--agent-bin ./agent/rk3588-agent_linux_arm64 \
|
||||
--agent-config ./agent/agent_cam1.config.json
|
||||
```
|
||||
|
||||
### 方法三:手动步骤(了解细节)
|
||||
|
||||
```bash
|
||||
# 1. 复制服务文件
|
||||
sudo cp scripts/systemd/media-server.service /etc/systemd/system/
|
||||
sudo cp scripts/systemd/rk3588-agent.service /etc/systemd/system/
|
||||
|
||||
# 2. 创建安装目录并复制文件
|
||||
sudo mkdir -p /opt/rk3588-media-server/{bin,lib,etc,logs}
|
||||
sudo cp build/media-server /opt/rk3588-media-server/bin/
|
||||
sudo cp configs/sample_cam1.json /opt/rk3588-media-server/etc/media-server.json
|
||||
|
||||
sudo mkdir -p /opt/rk3588-agent
|
||||
sudo cp agent/rk3588-agent_linux_arm64 /opt/rk3588-agent/rk3588-agent
|
||||
sudo cp agent/agent_cam1.config.json /opt/rk3588-agent/agent.config.json
|
||||
|
||||
# 3. 重载 systemd
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
# 4. 启动并启用服务
|
||||
sudo systemctl enable --now media-server
|
||||
sudo systemctl enable --now rk3588-agent
|
||||
```
|
||||
|
||||
## 服务管理
|
||||
|
||||
### 查看状态
|
||||
|
||||
```bash
|
||||
# 使用便捷脚本
|
||||
./scripts/systemd/status.sh
|
||||
|
||||
# 或手动查看
|
||||
sudo systemctl status media-server
|
||||
sudo systemctl status rk3588-agent
|
||||
|
||||
# 查看 NPU 负载
|
||||
sudo watch -n 1 cat /sys/kernel/debug/rknpu/load
|
||||
```
|
||||
|
||||
### 启动/停止/重启
|
||||
|
||||
```bash
|
||||
# Media Server
|
||||
sudo systemctl start media-server
|
||||
sudo systemctl stop media-server
|
||||
sudo systemctl restart media-server
|
||||
|
||||
# Agent
|
||||
sudo systemctl start rk3588-agent
|
||||
sudo systemctl stop rk3588-agent
|
||||
sudo systemctl restart rk3588-agent
|
||||
|
||||
# 同时重启两者
|
||||
sudo systemctl restart media-server rk3588-agent
|
||||
```
|
||||
|
||||
### 开机自启
|
||||
|
||||
```bash
|
||||
# 启用开机自启
|
||||
sudo systemctl enable media-server
|
||||
sudo systemctl enable rk3588-agent
|
||||
|
||||
# 禁用开机自启
|
||||
sudo systemctl disable media-server
|
||||
sudo systemctl disable rk3588-agent
|
||||
```
|
||||
|
||||
### 查看日志
|
||||
|
||||
```bash
|
||||
# 实时跟踪日志
|
||||
sudo journalctl -u media-server -f
|
||||
sudo journalctl -u rk3588-agent -f
|
||||
|
||||
# 查看最近 100 行
|
||||
sudo journalctl -u media-server -n 100 --no-pager
|
||||
|
||||
# 查看今天的日志
|
||||
sudo journalctl -u media-server --since today
|
||||
|
||||
# 按时间范围查看
|
||||
sudo journalctl -u media-server --since "2024-01-01 10:00:00" --until "2024-01-01 12:00:00"
|
||||
```
|
||||
|
||||
## 配置文件
|
||||
|
||||
### Media Server
|
||||
|
||||
位置: `/opt/rk3588-media-server/etc/media-server.json`
|
||||
|
||||
```bash
|
||||
# 编辑配置
|
||||
sudo nano /opt/rk3588-media-server/etc/media-server.json
|
||||
|
||||
# 验证 JSON 格式
|
||||
python3 -m json.tool /opt/rk3588-media-server/etc/media-server.json
|
||||
|
||||
# 重启生效
|
||||
sudo systemctl restart media-server
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
位置: `/opt/rk3588-agent/agent.config.json`
|
||||
|
||||
```bash
|
||||
sudo nano /opt/rk3588-agent/agent.config.json
|
||||
sudo systemctl restart rk3588-agent
|
||||
```
|
||||
|
||||
## 卸载
|
||||
|
||||
```bash
|
||||
# 使用卸载脚本(保留配置备份)
|
||||
sudo ./scripts/systemd/uninstall-systemd.sh
|
||||
|
||||
# 或手动卸载
|
||||
sudo systemctl stop media-server rk3588-agent
|
||||
sudo systemctl disable media-server rk3588-agent
|
||||
sudo rm -f /etc/systemd/system/media-server.service
|
||||
sudo rm -f /etc/systemd/system/rk3588-agent.service
|
||||
sudo systemctl daemon-reload
|
||||
# 然后手动删除 /opt/rk3588-media-server/ 和 /opt/rk3588-agent/
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 服务无法启动
|
||||
|
||||
```bash
|
||||
# 1. 查看详细错误信息
|
||||
sudo journalctl -u media-server -n 50 --no-pager
|
||||
|
||||
# 2. 检查配置文件
|
||||
sudo /opt/rk3588-media-server/bin/media-server --config /opt/rk3588-media-server/etc/media-server.json --version
|
||||
|
||||
# 3. 检查端口占用
|
||||
sudo ss -tlnp | grep -E '(9000|8554|8555|9100)'
|
||||
|
||||
# 4. 检查权限
|
||||
ls -la /opt/rk3588-media-server/bin/media-server
|
||||
```
|
||||
|
||||
### 端口冲突
|
||||
|
||||
如果 9000/8554/8555 端口被占用,修改配置文件:
|
||||
|
||||
```json
|
||||
// media-server.json
|
||||
{
|
||||
"http": {
|
||||
"port": 9001 // 修改为其他端口
|
||||
},
|
||||
"rtsp": {
|
||||
"port": 8556 // 修改为其他端口
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### NPU 相关问题
|
||||
|
||||
```bash
|
||||
# 检查 NPU 驱动
|
||||
cat /sys/kernel/debug/rknpu/version
|
||||
|
||||
# 检查 NPU 负载
|
||||
watch -n 1 cat /sys/kernel/debug/rknpu/load
|
||||
|
||||
# 检查设备节点
|
||||
ls -la /dev/rknpu*
|
||||
```
|
||||
|
||||
## 文件说明
|
||||
|
||||
```
|
||||
scripts/systemd/
|
||||
├── README.md # 本文件
|
||||
├── media-server.service # Media Server systemd 服务文件
|
||||
├── rk3588-agent.service # Agent systemd 服务文件
|
||||
├── install-systemd.sh # 安装脚本
|
||||
├── uninstall-systemd.sh # 卸载脚本
|
||||
├── status.sh # 状态查看脚本
|
||||
└── quick-setup.sh # 快速设置脚本(一键部署)
|
||||
```
|
||||
|
||||
## 服务文件详解
|
||||
|
||||
### media-server.service
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=RK3588 Media Server
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
ExecStart=/opt/rk3588-media-server/bin/media-server --config /opt/rk3588-media-server/etc/media-server.json
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
LimitNOFILE=65535
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
关键配置:
|
||||
|
||||
- `Restart=on-failure`: 崩溃后自动重启
|
||||
- `LimitNOFILE=65535`: 增加文件描述符限制(视频流需要)
|
||||
- `After=network-online.target`: 确保网络就绪后启动
|
||||
|
||||
### rk3588-agent.service
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=RK3588 Agent
|
||||
After=media-server.service # 可选:确保 media-server 先启动
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/opt/rk3588-agent/rk3588-agent --config /opt/rk3588-agent/agent.config.json
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **首次启动**: 确保配置文件路径正确,特别是模型路径和摄像头配置
|
||||
2. **权限**: 服务以 root 运行,需要访问 `/dev/rknpu` 设备
|
||||
3. **依赖**: Agent 可选依赖 media-server,可根据需要调整 `After=` 和 `Requires=`
|
||||
4. **日志**: 使用 `journalctl` 查看日志,日志大小由 systemd 管理
|
||||
|
||||
## 参考
|
||||
|
||||
- [命令.md](../../docs/命令.md) - 开发和部署命令参考
|
||||
- [API_Device_RemoteMgmt_InterfaceTable.md](../../API_Device_RemoteMgmt_InterfaceTable.md) - Agent API 文档
|
||||
271
scripts/systemd/install-systemd.sh
Normal file
271
scripts/systemd/install-systemd.sh
Normal file
@ -0,0 +1,271 @@
|
||||
#!/bin/bash
|
||||
# RK3588 Media Server & Agent Systemd 服务安装脚本
|
||||
# 适用于 Orange Pi 5 Plus (RK3588)
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 默认路径
|
||||
MEDIA_SERVER_BIN="${MEDIA_SERVER_BIN:-$(pwd)/build/media-server}"
|
||||
AGENT_BIN="${AGENT_BIN:-$(pwd)/agent/rk3588-agent_linux_arm64}"
|
||||
MEDIA_SERVER_CONFIG="${MEDIA_SERVER_CONFIG:-$(pwd)/configs/sample_cam1.json}"
|
||||
AGENT_CONFIG="${AGENT_CONFIG:-$(pwd)/agent/agent_cam1.config.json}"
|
||||
|
||||
INSTALL_DIR="/opt"
|
||||
SERVICE_DIR="/etc/systemd/system"
|
||||
|
||||
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║ RK3588 Media Server & Agent Systemd 安装 ║${NC}"
|
||||
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
# 检查 root 权限
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}错误: 请使用 sudo 运行此脚本${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查 systemd
|
||||
if ! command -v systemctl &> /dev/null; then
|
||||
echo -e "${RED}错误: 未找到 systemctl,此系统可能不支持 systemd${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 函数:安装 media-server
|
||||
install_media_server() {
|
||||
echo -e "${YELLOW}[1/6] 安装 Media Server...${NC}"
|
||||
|
||||
# 检查二进制文件
|
||||
if [ ! -f "$MEDIA_SERVER_BIN" ]; then
|
||||
echo -e "${RED}错误: 未找到 media-server 二进制文件: $MEDIA_SERVER_BIN${NC}"
|
||||
echo "请确认已编译,或设置 MEDIA_SERVER_BIN 环境变量"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 创建目录
|
||||
mkdir -p "$INSTALL_DIR/rk3588-media-server"/{bin,lib,etc,logs}
|
||||
|
||||
# 复制二进制文件
|
||||
cp "$MEDIA_SERVER_BIN" "$INSTALL_DIR/rk3588-media-server/bin/"
|
||||
chmod +x "$INSTALL_DIR/rk3588-media-server/bin/media-server"
|
||||
|
||||
# 复制依赖库(如果有)
|
||||
if [ -d "$(dirname $MEDIA_SERVER_BIN)/../lib" ]; then
|
||||
cp -r "$(dirname $MEDIA_SERVER_BIN)/../lib"/* "$INSTALL_DIR/rk3588-media-server/lib/" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 复制或创建配置文件
|
||||
if [ -f "$MEDIA_SERVER_CONFIG" ]; then
|
||||
cp "$MEDIA_SERVER_CONFIG" "$INSTALL_DIR/rk3588-media-server/etc/media-server.json"
|
||||
echo -e "${GREEN}✓${NC} 配置文件: $INSTALL_DIR/rk3588-media-server/etc/media-server.json"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ 未找到配置文件,请手动创建: $INSTALL_DIR/rk3588-media-server/etc/media-server.json${NC}"
|
||||
fi
|
||||
|
||||
# 安装服务文件
|
||||
cp "$(dirname $0)/media-server.service" "$SERVICE_DIR/"
|
||||
|
||||
echo -e "${GREEN}✓${NC} Media Server 安装完成"
|
||||
}
|
||||
|
||||
# 函数:安装 agent
|
||||
install_agent() {
|
||||
echo -e "${YELLOW}[2/6] 安装 RK3588 Agent...${NC}"
|
||||
|
||||
# 检查二进制文件
|
||||
if [ ! -f "$AGENT_BIN" ]; then
|
||||
# 尝试其他可能的名称
|
||||
if [ -f "$(dirname $AGENT_BIN)/rk3588-agent" ]; then
|
||||
AGENT_BIN="$(dirname $AGENT_BIN)/rk3588-agent"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ 未找到 Agent 二进制文件,跳过 Agent 安装${NC}"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# 创建目录
|
||||
mkdir -p "$INSTALL_DIR/rk3588-agent"/{logs,models}
|
||||
|
||||
# 复制二进制文件
|
||||
cp "$AGENT_BIN" "$INSTALL_DIR/rk3588-agent/rk3588-agent"
|
||||
chmod +x "$INSTALL_DIR/rk3588-agent/rk3588-agent"
|
||||
|
||||
# 复制或创建配置文件
|
||||
if [ -f "$AGENT_CONFIG" ]; then
|
||||
cp "$AGENT_CONFIG" "$INSTALL_DIR/rk3588-agent/agent.config.json"
|
||||
echo -e "${GREEN}✓${NC} 配置文件: $INSTALL_DIR/rk3588-agent/agent.config.json"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ 未找到 Agent 配置文件,请手动创建${NC}"
|
||||
fi
|
||||
|
||||
# 安装服务文件
|
||||
cp "$(dirname $0)/rk3588-agent.service" "$SERVICE_DIR/"
|
||||
|
||||
echo -e "${GREEN}✓${NC} RK3588 Agent 安装完成"
|
||||
}
|
||||
|
||||
# 函数:重载 systemd
|
||||
reload_systemd() {
|
||||
echo -e "${YELLOW}[3/6] 重载 systemd...${NC}"
|
||||
systemctl daemon-reload
|
||||
echo -e "${GREEN}✓${NC} systemd 已重载"
|
||||
}
|
||||
|
||||
# 函数:启动服务
|
||||
start_services() {
|
||||
echo -e "${YELLOW}[4/6] 启动服务...${NC}"
|
||||
|
||||
# 启动 media-server
|
||||
if [ -f "$SERVICE_DIR/media-server.service" ]; then
|
||||
echo " 启动 media-server..."
|
||||
systemctl enable media-server
|
||||
systemctl start media-server
|
||||
sleep 2
|
||||
if systemctl is-active --quiet media-server; then
|
||||
echo -e "${GREEN}✓${NC} media-server 运行中"
|
||||
else
|
||||
echo -e "${RED}✗${NC} media-server 启动失败,请检查日志"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 启动 agent
|
||||
if [ -f "$SERVICE_DIR/rk3588-agent.service" ] && [ -f "$INSTALL_DIR/rk3588-agent/rk3588-agent" ]; then
|
||||
echo " 启动 rk3588-agent..."
|
||||
systemctl enable rk3588-agent
|
||||
systemctl start rk3588-agent
|
||||
sleep 1
|
||||
if systemctl is-active --quiet rk3588-agent; then
|
||||
echo -e "${GREEN}✓${NC} rk3588-agent 运行中"
|
||||
else
|
||||
echo -e "${RED}✗${NC} rk3588-agent 启动失败,请检查日志"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:显示状态
|
||||
show_status() {
|
||||
echo -e "${YELLOW}[5/6] 服务状态...${NC}"
|
||||
echo ""
|
||||
|
||||
if [ -f "$SERVICE_DIR/media-server.service" ]; then
|
||||
echo -e "${BLUE}Media Server:${NC}"
|
||||
systemctl status media-server --no-pager | head -5
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ -f "$SERVICE_DIR/rk3588-agent.service" ]; then
|
||||
echo -e "${BLUE}RK3588 Agent:${NC}"
|
||||
systemctl status rk3588-agent --no-pager | head -5
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# 函数:显示使用说明
|
||||
show_usage() {
|
||||
echo -e "${YELLOW}[6/6] 使用说明${NC}"
|
||||
echo ""
|
||||
echo "┌─────────────────────────────────────────────────────────────┐"
|
||||
echo "│ 管理命令 │"
|
||||
echo "├─────────────────────────────────────────────────────────────┤"
|
||||
echo "│ 查看状态 │"
|
||||
echo "│ systemctl status media-server │"
|
||||
echo "│ systemctl status rk3588-agent │"
|
||||
echo "│ │"
|
||||
echo "│ 启动/停止/重启 │"
|
||||
echo "│ systemctl start media-server │"
|
||||
echo "│ systemctl stop media-server │"
|
||||
echo "│ systemctl restart media-server │"
|
||||
echo "│ │"
|
||||
echo "│ 开机自启 │"
|
||||
echo "│ systemctl enable media-server # 启用 │"
|
||||
echo "│ systemctl disable media-server # 禁用 │"
|
||||
echo "│ │"
|
||||
echo "│ 查看日志 │"
|
||||
echo "│ journalctl -u media-server -f # 实时跟踪 │"
|
||||
echo "│ journalctl -u media-server -n 100 # 最近100行 │"
|
||||
echo "│ journalctl -u rk3588-agent -f │"
|
||||
echo "│ │"
|
||||
echo "│ 文件位置 │"
|
||||
echo "│ 安装目录: /opt/rk3588-media-server/ │"
|
||||
echo "│ 配置文件: /opt/rk3588-media-server/etc/media-server.json │"
|
||||
echo "│ Agent目录: /opt/rk3588-agent/ │"
|
||||
echo "│ Agent配置: /opt/rk3588-agent/agent.config.json │"
|
||||
echo "└─────────────────────────────────────────────────────────────┘"
|
||||
}
|
||||
|
||||
# 主流程
|
||||
main() {
|
||||
# 如果传入了参数,解析环境变量
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--media-bin)
|
||||
MEDIA_SERVER_BIN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--agent-bin)
|
||||
AGENT_BIN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--media-config)
|
||||
MEDIA_SERVER_CONFIG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--agent-config)
|
||||
AGENT_CONFIG="$2"
|
||||
shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
echo "用法: $0 [选项]"
|
||||
echo ""
|
||||
echo "选项:"
|
||||
echo " --media-bin <路径> Media Server 二进制文件路径"
|
||||
echo " --agent-bin <路径> Agent 二进制文件路径"
|
||||
echo " --media-config <路径> Media Server 配置文件路径"
|
||||
echo " --agent-config <路径> Agent 配置文件路径"
|
||||
echo ""
|
||||
echo "环境变量:"
|
||||
echo " MEDIA_SERVER_BIN Media Server 二进制文件路径"
|
||||
echo " AGENT_BIN Agent 二进制文件路径"
|
||||
echo " MEDIA_SERVER_CONFIG Media Server 配置文件路径"
|
||||
echo " AGENT_CONFIG Agent 配置文件路径"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "未知选项: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "安装路径: $INSTALL_DIR"
|
||||
echo "Media Server: $MEDIA_SERVER_BIN"
|
||||
echo "Agent: $AGENT_BIN"
|
||||
echo ""
|
||||
|
||||
read -p "确认安装? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "安装已取消"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
install_media_server
|
||||
install_agent
|
||||
reload_systemd
|
||||
start_services
|
||||
show_status
|
||||
show_usage
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ 安装完成! ║${NC}"
|
||||
echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
40
scripts/systemd/media-server.service
Normal file
40
scripts/systemd/media-server.service
Normal file
@ -0,0 +1,40 @@
|
||||
[Unit]
|
||||
Description=RK3588 Media Server
|
||||
Documentation=https://github.com/your-org/OrangePi3588Media
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
WorkingDirectory=/opt/rk3588-media-server
|
||||
ExecStart=/opt/rk3588-media-server/bin/media-server --config /opt/rk3588-media-server/etc/media-server.json
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=30
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
StartLimitInterval=60s
|
||||
StartLimitBurst=3
|
||||
|
||||
# 资源限制
|
||||
LimitNOFILE=65535
|
||||
LimitNPROC=4096
|
||||
|
||||
# 环境变量
|
||||
Environment="LD_LIBRARY_PATH=/opt/rk3588-media-server/lib:$LD_LIBRARY_PATH"
|
||||
|
||||
# 日志输出
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=media-server
|
||||
|
||||
# 安全设置(根据实际需求调整)
|
||||
# NoNewPrivileges=false
|
||||
# ProtectSystem=false
|
||||
# ProtectHome=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
102
scripts/systemd/quick-setup.sh
Normal file
102
scripts/systemd/quick-setup.sh
Normal file
@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
# RK3588 Media Server 快速设置脚本
|
||||
# 适用于开发板直接编译部署
|
||||
|
||||
set -e
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${YELLOW}========== RK3588 Media Server 快速设置 ==========${NC}"
|
||||
echo ""
|
||||
|
||||
# 检测是否在 Orange Pi 上
|
||||
if [[ "$(uname -m)" != "aarch64" ]]; then
|
||||
echo "警告: 当前不是 ARM64 架构,此脚本适用于 RK3588 开发板"
|
||||
read -p "是否继续? (y/N): " -n 1 -r
|
||||
echo
|
||||
[[ ! $REPLY =~ ^[Yy]$ ]] && exit 1
|
||||
fi
|
||||
|
||||
# 检查 sudo
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "请使用 sudo 运行"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
BUILD_DIR="$PROJECT_DIR/build"
|
||||
|
||||
echo "项目目录: $PROJECT_DIR"
|
||||
echo ""
|
||||
|
||||
# 步骤1: 检查编译
|
||||
echo "[1/4] 检查编译状态..."
|
||||
if [ ! -f "$BUILD_DIR/media-server" ]; then
|
||||
echo "未找到编译好的 media-server,开始编译..."
|
||||
echo ""
|
||||
echo "CMake 配置:"
|
||||
cmake -S "$PROJECT_DIR" -B "$BUILD_DIR" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_TESTS=OFF \
|
||||
-DBUILD_SAMPLES=ON \
|
||||
-DRK3588_ENABLE_FFMPEG=ON \
|
||||
-DRK3588_ENABLE_MPP=ON \
|
||||
-DRK3588_ENABLE_RGA=ON \
|
||||
-DRK3588_ENABLE_ZLMEDIAKIT=ON \
|
||||
-DRK3588_ENABLE_RKNN=ON \
|
||||
-DRK_ZLMK_API_LIB_PATH="$PROJECT_DIR/third_party/rknpu2/examples/3rdparty/zlmediakit/aarch64/libmk_api.so" \
|
||||
-DRK_ZLMEDIAKIT_INCLUDE_DIR="$PROJECT_DIR/third_party/rknpu2/examples/3rdparty/zlmediakit/include"
|
||||
|
||||
echo ""
|
||||
echo "开始编译(使用 $(nproc) 线程)..."
|
||||
cmake --build "$BUILD_DIR" -j$(nproc)
|
||||
else
|
||||
echo -e "${GREEN}✓${NC} 已编译"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 步骤2: 安装 systemd 服务
|
||||
echo "[2/4] 安装 Systemd 服务..."
|
||||
"$(dirname "$0")/install-systemd.sh" \
|
||||
--media-bin "$BUILD_DIR/media-server" \
|
||||
--media-config "$PROJECT_DIR/configs/sample_cam1.json" \
|
||||
--agent-bin "$PROJECT_DIR/agent/rk3588-agent_linux_arm64" \
|
||||
--agent-config "$PROJECT_DIR/agent/agent_cam1.config.json"
|
||||
|
||||
echo ""
|
||||
|
||||
# 步骤3: 检查端口
|
||||
echo "[3/4] 检查端口..."
|
||||
for port in 9000 8554 8555 9100; do
|
||||
if ss -tln | grep -q ":$port "; then
|
||||
echo -e " ${GREEN}✓${NC} 端口 $port 监听正常"
|
||||
else
|
||||
echo " 端口 $port 未监听"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# 步骤4: 测试
|
||||
echo "[4/4] 快速测试..."
|
||||
sleep 2
|
||||
if systemctl is-active --quiet media-server; then
|
||||
echo -e "${GREEN}Media Server 运行正常${NC}"
|
||||
echo ""
|
||||
echo "测试地址:"
|
||||
IP=$(hostname -I | awk '{print $1}')
|
||||
echo " HLS: http://$IP:9000/hls/cam1/index.m3u8"
|
||||
echo " RTSP: rtsp://$IP:8555/live/cam1"
|
||||
else
|
||||
echo "Media Server 可能未正常启动,请检查日志:"
|
||||
echo " journalctl -u media-server -n 20"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo -e "${GREEN}设置完成!${NC}"
|
||||
echo ""
|
||||
echo "常用命令:"
|
||||
echo " 查看状态: $(dirname "$0")/status.sh"
|
||||
echo " 查看日志: journalctl -u media-server -f"
|
||||
echo " 重启服务: systemctl restart media-server"
|
||||
40
scripts/systemd/rk3588-agent.service
Normal file
40
scripts/systemd/rk3588-agent.service
Normal file
@ -0,0 +1,40 @@
|
||||
[Unit]
|
||||
Description=RK3588 Agent (Management API)
|
||||
Documentation=https://github.com/your-org/OrangePi3588Media
|
||||
After=network-online.target media-server.service
|
||||
Wants=network-online.target
|
||||
# 如果 agent 依赖 media-server,取消下面这行的注释
|
||||
# Requires=media-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
WorkingDirectory=/opt/rk3588-agent
|
||||
ExecStart=/opt/rk3588-agent/rk3588-agent --config /opt/rk3588-agent/agent.config.json
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=30
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
StartLimitInterval=60s
|
||||
StartLimitBurst=5
|
||||
|
||||
# 资源限制
|
||||
LimitNOFILE=65535
|
||||
LimitNPROC=4096
|
||||
|
||||
# 日志输出
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=rk3588-agent
|
||||
|
||||
# 安全设置
|
||||
# NoNewPrivileges=true
|
||||
# ProtectSystem=strict
|
||||
# ProtectHome=true
|
||||
# ReadWritePaths=/opt/rk3588-agent
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
82
scripts/systemd/status.sh
Normal file
82
scripts/systemd/status.sh
Normal file
@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
# RK3588 Media Server & Agent 状态查看脚本
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}========== RK3588 Media Server & Agent 状态 ==========${NC}"
|
||||
echo ""
|
||||
|
||||
# 显示系统信息
|
||||
echo -e "${YELLOW}[系统信息]${NC}"
|
||||
echo " 时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo " 运行时间: $(uptime -p 2>/dev/null || uptime)"
|
||||
echo ""
|
||||
|
||||
# NPU 负载
|
||||
echo -e "${YELLOW}[NPU 负载]${NC}"
|
||||
if [ -f /sys/kernel/debug/rknpu/load ]; then
|
||||
cat /sys/kernel/debug/rknpu/load | while read line; do
|
||||
echo " $line"
|
||||
done
|
||||
else
|
||||
echo " NPU 信息不可用"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Media Server 状态
|
||||
echo -e "${YELLOW}[Media Server]${NC}"
|
||||
if systemctl is-active --quiet media-server 2>/dev/null; then
|
||||
echo -e " 状态: ${GREEN}● 运行中${NC}"
|
||||
PID=$(systemctl show --property=MainPID --value media-server)
|
||||
echo " PID: $PID"
|
||||
|
||||
# 资源使用
|
||||
if [ -n "$PID" ] && [ "$PID" != "0" ]; then
|
||||
CPU_MEM=$(ps -p $PID -o %cpu,%mem --no-headers 2>/dev/null || echo "N/A")
|
||||
echo " CPU/MEM: $CPU_MEM"
|
||||
fi
|
||||
|
||||
# 端口监听
|
||||
echo " 端口监听:"
|
||||
ss -tlnp 2>/dev/null | grep -E "(9000|8554|8555)" | head -3 | while read line; do
|
||||
echo " $line"
|
||||
done
|
||||
else
|
||||
echo -e " 状态: ${RED}○ 停止${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Agent 状态
|
||||
echo -e "${YELLOW}[RK3588 Agent]${NC}"
|
||||
if systemctl is-active --quiet rk3588-agent 2>/dev/null; then
|
||||
echo -e " 状态: ${GREEN}● 运行中${NC}"
|
||||
PID=$(systemctl show --property=MainPID --value rk3588-agent)
|
||||
echo " PID: $PID"
|
||||
|
||||
if [ -n "$PID" ] && [ "$PID" != "0" ]; then
|
||||
CPU_MEM=$(ps -p $PID -o %cpu,%mem --no-headers 2>/dev/null || echo "N/A")
|
||||
echo " CPU/MEM: $CPU_MEM"
|
||||
fi
|
||||
else
|
||||
echo -e " 状态: ${RED}○ 停止${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 日志摘要
|
||||
echo -e "${YELLOW}[最近日志]${NC}"
|
||||
echo "Media Server (最后3行):"
|
||||
journalctl -u media-server --no-pager -n 3 2>/dev/null | tail -3 || echo " 无日志"
|
||||
echo ""
|
||||
echo "Agent (最后3行):"
|
||||
journalctl -u rk3588-agent --no-pager -n 3 2>/dev/null | tail -3 || echo " 无日志"
|
||||
echo ""
|
||||
|
||||
# 操作提示
|
||||
echo -e "${YELLOW}[管理命令]${NC}"
|
||||
echo " 重启服务: sudo systemctl restart media-server"
|
||||
echo " 查看日志: sudo journalctl -u media-server -f"
|
||||
echo " 查看NPU: sudo watch -n 1 cat /sys/kernel/debug/rknpu/load"
|
||||
81
scripts/systemd/uninstall-systemd.sh
Normal file
81
scripts/systemd/uninstall-systemd.sh
Normal file
@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# RK3588 Media Server & Agent Systemd 服务卸载脚本
|
||||
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${YELLOW}========== RK3588 Media Server & Agent 卸载 ==========${NC}"
|
||||
echo ""
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}错误: 请使用 sudo 运行${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 确认
|
||||
read -p "确定要卸载并停止所有服务? 数据将保留。 (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "卸载已取消"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 停止服务
|
||||
echo "[1/4] 停止服务..."
|
||||
systemctl stop media-server 2>/dev/null || true
|
||||
systemctl stop rk3588-agent 2>/dev/null || true
|
||||
systemctl disable media-server 2>/dev/null || true
|
||||
systemctl disable rk3588-agent 2>/dev/null || true
|
||||
echo -e "${GREEN}✓${NC} 服务已停止并禁用"
|
||||
|
||||
# 删除服务文件
|
||||
echo "[2/4] 删除服务文件..."
|
||||
rm -f /etc/systemd/system/media-server.service
|
||||
rm -f /etc/systemd/system/rk3588-agent.service
|
||||
systemctl daemon-reload
|
||||
echo -e "${GREEN}✓${NC} 服务文件已删除"
|
||||
|
||||
# 备份配置
|
||||
echo "[3/4] 备份配置..."
|
||||
BACKUP_DIR="/root/rk3588-backup-$(date +%Y%m%d%H%M%S)"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
if [ -f "/opt/rk3588-media-server/etc/media-server.json" ]; then
|
||||
cp "/opt/rk3588-media-server/etc/media-server.json" "$BACKUP_DIR/"
|
||||
echo " 已备份 media-server 配置"
|
||||
fi
|
||||
|
||||
if [ -f "/opt/rk3588-agent/agent.config.json" ]; then
|
||||
cp "/opt/rk3588-agent/agent.config.json" "$BACKUP_DIR/"
|
||||
echo " 已备份 agent 配置"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✓${NC} 配置已备份到: $BACKUP_DIR"
|
||||
|
||||
# 提示删除文件
|
||||
echo "[4/4] 清理文件..."
|
||||
echo ""
|
||||
echo "以下目录需要手动删除(如需完全清理):"
|
||||
echo " /opt/rk3588-media-server/"
|
||||
echo " /opt/rk3588-agent/"
|
||||
echo ""
|
||||
|
||||
read -p "是否删除这些目录? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
rm -rf /opt/rk3588-media-server/
|
||||
rm -rf /opt/rk3588-agent/
|
||||
echo -e "${GREEN}✓${NC} 目录已删除"
|
||||
else
|
||||
echo "保留目录,如需删除请手动执行:"
|
||||
echo " sudo rm -rf /opt/rk3588-media-server/"
|
||||
echo " sudo rm -rf /opt/rk3588-agent/"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}卸载完成${NC}"
|
||||
echo "备份位置: $BACKUP_DIR"
|
||||
Loading…
Reference in New Issue
Block a user