在树莓派上部署开源监控系统 ZoneMinder

原文:https://blog.iyatt.com/?p=17425

前言

自己搭建,可以用手里已有的设备,不需要额外买。这套系统的源码是公开的,录像数据也掌握在自己手里,不经过不可控的三方。

file

file

支持设置访问账号
file

可以保存录像,启用运动侦测
file
file

有配套 APP 使用
file

环境

  • 树莓派CM4
  • raspios 20240704 Debian 12 arm64
  • ZoneMinder 1.36.33

部署

参考官方文档:https://zoneminder.readthedocs.io/en/stable/installationguide/debian.html#debian-12-bookworm

配置数据库

安装 Mariadb 数据库(MySQL 开源替代品)

sudo apt update
sudo apt install -y mariadb-server

创建数据库

sudo mariadb # 连接数据库进入交互终端
CREATE DATABASE zm; # 创建数据库 zm,这个不建议自定义名字
CREATE USER zm_user@localhost IDENTIFIED BY 'zm123456'; # 创建用户 zm_user,并设置登录密码为 zm123456
GRANT ALL PRIVILEGES ON zm.* TO zm_user@localhost; # 将 zm 所有权限授予 zm_user 用户
FLUSH PRIVILEGES; # 刷新
exit; # 退出数据库交互

导入数据库结构

# zm_user 和 zm 对应前一步创建的用户名和数据库,执行后要输入上面设置的命令确认
mariadb -u zm_user -p zm < /usr/share/zoneminder/db/zm_create.sql

配置 ZoneMinder

安装软件

sudo apt install -y zoneminder apache2

更新 ZoneMinder 到最新版

sudo echo 'deb http://deb.debian.org/debian bookworm-backports main contrib' >> /etc/apt/sources.list
sudo apt update
sudo apt -t bookworm-backports install zoneminder

修改文件权限

sudo chgrp -c www-data /etc/zm/zm.conf
sudo chown -R www-data:www-data /usr/share/zoneminder/www
sudo find /usr/share/zoneminder/www -type d -exec chmod 755 {} \;
sudo find /usr/share/zoneminder/www -type f -exec chmod 644 {} \;

以 root 身份编辑 /etc/zm/zm.conf,找到ZM_DB_NAME、ZM_DB_USER、ZM_DB_PASS,分别对应前面创建的数据库、用户、密码,修改到等号后面
file

启用服务

sudo a2enconf zoneminder
sudo a2enmod cgi
sudo systemctl restart apache2.service
sudo systemctl restart zoneminder.service
sudo systemctl status zoneminder.service # 查看运行状态

使用

首次使用

访问测试
首次使用会出现隐私协议,翻到底部同意协议
file

修改地区和时区

上面从左到右第二个 option 选项,
file

语言选 zh_cn 就是中文(只是汉化不彻底,很多中英混合),还有 LOCALE_DEFAULT 选 zh_Hans_CN
file

再往下选时区,中国大陆地区的时区选亚洲上海(国际标准时区在新中国成立之前就定下来了,毕竟当时洋人多在上海,还是国际都市),修改后右下角点保存
file

添加 USB 摄像头

安装媒体工具库

sudo apt install -y v4l-utils

查看摄像头设备

v4l2-ctl --list-devices

file

这里的 imx291 就是我的 USB 摄像头,一般一个摄像头有两个 /dev/video 设备文件,其中第一个可以输出视频流,查看支持的媒体格式

v4l2-ctl -d /dev/video0 --list-formats-ext

我这里输出了下面的内容

yx@raspberrypi:~ $ v4l2-ctl -d /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMTType: Video Capture[0]: 'MJPG' (Motion-JPEG, compressed)Size: Discrete 1920x1080Interval: Discrete 0.033s (30.000 fps)Interval: Discrete 0.040s (25.000 fps)Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)Size: Discrete 1280x1024Interval: Discrete 0.033s (30.000 fps)Interval: Discrete 0.040s (25.000 fps)Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)Size: Discrete 1280x720Interval: Discrete 0.033s (30.000 fps)Interval: Discrete 0.040s (25.000 fps)Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)Size: Discrete 800x600Interval: Discrete 0.033s (30.000 fps)Interval: Discrete 0.040s (25.000 fps)Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)Size: Discrete 640x480Interval: Discrete 0.033s (30.000 fps)Interval: Discrete 0.040s (25.000 fps)Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)Size: Discrete 320x240Interval: Discrete 0.033s (30.000 fps)Interval: Discrete 0.040s (25.000 fps)Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)[1]: 'YUYV' (YUYV 4:2:2)Size: Discrete 1920x1080Interval: Discrete 0.200s (5.000 fps)Size: Discrete 1280x1024Interval: Discrete 0.200s (5.000 fps)Size: Discrete 1280x720Interval: Discrete 0.100s (10.000 fps)Size: Discrete 800x600Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)Size: Discrete 640x480Interval: Discrete 0.033s (30.000 fps)Interval: Discrete 0.040s (25.000 fps)Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)Size: Discrete 320x240Interval: Discrete 0.033s (30.000 fps)Interval: Discrete 0.040s (25.000 fps)Interval: Discrete 0.050s (20.000 fps)Interval: Discrete 0.067s (15.000 fps)Interval: Discrete 0.100s (10.000 fps)Interval: Discrete 0.200s (5.000 fps)

即支持MJPG和YUYV,以及在各种分辨率输出下支持的帧率大小

在控制台选项卡下点击新建监视器
file

取一个名字,信号源选本地
file
左侧切换到信号源,填上摄像头的设备文件路径,设置一下分辨率,就可以保存了
file
页面右上角切换状态到运行
file

由于 zoneminder 是以 www-data 用户运行的,而 /dev/video* 设备属于 video 用户组,可能没有权限访问
将 www-data 添加到 video 用户组,这样就能正常使用了

# 添加
sudo usermod -aG video www-data# 刷新
sudo newgrp video

内网穿透实现公网访问

大体还是基于这个思路:https://blog.iyatt.com/?p=17340
ZoneMinder 提供的配置方案是基于 Apache2 的,我看了好久都没搞懂怎么给 ZoneMinder 配置 https 访问,最后在本地用 Nginx 反向代理 Apache2 的 80 端口,转为 https,再用 frp 把 Nginx 代理的端口映射到公网,这样直接公网就能访问了,服务器还是新加坡的,视频先送到新加披再传回来,感觉延时都还可以,应该在 1 秒内,不会感觉明显的迟钝。

file

启用登录验证

打开选项,左侧用户栏可以创建或编辑用户
file

设置用户密码、语言、带宽限制、是否启用、可访问的设备、享有的设备权限…
设置后点击保存
file

选项左侧打开系统,勾选OPT_USE_AUTH,然后保存,这样就支持登录验证了
file

客户端程序(桌面程序、手机APP)

file
可以从 GitHub 下载:https://github.com/ZoneMinder/zmNinja/releases
我是用的 Android 手机,最开始是在 Google Play 上查找 APP,发现是收费的,后面才去 GitHub 上查找 ZoneMinder 项目,倒是可以直接下载(上面的链接)

配置 API 访问

在选项-系统中勾选OPT_USE_API然后保存,即启用 API
file

然后在选项-用户中,为指定用户启用 API,这样该用户就能在 APP 上使用了

“Login Auth Sucess but api failed”/“登录身份验证成功,但 API 失败”问题解决

APP 装上了,但是使用的时候就遇到标题的错误,网页端也能正常使用。
客户端应该是通过 API 连接的,就是这个 API 有问题。
昨天晚上就卡在这里,今天(2024.9.30)下班回家后,晚上又继续尝试解决这个问题,一直不停地在谷歌上搜索尝试,ZoneMinder 的项目 issues 找了都没解决,搜了两个小时,最后在 ZoneMinder 论坛上找到的回答解决了:https://forums.zoneminder.com/viewtopic.php?p=111193#p111193
推测就是树莓派版本的 ZoneMinder 包有问题,我用中文再转述一下解决方法:

新建一个文件名为 .htacess,写入

<IfModule mod_rewrite.c>RewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteRule ^ index.php [L]RewriteBase /zm/api
</IfModule>

修改文件所属用户和权限

sudo chown www-data:www-data .htacess
sudo chmod 644 .htacess

然后将这个文件复制到下面三个路径下面

  • /usr/share/zoneminder/www/api
  • /usr/share/zoneminder/www/api/app
  • /usr/share/zoneminder/www/api/app/webroot

可以测试访问,当可以显示版本或下图格式的错误信息的时候,就代表 API 正常工作了

地址//zm/api/host/getVersion.json

file
如果选项没有勾选OPT_USE_LEGACY_API_AUTH(旧版 API 认证,在启用 API 下一项),就会显示下面的状态,不启用也不影响 APP 使用
file

录像存储路径设置

打开选项-Storage,自己新建存储路径,填好路径并取一个名字
file

在具体的摄像头配置的 Storage 里有个存储区域,就可以选设置的路径名称
file

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/55425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《深入理解java虚拟机》——java内存区域与内存溢出异常

我是很喜欢用java语言编写代码的。从开始学习到现在其实也是在一步步体会java语言的各方面&#xff0c;开始看深入理解java虚拟机这本书觉得java虚拟机的内部感觉就像是一个操作系统&#xff0c;也可以说是个计算机。想要深入的理解我觉得需要先从整体去看。为什么需要java虚拟…

ProtoBuf快速上手

文章目录 创建 .proto文件编译 .proto文件编译后生成的文件序列化与反序列化的使用 此篇文章实现内容&#xff1a; 对一个通讯录的联系人信息&#xff0c;使用PB进行序列化&#xff0c;并将结果输出对序列化的内容使用PB进行反序列化&#xff0c;解析联系人信息并输出联系人信…

redis-数据类型

十大数据类型 学习 redis 操作手册 英文 Commands 中文 Redis命令中心&#xff08;Redis commands&#xff09; – Redis中国用户组&#xff08;CRUG&#xff09; 学习方法 举出一个数据结构的应用场景&#xff08;理解数据结构特点&#xff09;&#xff0c;并操作&…

Django学习笔记一:MVT的示例

Django的MVT&#xff08;Model-View-Template&#xff09;架构是一种将应用程序的不同部分分离的方法&#xff0c;旨在提高代码的可维护性和可扩展性。MVT将应用分解为三个主要部分&#xff1a;Model&#xff08;模型&#xff09;、View&#xff08;视图&#xff09;和Template…

【Java的SPI机制】Java SPI机制:实现灵活的服务扩展

在Java开发中&#xff0c;SPI&#xff08;Service Provider Interface&#xff0c;服务提供者接口&#xff09;机制是一种重要的设计模式&#xff0c;它允许在运行时动态地插入或更换组件实现&#xff0c;从而实现框架或库的扩展点。本文将深入浅出地介绍Java SPI机制&#xff…

JAVA开源项目 旅游管理系统 计算机毕业设计

本文项目编号 T 063 &#xff0c;文末自助获取源码 \color{red}{T063&#xff0c;文末自助获取源码} T063&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

TypeScript 封装 Axios 1.7.7

随着Axios版本的不同&#xff0c;类型也在改变&#xff0c;以后怎么写类型&#xff1f; yarn add axios1. 封装Axios 将Axios封装成一个类&#xff0c;同时重新封装request方法 重新封装request有几个好处&#xff1a; 所有的请求将从我们定义的requet请求中发送&#xff…

Vue3实现动态菜单功能

文章目录 0.效果演示1.搭建Vue3项目1.1 vite 脚手架创建 Vue3 项目1.2 设置文件别名1.3 安装配置 element-plus1.4 安装配置路由2.登录页面3.后台管理页面3.1 搭建后台框架3.2 左侧菜单栏3.3 header 用户信息3.4 主要内容3.5 footer4.配置静态路由5.记录激活菜单5.1 el-menu 绑…

卸载apt-get 安装的PostgreSQL版本

文章目录 卸载apt-get 安装的PostgreSQL版本查找已安装的PostgreSQL包卸载PostgreSQL&#xff1a;检查并删除残留文件验证卸载 卸载apt-get 安装的PostgreSQL版本 卸载通过apt-get安装的PostgreSQL 就版本&#xff0c;可以按照以下步骤进行。 查找已安装的PostgreSQL包 在卸…

信号处理快速傅里叶变换(FFT)的学习

FFT是离散傅立叶变换的快速算法&#xff0c;可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的&#xff0c;但是如果变换到频域之后&#xff0c;就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外&#xff0c;FFT可以将一个信号的频谱提取出来&am…

StarRocks 中如何做到查询超时(QueryTimeout)

背景 本文基于 StarRocks 3.1.7 主要是分析以下两种超时设置的方式: SESSION 级别 SET query_timeout 10;SELECT sleep(20);SQL 级别 select /* SET_VAR(query_timeout10) */ sleep(20); 通过本文的分析大致可以了解到在Starrocks的FE端是如何进行Command的交互以及数据流走…

Java Web 之 Cookie 详解

在 JavaWeb 开发中&#xff0c;Cookie 就像网站给浏览器贴的小纸条&#xff0c;用于记录一些用户信息或状态&#xff0c;方便下次访问时识别用户身份或进行个性化服务。 也可以这么理解&#xff1a; 场景一&#xff1a;想象一下&#xff0c;你去一家咖啡店&#xff0c;店员认…

webpack信息泄露

先看看webpack中文网给出的解释 webpack 是一个模块打包器。它的主要目标是将 JavaScript 文件打包在一起,打包后的文件用于在浏览器中使用,但它也能够胜任转换、打包或包裹任何资源。 如果未正确配置&#xff0c;会生成一个.map文件&#xff0c;它包含了原始JavaScript代码的映…

VPN简述

文章目录 VPNVPN基础VPN类型 VPN VPN隧道安全 VPN基础 背景&#xff1a; 在网络传输中&#xff0c;绝大部分数据内容都是明文传输&#xff0c;存在很多安全隐患&#xff08;窃听、篡改、冒充&#xff09; 总部、分公司、办事处、出差人员、合作单位等需要访问总部网络资源 Vi…

富格林:警悟可信经验安全投资

富格林指出&#xff0c;黄金具有不错的投资价值&#xff0c;一直以来备受投资者的喜爱&#xff0c;近年来大家也纷纷加入现货黄金市场为己增值财富。但是要为投资安全护航的前提&#xff0c;是需要投资者使用合适可信的方法以及掌握相对应的投资技巧。下面富格林将总结以下可信…

【数学分析笔记】第4章第4节 复合函数求导法则及其应用(1)

4. 微分 4.4 复合函数求导法则及其应用 4.4.1 复合函数求导法则 【定理4.4.1】 u g ( x ) ug(x) ug(x)在 x x 0 xx_0 xx0​可导&#xff0c; g ( x 0 ) u ( 0 ) g(x_0)u(0) g(x0​)u(0)&#xff0c; y f ( u ) yf(u) yf(u)在 u u 0 uu_0 uu0​可导&#xff0c;则 y f …

SpringBoot+Redis+RabbitMQ完成增删改查

各部分分工职责 RabbitMQ负责添加、修改、删除的异步操作 Redis负责数据的缓存 RabbitMQ里面角色职责简单描述 RabbitMQ里面有几个角色要先分清以及他们的对应关系&#xff1a; 交换机、队列、路由键 交换机和队列是一对多 队列和路由键是多对多 然后就是消息的发送者&…

课设实验-数据结构-线性表-手机销售

题目&#xff1a; 代码&#xff1a; #include<stdio.h> #include<string.h> #define MaxSize 10 //定义顺序表最大长度 //定义手机结构体类型 typedef struct {char PMod[10];//手机型号int PPri;//价格int PNum;//库存量 }PhoType; //手机类型 //记录手机的顺序…

【HTTP(3)】(状态码,https)

【认识状态码】 状态码最重要的目的&#xff0c;就是反馈给浏览器:这次请求是否成功&#xff0c;若失败&#xff0c;则出现失败原因 常见状态码: 200:OK&#xff0c;表示成功 404:Not Found&#xff0c;浏览器访问的资源在服务器上没有找到 403:Forbidden&#xff0c;访问被…

springboot系列--web相关知识探索三

一、前言 web相关知识探索二中研究了请求是如何映射到具体接口&#xff08;方法&#xff09;中的&#xff0c;本次文章主要研究请求中所带的参数是如何映射到接口参数中的&#xff0c;也即请求参数如何与接口参数绑定。主要有四种、分别是注解方式、Servlet API方式、复杂参数、…