Viseron 3.7.0 配置参数详解
Viseron 3.7.0 config.yaml 逐域参数详解:ffmpeg 取流、mog2 运动检测、darknet 物体检测与 labels 过滤、录像行为、存储分层、MQTT 事件输出、Web 认证限流与日志,默认值+实测回显双重支撑(2026-10-30)。
Viseron 3.7.0 配置参数详解
目标:把 Viseron 3.7.0 的
config.yaml按配置域逐个讲透——ffmpeg 取流、mog2 运动检测、darknet 物体检测与标签过滤、录像行为、存储分层、MQTT 事件输出、NVR 协调、Web/API 与日志,每个关键参数给出默认值、取值含义,并用实测回显(日志、REST API 响应、MQTT 抓包)验证参数改动的实际行为。全部命令与回显在 Ubuntu 22.04 服务器实测跑出(2026-10-30),部署方式与模拟摄像头接入见《Viseron 3.7.0 Docker Compose 部署指南》。
一、环境信息
本篇全部参数验证在下列环境中完成,所有回显均为真实输出(2026-10-30):
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04(Linux x86_64,6 核 CPU / 19GB 内存,无独立显卡) |
| Viseron | 3.7.0(官方渠道安装,内置 PostgreSQL 16.15 / FFmpeg 8.1 / go2rtc / nginx) |
| Web UI 端口 | 8888(部署时映射为宿主 8151,见姊妹部署篇) |
| 配置文件 | /config/config.yaml(挂载自宿主 /opt/viseron/config/config.yaml) |
| 数据目录 | /segments、/snapshots、/thumbnails、/event_clips、/timelapse |
| 模拟摄像头 | MediaMTX 1.21.3 提供 RTSP 流 rtsp://mediamtx:8554/cam(样例视频循环推流,768x432@12fps) |
| 检测模型 | /detectors/models/darknet/yolov7-tiny.weights + yolov7-tiny.cfg(官方内置) |
| API 认证 | 已启用,示例管理账号 admin / q1w2e3r4 |
| 检测阈值基线 | 运动检测 mog2,物体检测 darknet(YOLOv7-tiny) |
Viseron 的配置全部集中在一个 YAML 文件 /config/config.yaml,没有其他分散配置点;改配置 → 重启服务生效是唯一生效路径。官方文档站对每个组件域均有独立说明页(见文末参考链接),本篇以实测行为为主线逐一验证。
二、前置条件
阅读与复现本篇需要:
- 一套已跑通的 Viseron 3.7.0 环境:能打开 Web UI、能看到摄像头画面与事件列表。从零部署见《Viseron 3.7.0 Docker Compose 部署指南》,本篇所有命令在该环境上直接执行。
- 一个可用的摄像头源:真实 RTSP 摄像头或模拟源均可。本篇沿用部署篇的 MediaMTX 模拟源(样例视频 person-bicycle-car-detection.mp4 循环推流),画面中出现行人、自行车与汽车,正好覆盖 darknet 三个跟踪标签。
- 服务端能执行
curl命令,用于查 API、验证配置生效。 - 已知管理账号:本环境启用了
webserver.auth,示例账号 admin / q1w2e3r4(首次启动时在引导页创建)。
💡 技术拓展:Viseron 的检测能力全部走「组件 + 域」模型——同一「运动检测域(motion_detector)」可有多个组件实现,同一「物体检测域(object_detector)」同样如此。主要同类选项对比:
域 可选组件 特点 适用场景 motion_detector mog2 OpenCV MOG2 背景建模,CPU 开销低 通用场景首选,本篇实际采用 motion_detector background_subtractor 另一种背景减除实现,支持掩码矩形 需要精细划定检测区域的场合 object_detector darknet YOLO 系列权重(YOLOv7 等),CPU 可跑 通用物体识别,本篇实际采用 object_detector edgetpu Google Coral TPU 加速 有 Coral USB 加速棒 object_detector yolo / deepstack / codeprojectai 其他推理后端或外部推理服务 已有现成推理服务的部署 object_detector dlib / hailo 人脸向检测或 Hailo 加速卡 特定硬件生态 组件只负责「算」,域负责「管」:config.yaml 中每个域的
cameras段才是与摄像头联动的关键,后文逐域展开。
三、参数查看与修改方式
3.1 配置文件位置与首次生成
Viseron 启动时读取 /config/config.yaml;文件不存在时首次启动会自动生成一份默认配置,覆盖「接一个摄像头 + 开一个检测器」的最小可用场景。本环境从部署篇一路实测而来,当前的基线配置如下:
# /config/config.yaml —— 部署篇的基线配置
ffmpeg:
camera:
fake_camera:
name: Fake Camera
host: mediamtx
port: 8554
path: /cam
stream_format: rtsp
fps: 12
recorder:
idle_timeout: 5
mog2:
motion_detector:
cameras:
fake_camera:
fps: 2
darknet:
object_detector:
model_path: /detectors/models/darknet/yolov7-tiny.weights
model_config: /detectors/models/darknet/yolov7-tiny.cfg
cameras:
fake_camera:
fps: 2
scan_on_motion_only: false
labels:
- label: person
confidence: 0.7
trigger_event_recording: true
- label: bicycle
confidence: 0.7
trigger_event_recording: true
- label: car
confidence: 0.7
trigger_event_recording: true
nvr:
fake_camera:
webserver:
auth:
session_expiry:
days: 7
logger:
default_level: info
逐段解读:
- 顶层每个键就是一个组件名(ffmpeg、mog2、darknet、nvr、webserver、logger,以及可选的 mqtt、storage 等),Viseron 按「同名组件模块」加载,写错组件名会在启动日志里直接报模块缺失(见 3.4 节实测)。
nvr:下按摄像头标识逐个开启 NVR 协调,是事件与录像联动的总开关,漏掉则该摄像头「只见画面不出事件」。webserver.auth配置后所有 REST API 需要认证;logger.default_level控制全局日志级别。
3.2 通过 REST API 查看当前生效配置(实测)
改完配置后最可靠的确认方式是问服务本身:GET /api/v1/config 返回当前实际生效的配置(YAML 文本)。本环境已启用认证,先用管理账号在 Web UI(Profile 页)创建个人访问令牌(PAT),之后请求带 Authorization: Bearer 头即可:
# 查看当前生效配置(PAT 从 Web UI Profile 页创建)
curl -s -H "Authorization: Bearer vpat_eca2bf1a0881444ba2851348260bba724319b066cbd551a7813d06e5f321fc87f0834e09d1ea100129ff7b04c916a097c51176de132838b944353a716aea9f47" \
http://127.0.0.1:8888/api/v1/config
实测回显(当前环境真实输出):
ffmpeg:
camera:
fake_camera:
name: Fake Camera
host: mediamtx
port: 8554
path: /cam
stream_format: rtsp
fps: 12
recorder:
idle_timeout: 5
mog2:
motion_detector:
cameras:
fake_camera:
fps: 2
darknet:
object_detector:
model_path: /detectors/models/darknet/yolov7-tiny.weights
model_config: /detectors/models/darknet/yolov7-tiny.cfg
cameras:
fake_camera:
fps: 2
scan_on_motion_only: false
labels:
- label: person
confidence: 0.7
trigger_event_recording: true
- label: bicycle
confidence: 0.7
trigger_event_recording: true
- label: car
confidence: 0.7
trigger_event_recording: true
nvr:
fake_camera:
webserver:
auth:
session_expiry:
days: 7
logger:
default_level: info
回显与磁盘上的 config.yaml 一致,说明该接口读的就是生效配置,可以用来核对「我改的到底生效了没」。
3.3 修改与生效:编辑 → 重启(实测)
修改 /config/config.yaml 后重启 Viseron 服务生效(部署篇的 Compose 环境用 docker compose restart viseron;Web UI 左侧 Configuration 页内置编辑器,保存后同样触发重启)。每次重启都完整走一遍「初始化 → 校验 → 装载组件 → 装载域」流程,本篇做参数实验时重启了 4 轮,每轮的启动日志结构都一致:
# 重启后跟踪主日志,确认装载结果
tail -f /config/viseron.log
实测回显(一轮完整启动,输出节选):
2026-10-30 11:32:49.166 [INFO ] [viseron.core] - -------------------------------------------
2026-10-30 11:32:49.167 [INFO ] [viseron.core] - Initializing Viseron 3.7.0
2026-10-30 11:32:49.168 [INFO ] [viseron.components] - Setting up component data_stream
2026-10-30 11:32:49.170 [INFO ] [viseron.components] - Setup of component webserver took 0.0 seconds
2026-10-30 11:32:49.172 [INFO ] [viseron.components] - Setting up component storage
2026-10-30 11:32:49.184 [INFO ] [viseron.components.storage] - Database connection established successfully
2026-10-30 11:32:49.202 [INFO ] [viseron.components] - Setup of component darknet took 0.0 seconds
2026-10-30 11:32:49.204 [INFO ] [viseron.components] - Setup of component mog2 took 0.0 seconds
2026-10-30 11:32:49.204 [INFO ] [viseron.components] - Setting up component ffmpeg
2026-10-30 11:32:49.206 [INFO ] [viseron.components] - Setting up component nvr
2026-10-30 11:32:49.241 [INFO ] [viseron.domains] - Setting up domain camera with identifier fake_camera for component ffmpeg
2026-10-30 11:32:53.796 [INFO ] [viseron.domains] - Setup of domain camera with identifier fake_camera for component ffmpeg took 3.5 seconds
2026-10-30 11:32:54.104 [INFO ] [viseron.domains] - Setup of domain object_detector with identifier fake_camera for component darknet took 0.5 seconds
2026-10-30 11:32:54.109 [INFO ] [viseron.components.nvr.nvr.fake_camera] - NVR for camera Fake Camera initialized
2026-10-30 11:32:54.562 [INFO ] [viseron.core] - Viseron initialized in 5.4 seconds
验证要点:看到 Viseron initialized in N seconds 即代表全部组件与域装载成功;任何一个组件校验失败,对应行会变成 Setup of component mog2 failed 这样的失败行(3.4 节有实测原文),且相关域会被禁用。
3.4 非法参数的校验行为(实测)
Viseron 对配置的校验发生在启动阶段,错误信息非常具体。本篇实测了两类典型错误:
错误一:顶层出现未知键。config.yaml 顶层写了一个不存在的键 nonexistent_key_check: true——顶层键会被当作组件名去加载,日志直接报模块缺失:
2026-10-30 11:06:23.800 [INFO ] [viseron.components] - Setting up component nonexistent_key_check
2026-10-30 11:06:23.806 [ERROR ] [viseron.components] - Failed to load component nonexistent_key_check: No module named 'viseron.components.nonexistent_key_check'
错误二:参数类型/取值非法。把 mog2 的 fps 写成字符串 notanumber,校验器精确报出出错路径与值:
2026-10-30 11:06:23.806 [ERROR ] [viseron.components] - Error validating config for component mog2: expected float for dictionary value @ data['mog2']['motion_detector']['cameras']['fake_camera']['fps']. Got 'notanumber'
2026-10-30 11:06:23.814 [ERROR ] [viseron.components] - Setup of component mog2 failed
2026-10-30 11:06:28.269 [INFO ] [viseron.components.nvr.nvr.fake_camera] - Motion detector is disabled
两条实测结论:
- 校验失败只禁用该组件,不影响其余组件启动(上例 ffmpeg/darknet/nvr 正常装载,只是运动检测被禁用);
- 错误信息给出完整的 YAML 路径与非法值,照着改即可,无需查文档。
⚠️ 注意:
nvr域启动时会打印Motion detector is disabled或Object detector is disabled提示哪些检测器没起来。生产上重启后务必扫一眼这两行,避免「以为在检测,实际早就被禁用」。
四、参数总览
按配置域汇总本篇覆盖的参数(默认值取自 3.7.0 内置校验 schema,行为均经实测验证):
| 配置域 | 关键参数 | 默认值 | 作用一句话 |
|---|---|---|---|
| ffmpeg.camera | host / port / path | 无(必填) | RTSP 地址三要素 |
| ffmpeg.camera | stream_format | rtsp | 信令格式(rtsp/mjpeg) |
| ffmpeg.camera | fps | 无(取流帧率) | 送检帧率上限 |
| ffmpeg.camera | rtsp_transport | tcp | RTSP 传输方式 |
| ffmpeg.camera.recorder | lookback | 5 | 录像向前回溯秒数 |
| ffmpeg.camera.recorder | idle_timeout | 10 | 事件结束后延录秒数 |
| ffmpeg.camera.recorder | max_recording_time | 300 | 单次录像最长秒数 |
| ffmpeg.camera.recorder | continuous_recording | true | 是否开启持续录像 |
| ffmpeg.camera.recorder | create_event_clip | false | 是否生成事件片段 mp4 |
| ffmpeg.camera.still_image | refresh_interval | 10 | 静态图刷新秒数 |
| mog2.motion_detector.cameras | fps | 1 | 运动检测帧率 |
| mog2.motion_detector.cameras | area | 0.08 | 触发运动的最小面积占比 |
| mog2.motion_detector.cameras | width / height | 300 / 300 | 背景建模前帧缩放尺寸 |
| mog2.motion_detector.cameras | threshold | 15 | 像素判运动的帧差阈值(0~255) |
| mog2.motion_detector.cameras | history | 500 | 参与背景建模的历史帧数 |
| mog2.motion_detector.cameras | detect_shadows | false | 是否把阴影计入运动 |
| mog2.motion_detector.cameras | learning_rate | 0.01 | 背景模型学习速率(-1~1) |
| mog2.motion_detector.cameras | trigger_event_recording | false | 运动是否触发录像 |
| mog2.motion_detector.cameras | recorder_keepalive | true | 无物体时运动维持录像 |
| mog2.motion_detector.cameras | max_recorder_keepalive | 30 | 运动维持录像的上限秒数 |
| darknet.object_detector | model_path / model_config | 内置默认 | 检测模型权重/结构文件 |
| darknet.object_detector.cameras | fps | 1 | 检测帧率 |
| darknet.object_detector.cameras | scan_on_motion_only | true | 仅在运动时检测 |
| darknet.object_detector.cameras | max_frame_age | 2 | 丢弃过老帧的秒数 |
| darknet.object_detector.cameras.labels | confidence | 0.8 | 单标签置信度阈值 |
| darknet.object_detector.cameras.labels | trigger_event_recording | true | 命中是否触发录像 |
| darknet.object_detector.cameras.labels | store | true | 命中是否入库+快照 |
| darknet.object_detector.cameras.labels | store_interval | 60 | 入库/快照间隔秒数 |
| darknet.object_detector.cameras.labels | require_motion_overlap | false | 检测框需与运动轮廓重叠(3.7.0 新增) |
| darknet.object_detector.cameras.labels | motion_overlap_threshold | 0.1 | 重叠占比阈值 |
| storage | recorder.tiers[].events.max_age.days | 7 | 事件录像默认保留天数 |
| storage | snapshots.tiers[].max_age.days | 7 | 快照默认保留天数 |
| mqtt | broker / port | 无 / 1883 | MQTT 代理地址 |
| mqtt | client_id | viseron | 客户端 ID,兼作默认主题前缀 |
| mqtt | home_assistant.discovery_prefix | homeassistant | HA 发现前缀 |
| webserver | port | 8888 | Web/API 监听端口 |
| webserver.auth | session_expiry.days | 无(必填于 auth) | 会话有效期 |
| webserver.auth.rate_limits | login | 10 次 / 60 秒 | 登录限流 |
| logger | default_level | info | 全局日志级别 |
解读:整张表按「取流 → 运动检测 → 物体检测 → 录像 → 存储保留 → 对外接口」的数据流顺序排列,与下文各节顺序一致;加粗行为对资源占用/磁盘量影响最大的三个参数——fps(检测帧率)、scan_on_motion_only(是否常开检测)、max_age(保留时长),生产环境优先调这三个。
五、核心参数分类详解
5.1 ffmpeg:取流与录制通道
ffmpeg 组件负责从摄像头拉流、解码出帧送给检测器,并在录像时生成视频分段。它内部内置了 FFmpeg 8.1,命令行由 Viseron 自动拼装,绝大多数场景无需手写命令:
ffmpeg:
camera:
fake_camera:
name: Fake Camera # 摄像头显示名
host: mediamtx # RTSP 主机
port: 8554 # RTSP 端口
path: /cam # RTSP 路径
stream_format: rtsp # 信令格式:rtsp 或 mjpeg
fps: 12 # 送检帧率
rtsp_transport: tcp # RTSP 传输方式,默认 tcp
recorder:
idle_timeout: 5 # 录像参数,见 5.4
逐项说明:
- host / port / path:摄像头地址三要素。真实摄像头典型写法如
host: 192.168.1.64、port: 554、path: /Streaming/Channels/101/(海康主码流)。 - username / password:摄像头认证凭据,未配置表示匿名;同时支持
protocol: https(mjpeg over https)。 - stream_format:
rtsp(默认)或mjpeg。mjpeg 常见于老式网络摄像头的 HTTP MJPEG 端点。 - fps:不写则沿用流自身帧率;写了则以该值上限送帧。它是资源消耗的第一杠杆——12fps 的流配
fps: 12与fps: 5,CPU 差异立现。 - rtsp_transport:默认
tcp。UDP 丢包严重时保持 tcp 即可;某些老设备只支持 udp 时改此值。 - substream:可选子码流配置(独立 path/port/stream_format),检测走子码流、录制走主码流的经典用法。
- width / height:不写按流分辨率;摄像头流异常时可强制指定。
💡 技术拓展:RTSP 拉流的传输方式不止一种——
rtsp_transport可选 tcp / udp / udp_multicast / http。tcp 可靠但偶发队头阻塞;udp 延迟低但丢包会花屏;multicast 适合一录多播的内网;http 走 RTSP over HTTP 隧道穿透防火墙。本篇实测环境与生产内网直连场景均采用默认tcp(丢包率为零的内网,可靠性优先)。
实测验证:本轮参数实验把 fps 从 12 调成 2(模拟低配机器送检),重启后域装载成功且事件照常产生——fps 只影响送检节奏,不改变流本身:
2026-10-30 11:32:53.796 [INFO ] [viseron.domains] - Setup of domain camera with identifier fake_camera for component ffmpeg took 3.5 seconds
5.2 mog2:运动检测
mog2 是运动检测域的实现组件(OpenCV MOG2 背景建模)。按摄像头逐一开启:
mog2:
motion_detector:
cameras:
fake_camera:
fps: 5 # 运动检测帧率
area: 0.05 # 触发运动的最小面积占比
trigger_event_recording: true # 运动触发事件录像
recorder_keepalive: true # 无物体时运动维持录像
max_recorder_keepalive: 20 # 运动维持录像上限(秒)
逐项说明:
- fps:运动检测执行帧率,默认 1。运动检测在缩小到 300x300 的帧上做背景建模(
width/height可改),本身很轻,但对多摄像头场景仍是「摄像头数 × fps」的固定开销。 - area:画面中变化区域占整帧的最小比例,默认 0.08(8%)。调小更灵敏(易误报),调大更迟钝(漏报远处小目标)。实测把 area 从默认 0.08 调到 0.05、fps 调到 5 后,一小时内产生 101 条 motion 事件(REST API
/events/fake_camera统计),样例视频中行人入画即可触发。 - trigger_event_recording:默认 false——纯运动不录像,只有物体检测命中才录。设为 true 后运动本身也会触发录像。实测:把三个物体标签的
trigger_event_recording全部关掉、只留运动触发,录像列表立即出现trigger_type: motion的记录:
{"camera_identifier": "fake_camera", "type": "recording", "id": 299, "trigger_type": "motion",
"start_time": "2026-10-30T03:24:25.145719+00:00", "end_time": "2026-10-30T03:24:38.723120+00:00",
"duration": 13.577, "hls_url": "/api/v1/hls/fake_camera/299/index.m3u8",
"thumbnail_path": "/files/thumbnails/fake_camera/299.jpg", "lookback": 3}
- recorder_keepalive / max_recorder_keepalive:物体消失但画面仍有运动时,默认让录像继续(keepalive),上限 30 秒防「无限录像」(如对着一棵随风摇的树)。设 0 关闭上保。
- max_motion_duration:运动状态最长保持秒数,默认 0(不限制),是外部运动源(如 PIR 传感器经 MQTT 送 on 后失联)的安全阀。
- width / height / threshold / history / detect_shadows / learning_rate:MOG2 背景建模的六个细调参数,默认值分别为
300/300/15/500/false/0.01。含义逐个说:width、height是参与建模前把帧缩放到的目标尺寸(固定缩到 300x300 一类的低分辨率再算背景,省掉大半算力);threshold是当前帧与背景模型逐像素比较的差值门槛(取值 0~255,越小越灵敏,风草晃动的场景调大可压制误报);history是参与背景建模的历史帧数(越大背景越稳定,但适应缓慢光照变化越慢);detect_shadows开启后阴影也判为运动(更准但更耗资源,默认关闭);learning_rate控制背景模型学习速率(0 表示模型完全不更新、1 表示完全用上一帧重建,负值由算法自动选择)。日常场景默认即可,灵敏度优先只动threshold与area两个旋钮。 - mask:排除区域列表(多边形坐标),把不影响判断却常刮风下雨的天空、树梢划出检测范围,
coordinates至少 3 个点围成多边形(官方文档建议用 image-map.net 之类的多边形工具画完直接取坐标):
mog2:
motion_detector:
cameras:
fake_camera:
mask:
- coordinates:
- x: 400
y: 200
- x: 1000
y: 200
- x: 1000
y: 750
- x: 400
y: 750
💡 技术拓展:运动检测算法不止 MOG2 一家。常见同类对比——
算法/实现 原理 特点 MOG2(本篇采用) 高斯混合背景建模 OpenCV 内置,自适应多模态背景,Viseron 的 mog2 组件 KNN 背景建模 K 近邻背景建模 对缓慢光照变化更稳,计算量略高 帧差法 相邻帧差分 最轻量,空洞明显,适合粗筛 外部传感器 PIR/门磁经 MQTT 送信号 零算力,Viseron 可把 MQTT 运动源接入同一 motion_detector 域 Viseron 的域抽象允许混用:一台摄像头用 mog2,另一台接 MQTT 外部运动源,NVR 层不感知差异。
5.3 darknet:物体检测与 labels 过滤
darknet 是物体检测域的实现组件,加载 YOLO 系权重做推理。模型路径 + 按摄像头的检测参数与标签过滤是其全部内容:
darknet:
object_detector:
model_path: /detectors/models/darknet/yolov7-tiny.weights # 权重
model_config: /detectors/models/darknet/yolov7-tiny.cfg # 网络结构
cameras:
fake_camera:
fps: 2 # 检测帧率
scan_on_motion_only: false # 是否仅运动时检测
max_frame_age: 5 # 帧最大年龄(秒)
labels:
- label: person
confidence: 0.5
trigger_event_recording: true
store_interval: 30
逐项说明:
- model_path / model_config / label_path:模型三件套。官方环境内置 YOLO 模型于
/detectors/models/darknet/,换自定义模型时把权重文件放进来并改这两个路径即可。 - fps:检测执行帧率,默认 1。这是最贵的参数——YOLOv7-tiny 在纯 CPU 上单帧推理约 0.7 秒(本环境实测
/tune接口报 inference_fps 1.4,即每秒 1.4 帧),fps 设 5 意味着推理队列积压、CPU 打满。多摄像头场景宁可降 fps。 - scan_on_motion_only:默认 true——只在运动检测到目标时才跑物体检测,CPU 占用大幅下降;关闭则持续检测。实测开启时日志呈清晰的「运动来 → 检测器起,事件结束 → 检测器停」交替:
2026-10-30 11:22:37.525 [DEBUG ] [viseron.components.nvr.nvr.fake_camera] - Starting object detector
2026-10-30 11:22:50.567 [DEBUG ] [viseron.components.nvr.nvr.fake_camera] - Not recording, pausing object detector
2026-10-30 11:23:31.366 [DEBUG ] [viseron.components.nvr.nvr.fake_camera] - Starting object detector
2026-10-30 11:23:45.331 [DEBUG ] [viseron.components.nvr.nvr.fake_camera] - Not recording, pausing object detector
- max_frame_age:待检帧的最大年龄(秒),默认 2。推理慢于取流时老帧直接丢弃,防止「检测结果是几秒前的画面」。
- labels[]:跟踪标签列表(不写则跟踪全部标签)。
- confidence:单标签置信度阈值,默认 0.8。实测把 person/bicycle/car 全部降到 0.5 后,事件流里出现 0.526~0.6 区间的低置信事件(0.7 阈值下这些会被过滤);同帧同标签多余检测由 suppression(默认 0.5)做非极大值抑制。
- trigger_event_recording:命中即触发事件录像,默认 true;配合 5.2 的运动触发形成双通道。
- store / store_interval:是否入库并保存快照(默认 true,总是存),入库间隔默认 60 秒;实测设为 30 后同一目标每 30 秒落一条 object 事件。
- height_min/height_max/width_min/width_max:按目标框相对宽高过滤(如
height_max: 0.5过滤掉近景占屏一半以上的误检)。 - require_motion_overlap / motion_overlap_threshold:3.7.0 新增——要求检测框与运动轮廓重叠(占比默认 0.1)才算有效目标,专治「画面里有车停着不动,检测器一直触发」的 stationary object 问题;旧参数
require_motion(物体消失即停录)仍保留,两者语义不同。
5.4 recorder:录像行为参数
录像参数挂在 ffmpeg.camera.<名称>.recorder 下(由 camera 域的 RECORDER_SCHEMA 定义),控制「事件前后录多少、录多长、产物是什么」:
recorder:
lookback: 5 # 事件发生前回溯录像秒数
idle_timeout: 10 # 事件结束后延录秒数
max_recording_time: 300 # 单次录像硬上限(秒)
continuous_recording: true # 持续录像开关
create_event_clip: false # 事件片段 mp4 开关
thumbnail:
save_to_disk: true # 录像缩略图落盘
逐项说明(均实测验证):
- lookback(默认 5):触发录像时把事件前 5 秒已缓存的分段并入录像文件。实测改为 3 后,事件 API 返回的录像对象中
"lookback": 3生效。 - idle_timeout(默认 10):事件结束后画面安静多少秒才停录,日志以秒级倒计时可视化。实测从 5 调到 10,倒计时上限同步变成 10s:
2026-10-30 11:18:22.311 [DEBUG ] [viseron.components.ffmpeg.recorder.fake_camera] - Saving thumbnail in /thumbnails/fake_camera
2026-10-30 11:18:23.268 [INFO ] [viseron.components.nvr.nvr.fake_camera] - Stopping recording in: 10s
2026-10-30 11:18:24.270 [INFO ] [viseron.components.nvr.nvr.fake_camera] - Stopping recording in: 9s
...(节选:8s~1s 各行逐秒递减)
2026-10-30 11:18:33.199 [INFO ] [viseron.components.nvr.nvr.fake_camera] - Stopping recording in: 0s
- max_recording_time(默认 300):单次录像最长 5 分钟,防止目标一直不离开画面导致无限录像;与 5.2 的
max_recorder_keepalive、5.3 的require_motion_overlap构成三重保险。 - continuous_recording(默认 true):开启后即使没有事件也持续写分段,事件录像由这些分段拼装而成(这是 lookback 能回溯的前提);磁盘紧张时置 false 只保留事件录像。
- create_event_clip(默认 false):开启后每次事件额外产出
/event_clips/<camera>/<id>.mp4单文件片段,便于直接转发(不开则只存分段,靠 HLS 回放)。 - filename_pattern(默认
%H:%M:%S):持续录像分段的文件名时间格式。 - schedule:3.7.0 新增的按 cron 表达式的录像计划——
schedule.events: [{start: "0 9 * * *", end: "30 18 * * *"}]表示仅工作时段内的事件录像;schedule.continuous同理控制持续录像时段;schedule.timezone指定计划时区。
5.5 storage:存储分层与保留策略
storage 组件管理所有落盘数据的保留。默认配置等价于「事件录像与快照各保留 7 天」,分层(tier)模型支持把老数据挪到慢盘:
storage:
tier_check_cpu_limit: 10 # tier 检查任务的 CPU 限额(%)
tier_check_workers: 4 # 检查并行度
tier_check_batch_size: 5 # 每批处理文件数
tier_check_sleep_between_batches: 0.5
recorder:
tiers:
- path: / # 录像数据根
check_interval:
minutes: 30 # 每层检查频率
events: # 事件录像的保留策略
max_age:
days: 7 # 保留 7 天
max_size:
gb: 50 # 或容量上限 50GB(先到先删)
continuous: # 持续录像的保留策略(结构同上)
max_age:
days: 2
snapshots:
tiers:
- path: /
max_age:
days: 7 # 快照保留 7 天
逐项说明:
- tiers[]:分层列表,每层一个
path(如/与/mnt/archive/两层:第一层写满或到期后向下一层转移,poll: true/move_on_shutdown: true控制转移时机,drain: true清空本层)。对单盘场景一层即可。 - events / continuous / max_age / max_size:事件录像与持续录像分别设保留策略,
max_age(days/hours/minutes)与max_size(gb/mb)先到者触发清理;min_age/min_size则保护「太新/太小」的文件不被误删。 - check_interval(默认全 0,即交给内置调度节奏):每层清理检查的间隔,密集写入时可加密。
- 实测佐证:默认保留策略下,录像分段按时间戳落在
/segments/<camera>/<unix_ts>.m4s(实测目录列表):
/segments/fake_camera/1793326549.m4s
/segments/fake_camera/1793327834.m4s
/segments/fake_camera/1793328504.m4s
/segments/fake_camera/1793329348.m4s
缩略图与快照同样按域分目录:/thumbnails/<camera>/<录像id>.jpg 与 latest_thumbnail.jpg、/snapshots/<检测组件>/<camera>/<时间戳>-<uuid>.jpg 与 latest_snapshot.jpg,与 storage 的 subcategory 设计一致。
⚠️ 注意:
max_size按 tier 内文件总量计算而非单文件;删除动作在 DEBUG 日志中为Deleting file <path>,排查「录像怎么没了」时把viseron.components.storage日志级别临时调到 debug 即可看到判定过程。
5.6 mqtt:MQTT 事件输出
mqtt 组件把 Viseron 的实体状态实时发布到 MQTT 代理,是接入 Home Assistant 或自建告警管道的标准通道。本环境实测时部署了 Eclipse Mosquitto 2.1.2 作为代理,配置:
mqtt:
broker: mqtt # 代理地址(本实验内网服务名)
port: 1883 # 默认 1883
client_id: viseron # 客户端 ID,兼作默认主题前缀
# username / password:代理需要认证时填写
# base_topic:不写则用 client_id 作为主题前缀
重启后组件装载成功,并立即在代理上出现 retained 的存活状态与实体主题:
2026-10-30 11:26:23.508 [INFO ] [viseron.components] - Setting up component mqtt
2026-10-30 11:26:23.588 [INFO ] [viseron.components] - Setup of component mqtt took 0.0 seconds
用 mosquitto_sub -t 'viseron/#' -v 抓取 150 秒,实测主题分布如下(节选):
| 主题 | 载荷(实测节选) | 说明 |
|---|---|---|
| viseron/lwt | alive | 遗嘱主题:进程异常退出时代理代发离线 |
| viseron/state | online | 在线状态 |
| viseron/binary_sensor/fake_camera_motion_detected/state | {"state": "on", ...} | 运动检测二值状态 |
| viseron/binary_sensor/fake_camera_recorder/state | {"state": "on", "attributes": {... "id": 302, "trigger_type": "motion"}} | 录像状态,含完整录像属性 |
| viseron/binary_sensor/fake_camera_object_detected_car/state | {"state": "on", "attributes": {"count": 1, "objects": [{"label": "car", "confidence": 0.733, "rel_x1": 0.0, ...}]}} | 分标签检测状态,含目标框坐标 |
| viseron/sensor/fake_camera_operation_state/state | {"state": "recording"} | 运行状态机(scanning_for_motion/recording/scanning_for_objects) |
| viseron/sensor/fake_camera_object_detector_fps/state | {"state": 1.4, "attributes": {"inference_fps": 1.4, "theoretical_max_fps": 1.4}} | 推理帧率传感器 |
| viseron/image/fake_camera_latest_thumbnail/image | (二进制 JPEG) | 最新缩略图原图 |
| viseron/image/fake_camera_latest_thumbnail/attributes | {"attributes": {...}} | 缩略图元数据 |
| viseron/toggle/fake_camera_manual_recording/state | {"state": "off", ...} | 手动录像开关状态 |
实测的一条完整状态链(运动出现 → 录像 → 物体命中 → 收尾):
viseron/binary_sensor/fake_camera_motion_detected/state {"state": "on", ...}
viseron/binary_sensor/fake_camera_recorder/state {"state": "on", "attributes": {... "id": 302, ... "trigger_type": "motion"}}
viseron/sensor/fake_camera_operation_state/state {"state": "recording", ...}
viseron/binary_sensor/fake_camera_object_detected_car/state {"state": "on", "attributes": {"count": 1, "objects": [{"label": "car", "confidence": 0.733, ...}]}}
viseron/binary_sensor/fake_camera_object_detected_car/state {"state": "off", "attributes": {... "count": 0, "objects": []}}
viseron/binary_sensor/fake_camera_recorder/state {"state": "off", "attributes": {... "id": 302, "end_time": "2026-10-30T03:28:14.541423+00:00", ...}}
viseron/sensor/fake_camera_operation_state/state {"state": "scanning_for_objects", ...}
(以上为实测消息流节选,主题与 state 字段为原文,较长 attributes 以 ... 截短,完整属性见上文主题表。)
MQTT 不只下行发布,还能反向控制。开关实体的命令主题是 <base_topic>/toggle/<camera>_manual_recording/command,实测发布 JSON 载荷触发了一次 5 秒手动录像,录像系统随即出现 trigger_type: manual 的记录(id 306):
mosquitto_pub -t "viseron/toggle/fake_camera_manual_recording/command" \
-m '{"action":"start","duration":5}'
- home_assistant:子配置
home_assistant: {enabled: true}(组件内默认开启发现前缀homeassistant、retain_config默认 true)会把每个实体发布为 HA MQTT Discovery 配置,HA 侧零配置自动发现全部传感器、二值传感器与开关。 - publish_states_on_reconnect(默认 true):代理闪断重连后自动重发全部状态,订阅方无需等下一次变化。
5.7 nvr:摄像头协调器
nvr 组件的配置极度简单——按摄像头标识逐个开空段即可,它是「让检测器/录像器/实体开始协同」的注册表:
nvr:
fake_camera: # 与 ffmpeg.camera 下的标识一致
# second_camera: # 多摄像头时逐个列出
实测说明:nvr.<camera> 段内部当前没有参数(3.7.0 的 schema 为空 dict,保留扩展位),它的作用是声明「该摄像头启用 NVR 域」。缺了它,该摄像头能显示画面但不会产生运动/物体/录像实体;配置后日志出现初始化完成行:
2026-10-30 11:32:54.109 [INFO ] [viseron.components.nvr.nvr.fake_camera] - NVR for camera Fake Camera initialized
5.8 webserver:Web/API、认证与限流
webserver 组件承载 Web UI 与全部 REST API:
webserver:
port: 8888 # Web/API 监听端口,默认 8888
debug: false # 调试模式
auth:
session_expiry:
days: 7 # 浏览器会话有效期
rate_limits:
login: # 登录接口限流(默认值如下)
max_attempts: 10
window_seconds: 60
token:
max_attempts: 30
window_seconds: 60
onboarding:
max_attempts: 5
window_seconds: 60
逐项说明(限流为实测验证):
- port:默认 8888,与部署篇的宿主端口映射
8151:8888对应。 - auth.session_expiry:浏览器会话有效期,
days/hours/minutes三档可组合;本环境设 7 天。 - auth.rate_limits:按接口的滑动窗口限流。实测对登录接口连续输错密码,第 1~10 次返回
401 {"status": 401, "error": "Invalid username or password"},第 11 次起被限流:
attempt 1 => {"status": 401, "error": "Invalid username or password"}|401
attempt 2 => {"status": 401, "error": "Invalid username or password"}|401
...(3~10 次同为 401,略)
attempt 11 => {"status": 429, "error": "Too many requests, please try again later"}|429
attempt 12 => {"status": 429, "error": "Too many requests, please try again later"}|429
- public_base_url / public_url_expiry_hours / public_url_max_downloads:生成对外分享链接时的基础地址与链接有效期/下载次数(默认 24 小时、不限次数)。
5.9 logger:日志级别
logger 组件控制全局与细粒度日志:
logger:
default_level: info # 全局级别
logs:
viseron.components.ffmpeg.recorder: debug # 指定 logger 名调到 debug
viseron.components.nvr: debug
逐项说明:
- default_level:全局级别,默认 info。
- logs:按 logger 名(即 Python 模块路径)单独调级,排障利器。实测给
viseron.components.nvr开 debug 后,日志出现逐帧年龄判定与检测器暂停明细:
2026-10-30 11:24:33.311 [DEBUG ] [viseron.components.nvr.nvr.fake_camera] - Frame is 1.1518199443817139 seconds old. Discarding
2026-10-30 11:24:38.833 [DEBUG ] [viseron.components.nvr.nvr.fake_camera] - Not recording, pausing object detector
给 viseron.components.ffmpeg.recorder 开 debug 后能看到缩略图保存动作(见 5.4 实测回显)。日志同时可通过 REST API GET /api/v1/logger/logs?lines=12 拉取(Web UI 内置日志查看器即用此接口,3.7.0 新特性)。
六、生产配置模板
一套面向「4 路摄像头、8GB 内存、NVMe 单盘、7 天事件保留」的生产基线(本篇参数均在同环境实测过单项行为,模板组合为推荐值):
ffmpeg:
camera:
front_door:
name: Front Door
host: 192.168.1.64
port: 554
path: /Streaming/Channels/102/ # 用子码流送检,降低解码压力
stream_format: rtsp
fps: 5
rtsp_transport: tcp
recorder:
lookback: 5
idle_timeout: 10
max_recording_time: 300
create_event_clip: true
mog2:
motion_detector:
cameras:
front_door:
fps: 3
area: 0.08
trigger_event_recording: true
max_recorder_keepalive: 30
darknet:
object_detector:
model_path: /detectors/models/darknet/yolov7-tiny.weights
model_config: /detectors/models/darknet/yolov7-tiny.cfg
cameras:
front_door:
fps: 1 # CPU 推理场景 1fps 起步,有 GPU/TPU 再加
scan_on_motion_only: true # 纯 CPU 生产必须开
labels:
- label: person
confidence: 0.7
trigger_event_recording: true
require_motion_overlap: true
- label: car
confidence: 0.7
trigger_event_recording: true
require_motion_overlap: true
mqtt:
broker: 192.168.1.10 # 内网 MQTT 代理
port: 1883
client_id: viseron
nvr:
front_door:
webserver:
port: 8888
auth:
session_expiry:
days: 7
rate_limits:
login:
max_attempts: 10
window_seconds: 60
logger:
default_level: info
storage:
recorder:
tiers:
- path: /
check_interval:
hours: 1
events:
max_age:
days: 7
max_size:
gb: 200
continuous:
max_age:
days: 2
snapshots:
tiers:
- path: /
max_age:
days: 7
适用边界与理由:
- 资源档位:8GB 内存 / 4 核 CPU / NVMe。
scan_on_motion_only: true是纯 CPU 部署的省算力关键(实测检测器随录像启停,空闲期零推理开销);检测帧率 1fps 时单路推理开销约一核的 60~70%(实测/tune报 inference_fps 1.4,即单路占满约 0.7 核)。 - 磁盘估算:单路 5fps 子码流 + 持续录像约 1~2GB/天,
continuous.max_age: days: 2+events.max_age: days: 7+max_size: gb: 200三层兜底,NVMe 盘 500GB 余量充足。 - 场景假设:门口/车道类场景,person/car 是核心关注目标;
require_motion_overlap: true(3.7.0 新增)过滤静止物体的重复触发。 - 多路扩展:每加一路摄像头复制
front_door段并改标识(标识只能用小写字母/数字/下划线),CPU 按每路约 1 核预留;有 Coral TPU 时把 darknet 换成 edgetpu 组件并将 fps 提到 5。
七、常见问题
Q1:改了 config.yaml 不生效?
配置只在启动时读取。docker compose restart viseron(部署篇环境)或 Web UI Configuration 页保存即触发重启;重启后用 GET /api/v1/config(3.2 节)核对生效值,别只看文件。
Q2:启动报 Failed to load component xxx: No module named 'viseron.components.xxx'?
顶层键名写错了——顶层每个键必须是真实组件名(如 mog2、darknet),拼错的键会被当作组件去加载(3.4 节错误一实测原样报错)。
Q3:启动报 Error validating config for component xxx: expected float ... Got 'notanumber'?
参数类型错误,报错里的 data['组件']['域']['cameras']['标识']['参数'] 就是精确路径,改成正确类型(fps 要数字)即可(3.4 节错误二实测)。校验失败只禁用该组件,其余功能不受影响,但重启后要确认对应域没有 disabled。
Q4:检测明明配置了,日志却显示 Motion detector is disabled?
该组件校验失败被禁用了(常见于 Q3 的类型错误),去启动日志找 Setup of component xxx failed 定位。
Q5:CPU 占用过高?
三个杠杆按顺序调:darknet ... scan_on_motion_only 设 true(实测空闲期检测器完全暂停)、检测 fps 降到 1、运动检测 fps 降到 1~2。再不够就换子码流(substream)送检或上硬件加速组件。
Q6:录像一直不停或文件巨大?
三重保险按需收紧:recorder.max_recording_time(硬上限)、mog2 ... max_recorder_keepalive(运动维持上限)、labels 上 require_motion_overlap: true(静止物体不再触发)。磁盘总量兜底交给 storage 的 max_size。
Q7:MQTT 主题里 image 主题全是乱码?
viseron/image/.../image 主题载荷就是原始 JPEG 二进制,文本终端显示乱码是正常现象;订阅时避开 image 主题(如 viseron/# -v 改为 viseron/binary_sensor/#、viseron/sensor/#)即可。
Q8:登录一直 429? webserver 登录限流默认 10 次/60 秒(实测第 11 次起 429),等窗口过去或从其他正常途径(Web UI)登录;生产上不建议放宽,它是暴力破解的第一道闸。
八、参考链接
- Viseron 官方配置文档:https://viseron.netlify.app/docs/documentation/configuration
- FFmpeg 组件文档:https://viseron.netlify.app/docs/components/ffmpeg
- NVR 组件文档:https://viseron.netlify.app/docs/components/nvr
- MQTT 组件文档:https://viseron.netlify.app/docs/components/mqtt
- v3.7.0 发布说明(require_motion_overlap、cron 录像计划等新特性):https://github.com/roflcoopter/viseron/releases/tag/v3.7.0
- Viseron 仓库:https://github.com/roflcoopter/viseron
- 本专栏姊妹篇:《Viseron 3.7.0 介绍与选型指南》 | 《Viseron 3.7.0 Docker Compose 部署指南》 | 《Viseron 3.7.0 API 使用详解》