safesight-edge/docs/config_guide.md

657 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 配置文件编写指南
本文档详细说明如何编写和定制 RK3588 Media Server 的配置文件。
---
## 1. 配置文件结构
配置文件采用 **JSON 格式**,分为四个主要部分:
```json
{
"global": { ... }, // 全局设置
"queue": { ... }, // 队列策略
"templates": { ... }, // 节点模板定义
"instances": [ ... ] // 实例化配置
}
```
### 1.1 全局设置 (global)
```json
{
"global": {
"metrics_port": 9000, // HTTP 服务端口(监控/HLS
"web_root": "web" // Web 静态文件根目录
}
}
```
### 1.2 队列策略 (queue)
```json
{
"queue": {
"size": 4, // 队列长度
"strategy": "drop_oldest" // 队列满时的策略
}
}
```
**strategy 选项:**
- `drop_oldest` - 丢弃最旧的帧(推荐,实时性好)
- `drop_newest` - 丢弃最新的帧
- `block` - 阻塞等待(可能导致延迟累积)
---
## 2. 模板定义 (templates)
模板定义了一组节点和连接关系,可以被多个实例复用。
### 2.1 模板基本结构
```json
{
"templates": {
"template_name": {
"nodes": [ ... ], // 节点列表
"edges": [ ... ] // 连接关系
}
}
}
```
### 2.2 节点 (nodes)
每个节点必须包含以下字段:
```json
{
"id": "node_id", // 节点唯一标识
"type": "node_type", // 节点类型
"role": "source/filter/sink", // 角色
"enable": true // 是否启用
}
```
**节点类型说明:**
| 类型 | 角色 | 功能 |
|------|------|------|
| `input_rtsp` | source | 拉取 RTSP 视频流 |
| `input_file` | source | 读取本地视频文件 |
| `preprocess` | filter | 图像预处理(缩放/格式转换)|
| `ai_yolo` | filter | YOLO 目标检测 |
| `ai_face_det` | filter | 人脸检测 |
| `ai_face_recog` | filter | 人脸识别 |
| `tracker` | filter | 目标跟踪 |
| `osd` | filter | 绘制检测框/文字 |
| `alarm` | sink | 报警规则处理 |
| `publish` | sink | 视频编码输出 |
| `storage` | sink | 录像存储 |
---
## 3. 节点详细配置
### 3.1 输入节点
#### input_rtspRTSP 拉流)
```json
{
"id": "in",
"type": "input_rtsp",
"role": "source",
"enable": true,
"url": "rtsp://10.0.0.49:8554/cam", // RTSP 地址
"fps": 30, // 预期帧率
"width": 1920, // 预期宽度
"height": 1080, // 预期高度
"use_mpp": true, // 使用 MPP 硬件解码
"use_ffmpeg": false, // 是否使用 FFmpeg
"force_tcp": true, // 强制 TCP 传输
"reconnect_sec": 5, // 重连间隔
"reconnect_backoff_max_sec": 30 // 最大重连间隔
}
```
#### input_file文件输入
```json
{
"id": "in",
"type": "input_file",
"role": "source",
"enable": true,
"path": "/path/to/video.mp4",
"loop": true, // 循环播放
"fps": 30
}
```
### 3.2 预处理节点
#### preprocess图像预处理
```json
{
"id": "pre",
"type": "preprocess",
"role": "filter",
"enable": true,
"dst_w": 768, // 输出宽度
"dst_h": 768, // 输出高度
"dst_format": "rgb", // 输出格式
"dst_packed": true, // 是否 packed 格式
"resize_mode": "stretch", // 缩放模式(推荐)
"rga_gate": "cam1", // RGA 资源锁(同名互斥)
"use_rga": true // 使用 RGA 硬件
}
```
**resize_mode 选项:**
- `stretch` - 拉伸填充(**推荐**,生产环境默认使用)
- `keep_ratio` - 保持比例(可能留黑边)
- `letterbox` - 保持比例,边缘填充黑色(保留功能,当前有稳定性问题)
> **注意**`stretch` 模式在输入输出比例相同时(如 16:9→16:9不会有明显变形。当输入 16:9 拉伸到模型 1:1 再拉伸回 16:9 输出时,两次变形相互抵消,最终画面正常。该模式性能更好、画面更稳定,推荐生产环境使用。
**dst_format 选项:**
- `rgb` - RGB24
- `bgr` - BGR24
- `nv12` - NV12 (YUV420SP)
- `yuv420` - YUV420P
### 3.3 AI 节点
#### ai_yoloYOLO 目标检测)
```json
{
"id": "ai",
"type": "ai_yolo",
"role": "filter",
"enable": true,
"infer_fps": 10, // 推理帧率
"model_path": "./models/best-768.rknn",
"model_version": "v8", // v5 或 v8
"model_w": 768, // 模型输入宽度
"model_h": 768, // 模型输入高度
"num_classes": 11, // 类别数
"conf": 0.35, // 置信度阈值
"nms": 0.45, // NMS IoU 阈值
"class_filter": [3, 6] // 只检测指定类别
}
```
#### ai_face_det人脸检测
```json
{
"id": "face_det",
"type": "ai_face_det",
"role": "filter",
"enable": true,
"model_path": "./models/RetinaFace_mobile320.rknn",
"conf": 0.7,
"nms": 0.4,
"max_faces": 10, // 最大检测人脸数
"output_landmarks": true, // 输出关键点
"input_format": "rgb" // 输入格式
}
```
#### ai_face_recog人脸识别
```json
{
"id": "face_recog",
"type": "ai_face_recog",
"role": "filter",
"enable": true,
"model_path": "./models/mobilefacenet_arcface.rknn",
"align": true, // 是否对齐人脸
"emit_embedding": false, // 是否输出特征向量
"max_faces": 10,
"input_format": "rgb",
"input_dtype": "uint8",
"threshold": {
"accept": 0.45, // 识别通过阈值
"margin": 0.05 // 边距
},
"gallery": {
"backend": "sqlite",
"path": "./models/face_gallery.db", // 人脸库路径
"load_on_start": true,
"expected_dim": 512,
"dtype": "auto"
}
}
```
### 3.4 跟踪节点
#### tracker目标跟踪
```json
{
"id": "trk",
"type": "tracker",
"role": "filter",
"enable": true,
"mode": "bytetrack_lite", // 跟踪算法
"per_class": true, // 按类别分别跟踪
"state_key": "cam1", // 状态键(多路隔离)
"track_classes": [3, 6], // 跟踪的类别
"high_th": 0.5, // 高分阈值
"low_th": 0.1, // 低分阈值
"iou_th": 0.3, // IOU 阈值
"max_age_ms": 1500, // 最大丢失时间
"min_hits": 2, // 最小确认帧数
"max_tracks": 128 // 最大跟踪数
}
```
### 3.5 显示节点
#### osd屏幕显示
```json
{
"id": "osd",
"type": "osd",
"role": "filter",
"enable": true,
"draw_bbox": true, // 绘制检测框
"draw_text": true, // 绘制文字
"draw_face_det": true, // 绘制人脸框
"draw_face_bbox": true, // 绘制人脸边框
"line_width": 2, // 线宽
"font_scale": 1, // 字体缩放
"use_rga_bbox": false, // 使用 RGA 绘制框
"labels": ["helmet", "gloves", "vest", "boots", ...] // 类别标签
}
```
### 3.6 报警节点
#### alarm报警处理
```json
{
"id": "alarm",
"type": "alarm",
"role": "sink",
"enable": true,
"eval_fps": 10, // 评估帧率
"labels": ["helmet", "gloves", ...], // 类别标签
"rules": [
{
"name": "ppe_violation", // 规则名称
"class_ids": [3, 6], // 触发类别
"roi": {"x": 0.0, "y": 0.0, "w": 1.0, "h": 1.0}, // ROI
"min_score": 0.4, // 最小置信度
"min_box_area_ratio": 0.02, // 最小框面积比
"require_track_id": true, // 需要跟踪ID
"min_duration_ms": 1500, // 最小持续时间
"min_hits": 3, // 最小命中次数
"hit_window_ms": 1500, // 命中窗口
"cooldown_ms": 5000 // 冷却时间
}
],
"actions": {
"log": {"enable": true, "level": "info"},
"snapshot": {
"enable": true,
"min_interval_ms": 15000,
"format": "jpg",
"quality": 85,
"upload": {
"type": "minio",
"endpoint": "http://10.0.0.49:9000",
"bucket": "myminio",
"access_key": "minioadmin",
"secret_key": "minioadmin"
}
},
"clip": {
"enable": true,
"min_interval_ms": 15000,
"pre_sec": 5,
"post_sec": 10,
"format": "mp4",
"upload": { ... }
}
}
}
```
### 3.7 输出节点
#### publish视频输出
```json
{
"id": "pub",
"type": "publish",
"role": "filter",
"enable": true,
"queue": {"size": 2, "policy": "drop_oldest"},
"codec": "h264", // 编码格式
"fps": 30, // 输出帧率
"gop": 60, // GOP 大小
"bitrate_kbps": 4000, // 码率
"use_mpp": true, // 使用 MPP 编码
"use_ffmpeg_mux": true, // 使用 FFmpeg 封装
"outputs": [
{
"proto": "rtsp_server", // RTSP 输出
"port": 8555,
"path": "/live/cam1"
},
{
"proto": "hls", // HLS 输出
"path": "./web/hls/cam1/index.m3u8",
"segment_sec": 2 // 切片时长
}
]
}
```
---
## 4. 连接关系 (edges)
edges 定义了数据流向:
```json
{
"edges": [
["in", "pre"], // in -> pre
["pre", "ai"], // pre -> ai
["ai", "trk"], // ai -> trk
["trk", "osd"], // trk -> osd
["osd", "post"], // osd -> post
["post", "pub"], // post -> pub
["pub", "alarm"] // pub -> alarm
]
}
```
**注意:** 数据流是单向的,从 source 到 sink。
---
## 5. 实例化 (instances)
实例化将模板应用到具体配置:
```json
{
"instances": [
{
"name": "cam1", // 实例名称
"template": "ppe_detection_pipeline", // 使用的模板
"params": { // 参数替换
"name": "cam1",
"url": "rtsp://10.0.0.49:8554/cam1",
"face_gallery_path": "./models/face_gallery.db",
"minio_endpoint": "http://10.0.0.49:9000",
"minio_bucket": "myminio",
"minio_ak": "minioadmin",
"minio_sk": "minioadmin"
}
}
]
}
```
### 5.1 变量替换
模板中使用 `${variable}` 定义变量,在实例的 `params` 中提供值:
**模板中:**
```json
"url": "${url}",
"face_gallery_path": "${face_gallery_path}"
```
**实例中:**
```json
"params": {
"url": "rtsp://10.0.0.49:8554/cam1",
"face_gallery_path": "./models/face_gallery.db"
}
```
---
## 6. 完整配置示例
### 6.1 单路 PPE 检测(完整)
```json
{
"global": {
"metrics_port": 9000,
"web_root": "web"
},
"queue": {
"size": 4,
"strategy": "drop_oldest"
},
"templates": {
"ppe_pipeline": {
"nodes": [
{
"id": "in",
"type": "input_rtsp",
"role": "source",
"enable": true,
"url": "${url}",
"fps": 30,
"use_mpp": true,
"force_tcp": true,
"reconnect_sec": 5
},
{
"id": "pre",
"type": "preprocess",
"role": "filter",
"enable": true,
"dst_w": 768,
"dst_h": 768,
"dst_format": "rgb",
"resize_mode": "stretch",
"use_rga": true
},
{
"id": "ai",
"type": "ai_yolo",
"role": "filter",
"enable": true,
"infer_fps": 10,
"model_path": "./models/best-768.rknn",
"model_version": "v8",
"model_w": 768,
"model_h": 768,
"num_classes": 11,
"conf": 0.35,
"nms": 0.45,
"class_filter": [3, 6]
},
{
"id": "trk",
"type": "tracker",
"role": "filter",
"enable": true,
"mode": "bytetrack_lite",
"per_class": true,
"track_classes": [3, 6],
"max_age_ms": 1500
},
{
"id": "osd",
"type": "osd",
"role": "filter",
"enable": true,
"draw_bbox": true,
"draw_text": true
},
{
"id": "post",
"type": "preprocess",
"role": "filter",
"enable": true,
"dst_w": 1920,
"dst_h": 1080,
"dst_format": "nv12",
"resize_mode": "keep_ratio",
"use_rga": true
},
{
"id": "alarm",
"type": "alarm",
"role": "sink",
"enable": true,
"eval_fps": 10,
"rules": [
{
"name": "ppe_violation",
"class_ids": [3, 6],
"min_score": 0.4,
"min_duration_ms": 1500
}
],
"actions": {
"log": {"enable": true}
}
},
{
"id": "pub",
"type": "publish",
"role": "filter",
"enable": true,
"codec": "h264",
"fps": 30,
"bitrate_kbps": 4000,
"outputs": [
{"proto": "rtsp_server", "port": 8555, "path": "/live/${name}"},
{"proto": "hls", "path": "./web/hls/${name}/index.m3u8", "segment_sec": 2}
]
}
],
"edges": [
["in", "pre"],
["pre", "ai"],
["ai", "trk"],
["trk", "osd"],
["osd", "post"],
["post", "pub"],
["pub", "alarm"]
]
}
},
"instances": [
{
"name": "cam1",
"template": "ppe_pipeline",
"params": {
"name": "cam1",
"url": "rtsp://10.0.0.49:8554/cam1"
}
}
]
}
```
### 6.2 多路复用模板
```json
{
"instances": [
{
"name": "cam1",
"template": "ppe_pipeline",
"params": {
"name": "cam1",
"url": "rtsp://10.0.0.49:8554/cam1"
}
},
{
"name": "cam2",
"template": "ppe_pipeline",
"params": {
"name": "cam2",
"url": "rtsp://10.0.0.49:8554/cam2"
}
},
{
"name": "cam3",
"template": "ppe_pipeline",
"params": {
"name": "cam3",
"url": "rtsp://10.0.0.49:8554/cam3"
}
},
{
"name": "cam4",
"template": "ppe_pipeline",
"params": {
"name": "cam4",
"url": "rtsp://10.0.0.49:8554/cam4"
}
}
]
}
```
---
## 7. 常见问题
### Q: 如何禁用某个节点?
```json
"enable": false
```
### Q: 如何修改日志级别?
节点级别的 debug 配置:
```json
"debug": {
"stats": false, // 关闭统计日志
"stats_interval": 100, // 统计间隔(帧数)
"detections": false // 关闭检测日志
}
```
### Q: 配置错误如何排查?
```bash
# 检查 JSON 格式
python3 -m json.tool config.json > /dev/null
# 启动时查看错误日志
./build/media-server --config config.json 2>&1 | grep -i error
```
---
## 8. 参考配置
| 配置文件 | 说明 |
|----------|------|
| `configs/production_4ch.json` | 4路生产环境配置1080p|
| `configs/stress_5ch_face_recog.json` | 5路压力测试配置 |
| `configs/sample_cam_ppe11.json` | 单路 PPE 检测示例 |
---
**版本**v1.0
**更新日期**2026-02-28