OrangePi3588Media/docs/config_guide.md

17 KiB
Raw Blame History

配置文件编写指南

本文档详细说明如何编写和定制 RK3588 Media Server 的配置文件。


1. 配置文件结构

配置文件采用 JSON 格式,分为四个主要部分:

{
  "global": { ... },      // 全局设置
  "queue": { ... },       // 队列策略
  "templates": { ... },   // 节点模板定义
  "instances": [ ... ]    // 实例化配置
}

1.1 全局设置 (global)

{
  "global": {
    "metrics_port": 9000,      // HTTP 服务端口(监控/HLS
    "web_root": "web"          // Web 静态文件根目录
  }
}

1.2 队列策略 (queue)

{
  "queue": {
    "size": 4,                    // 队列长度
    "strategy": "drop_oldest"     // 队列满时的策略
  }
}

strategy 选项:

  • drop_oldest - 丢弃最旧的帧(推荐,实时性好)
  • drop_newest - 丢弃最新的帧
  • block - 阻塞等待(可能导致延迟累积)

2. 模板定义 (templates)

模板定义了一组节点和连接关系,可以被多个实例复用。

2.1 模板基本结构

{
  "templates": {
    "template_name": {
      "nodes": [ ... ],     // 节点列表
      "edges": [ ... ]      // 连接关系
    }
  }
}

2.2 节点 (nodes)

每个节点必须包含以下字段:

{
  "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 拉流)

{
  "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文件输入

{
  "id": "in",
  "type": "input_file",
  "role": "source",
  "enable": true,
  "path": "/path/to/video.mp4",
  "loop": true,           // 循环播放
  "fps": 30
}

3.2 预处理节点

preprocess图像预处理

{
  "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 目标检测)

{
  "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人脸检测

{
  "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人脸识别

{
  "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目标跟踪

{
  "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屏幕显示

{
  "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报警处理

{
  "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视频输出

{
  "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                  // 切片时长
    }
  ]
}

logic_gate逻辑门 - PPE合规检测

用于空间关联检测和颜色分析,典型场景:检测人是否穿劳保鞋及颜色是否合规。

{
  "id": "logic_ppe",
  "type": "logic_gate",
  "role": "filter",
  "enable": true,
  "mode": "ppe_boots_check",       // 工作模式
  "anchor_class": 6,                // 基准类别:人(Person)
  "boots_class": 3,                 // 目标类别:鞋(boots)
  "color_check": {
    "enable": true,                 // 启用颜色检测
    "method": "hsv",                // 颜色空间hsv/rgb/brightness
    "dark_threshold": 80,           // 深色阈值0-255
    "roi_expand": 1.0               // 检测框扩大系数
  },
  "debug": false                    // 调试输出
}

颜色阈值调整建议:

阈值 效果 适用场景
60 很严格,只有纯黑才算深色 环境光很暗
80 (默认) 适中,黑色/深灰通过 正常室内光
100 较宽松,灰色也算深色 环境光很亮
120 很宽松,浅灰也算深色 强光/反光环境

判断逻辑:

is_dark = (平均亮度 < dark_threshold) && (深色像素比例 > 60%)

使用示例流程:

input → preprocess → ai_yolo(Person+boots) → tracker → logic_gate → osd → publish
                                                   ↓
                                            判断:人+鞋同时存在?
                                                   ↓
                                            是 → 检查鞋颜色
                                                 ↓
                                            深色 → 合规
                                            浅色 → 告警

4. 连接关系 (edges)

edges 定义了数据流向:

{
  "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)

实例化将模板应用到具体配置:

{
  "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 中提供值:

模板中:

"url": "${url}",
"face_gallery_path": "${face_gallery_path}"

实例中:

"params": {
  "url": "rtsp://10.0.0.49:8554/cam1",
  "face_gallery_path": "./models/face_gallery.db"
}

6. 完整配置示例

6.1 单路 PPE 检测(完整)

{
  "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 多路复用模板

{
  "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: 如何禁用某个节点?

"enable": false

Q: 如何修改日志级别?

节点级别的 debug 配置:

"debug": {
  "stats": false,        // 关闭统计日志
  "stats_interval": 100, // 统计间隔(帧数)
  "detections": false    // 关闭检测日志
}

Q: 配置错误如何排查?

# 检查 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