当前位置: 首页 > news >正文

树莓派5-实战指南:利用群辉NAS构建高效RTSP监控系统

1. 为什么选择树莓派5+群晖NAS做监控?

如果你和我一样,既想在家里搞个靠谱的监控系统,又不想把视频数据交给云服务商,那这套组合绝对值得你花时间折腾一下。我前前后后试过不少方案,从直接用现成的家用摄像头,到用旧手机装App,再到用电脑主机挂载,最后发现,树莓派5配上群晖NAS的Surveillance Station,在稳定性、隐私性和扩展性上找到了一个完美的平衡点

简单来说,这套方案的核心思路就是:让树莓派5专心做“眼睛”和“编码器”。它利用自带的摄像头模块或者USB摄像头,实时采集视频画面,并通过RTSP协议将视频流“推送”出去。而**群晖NAS则扮演“大脑”和“仓库”**的角色,它的Surveillance Station套件负责接收、管理、录制这些视频流,并提供强大的回放、事件检测和远程查看功能。这样一来,视频数据全程都在你自己的局域网内流转,或者通过你自己可控的远程访问方式查看,隐私完全掌握在自己手里。

树莓派5作为最新一代,性能提升非常明显。它的CPU和GPU处理视频编码的能力比前几代强了不少,这意味着你可以推更高分辨率、更高帧率的视频流,而不会让树莓派“气喘吁吁”。实测下来,用树莓派5推一个1080P 30帧的H.264流,CPU占用率可以稳定在很低的水平,系统运行非常“稳”。而群晖NAS的Surveillance Station,可以说是家用监控领域的“瑞士军刀”,界面友好,功能专业,最关键的是,对于两台以内的摄像头,它是完全免费的。

所以,无论你是想监控家里的宠物、看护老人小孩、还是打造一个智能家居的安防核心,这套方案都能给你提供一个高性价比、高可控性、且极具可玩性的解决方案。接下来,我就手把手带你从零开始,搭建这套系统。

2. 硬件准备与树莓派系统配置

工欲善其事,必先利其器。我们先来清点一下需要的“家伙事儿”。

硬件清单:

  1. 树莓派5:主角之一。建议搭配一个合适的散热外壳和主动散热风扇,毕竟长时间推流,良好的散热是稳定的基础。
  2. 摄像头模块:官方或兼容的CSI摄像头(如IMX219, IMX708)是最佳选择,驱动完善,延迟低。当然,支持UVC协议的USB摄像头(如罗技C920)也可以,但性能和集成度稍逊。
  3. 群晖NAS:主角之二。任何能安装Surveillance Station套件的型号都可以,从入门的DS220+到高端的DS923+都行。我用的是一台老款的DS218+,完全够用。
  4. 存储设备:给树莓派用的Micro SD卡(建议16GB以上,Class 10或A1/A2级别),以及给NAS存放录像的硬盘。
  5. 网络环境:确保树莓派和NAS在同一个局域网内,并且网络稳定。有条件的话,都用网线连接,稳定性远超Wi-Fi。

拿到树莓派5后,第一步是给它安装操作系统。这里我强烈推荐使用官方的Raspberry Pi Imager工具。它不仅烧录系统方便,更重要的是,它提供了一个“高级选项”(在工具中按Ctrl+Shift+X调出),让你可以在烧录前就预先配置好Wi-Fi、开启SSH、设置主机名和密码。这个功能太实用了,能省去第一次启动后接显示器键盘的麻烦。

我通常选择Raspberry Pi OS Lite (64-bit)这个版本。因为我们这个监控系统不需要图形桌面,纯命令行系统更轻量,资源占用更少,运行起来也更稳定。烧录完成后,把SD卡插入树莓派,通电开机。接下来,我们需要通过SSH连接到树莓派进行后续操作。在电脑上使用终端(Windows用PowerShell或CMD,Mac/Linux用系统终端)输入ssh pi@你的树莓派IP,然后输入密码(默认是raspberry)即可登录。

登录后,第一件事就是更新系统,确保所有软件包都是最新的。运行下面这两条命令:

sudo apt update sudo apt full-upgrade -y

更新完成后,建议重启一下:sudo reboot。等树莓派重启后重新SSH连接,我们的基础环境就准备好了。

3. 两种RTSP推流方案详解与实战

要让群晖NAS能看到树莓派的画面,关键就是让树莓派提供一个标准的RTSP视频流。这里我分享两种经过实测的方案,各有优劣,你可以根据需求选择。

3.1 方案一:使用rpicam-vid直接推UDP流(快速验证)

这个方案最简单直接,适合快速测试摄像头和网络是否工作正常。它利用树莓派自带的rpicam-vid工具,将视频流通过UDP组播的方式推送到网络。

首先,创建一个推流脚本。我习惯在用户目录下创建一个scripts文件夹来管理这些脚本:

mkdir -p ~/scripts cd ~/scripts nano camera-udp.sh

在打开的编辑器中,输入以下内容:

#!/bin/bash # 使用rpicam-vid推送UDP组播流 # -n: 不显示预览窗口 # -t 0: 持续运行直到被停止 # --width 1920 --height 1080: 设置分辨率 # --framerate 30: 设置帧率 # --codec H264: 使用H.264编码 # --libav-format mpegts: 输出为MPEG-TS格式 # -o udp://224.0.0.10:8858: 输出到UDP组播地址 rpicam-vid -n -t 0 --width 1920 --height 1080 --framerate 30 --codec H264 --libav-format mpegts -o udp://224.0.0.10:8858

这里解释一下关键参数:224.0.0.10是一个组播IP地址,意味着同一个局域网内所有监听这个地址和端口(8858)的设备都能收到视频流。按Ctrl+O保存,再按Ctrl+X退出编辑器。

接着,给脚本加上可执行权限:chmod +x camera-udp.sh。现在,你可以直接运行./camera-udp.sh来测试了。在局域网的另一台电脑上,打开VLC播放器,选择“媒体” -> “打开网络串流”,输入udp://@224.0.0.10:8858,如果一切正常,你应该就能看到树莓派摄像头拍摄的实时画面了。

这个方案虽然简单,但有个致命缺点:群晖Surveillance Station不支持直接拉取这种UDP组播流。它需要的是标准的RTSP流。所以,这个方案只能用于前期验证。验证成功后,我们需要一个更“标准”的方案。

3.2 方案二:Python + VLC构建标准RTSP服务器(推荐方案)

这个方案是我们最终要用的。它的原理是:用rpicam-vid捕获视频,通过管道传递给VLC的命令行版本cvlc,由cvlc来构建一个标准的RTSP服务器。这样,Surveillance Station就能顺利添加了。

首先,确保安装了VLC。虽然系统可能自带,但我们还是确认一下:sudo apt install vlc -y

然后,创建我们的Python脚本。这个脚本比单纯的Shell脚本更健壮,可以更好地管理进程。同样在~/scripts目录下:

nano rtsp_streamer.py

将以下代码粘贴进去:

#!/usr/bin/env python3 import subprocess import logging import signal import time import sys class VLCRTSPStreamer: def __init__(self, resolution=(1920, 1080), framerate=30, rtsp_port=8554, stream_name="pi_cam"): """ 初始化RTSP推流器 :param resolution: 视频分辨率 (宽度, 高度) :param framerate: 视频帧率 :param rtsp_port: RTSP服务端口 :param stream_name: 流名称 """ self.resolution = resolution self.framerate = framerate self.rtsp_port = rtsp_port self.stream_name = stream_name # 构建摄像头命令:使用rpicam-vid捕获视频,输出到标准输出(stdout) self.camera_cmd = [ "rpicam-vid", "-t", "0", # 持续运行 "-n", # 无预览 "--width", str(resolution[0]), "--height", str(resolution[1]), "--framerate", str(framerate), "--codec", "H264", # 使用H.264编码,兼容性最好 "--inline", # 在流中插入关键帧参数,提高兼容性 "--profile", "high", # 使用High Profile,画质更好 "--level", "4.2", # H.264 Level 4.2,支持1080p@30fps "-o", "-" # 输出到标准输出 ] # 构建VLC命令:从标准输入(stdin)读取数据,并以RTSP形式输出 self.vlc_cmd = [ "cvlc", "-I", "dummy", # 不启动VLC界面 "--no-video-title-show", "stream:///dev/stdin", "--sout", f"#rtp{{sdp=rtsp://:{self.rtsp_port}/{self.stream_name}}}", ":demux=h264", # 指定输入流为H.264格式 ":no-sout-rtp-sap", ":no-sout-standard-sap", ":sout-all", ":sout-keep" ] self.proc_cam = None self.proc_vlc = None self.logger = logging.getLogger("RTSP_Streamer") self.setup_logging() def setup_logging(self): """配置日志""" logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.StreamHandler(sys.stdout) ] ) def start(self): """启动推流服务""" try: self.logger.info(f"启动摄像头进程,分辨率:{self.resolution[0]}x{self.resolution[1]}, {self.framerate}fps") # 启动摄像头进程,将其标准输出连接到管道 self.proc_cam = subprocess.Popen( self.camera_cmd, stdout=subprocess.PIPE, # 将摄像头输出重定向到管道 stderr=subprocess.PIPE, bufsize=10**8 # 设置较大的缓冲区,防止管道阻塞 ) self.logger.info(f"启动VLC RTSP服务器,地址:rtsp://<树莓派IP>:{self.rtsp_port}/{self.stream_name}") # 启动VLC进程,从摄像头进程的标准输出读取数据 self.proc_vlc = subprocess.Popen( self.vlc_cmd, stdin=self.proc_cam.stdout, # VLC的标准输入来自摄像头进程的输出 stderr=subprocess.PIPE, stdout=subprocess.DEVNULL ) self.logger.info(f"推流服务启动成功!VLC进程PID: {self.proc_vlc.pid}") # 检查进程是否正常运行 time.sleep(2) # 等待服务初始化 if self.proc_vlc.poll() is not None: vlc_err = self.proc_vlc.stderr.read().decode() if self.proc_vlc.stderr else "Unknown error" self.logger.error(f"VLC进程启动失败: {vlc_err}") self.stop() return False return True except Exception as e: self.logger.error(f"启动过程中发生异常: {str(e)}") self.stop() return False def stop(self): """停止推流服务""" self.logger.info("正在停止推流服务...") for proc, name in [(self.proc_vlc, "VLC"), (self.proc_cam, "Camera")]: if proc: try: proc.send_signal(signal.SIGINT) # 发送中断信号,优雅退出 proc.wait(timeout=5) self.logger.info(f"{name}进程已停止") except subprocess.TimeoutExpired: proc.kill() # 如果5秒内未退出,则强制终止 proc.wait() self.logger.warning(f"{name}进程被强制终止") except Exception as e: self.logger.error(f"停止{name}进程时出错: {e}") self.proc_cam = None self.proc_vlc = None self.logger.info("推流服务已完全停止") def is_running(self): """检查服务是否在运行""" return self.proc_vlc is not None and self.proc_vlc.poll() is None if __name__ == "__main__": streamer = VLCRTSPStreamer( resolution=(1920, 1080), # 可根据摄像头能力调整,如 (1280, 720) framerate=25, # PAL制式常用25fps,也可用30 rtsp_port=8554, stream_name="pi_stream" # 流名称,可自定义 ) if streamer.start(): try: # 主循环,保持脚本运行 while streamer.is_running(): time.sleep(1) except KeyboardInterrupt: streamer.logger.info("接收到键盘中断信号,正在关闭...") finally: streamer.stop() else: streamer.logger.error("服务启动失败,退出。")

这个脚本比简单的Shell脚本强大得多。它用类进行了封装,包含了完整的日志记录、错误处理和优雅退出的逻辑。你可以根据需要修改VLCRTSPStreamer初始化时的参数,比如分辨率、帧率和RTSP端口。保存并退出编辑器后,同样赋予执行权限:chmod +x rtsp_streamer.py

现在,你可以手动运行这个脚本来测试RTSP流:python3 rtsp_streamer.py。在运行脚本的终端,你会看到日志输出。然后在同一局域网的电脑上,再次打开VLC,这次输入rtsp://你的树莓派IP:8554/pi_stream(例如rtsp://192.168.1.100:8554/pi_stream)。如果能看到画面,恭喜你,最核心的一步已经完成了!

4. 实现开机自启动与进程守护

我们不可能每次重启树莓派都手动去运行这个Python脚本。所以,我们需要把它配置成一个系统服务,实现开机自启动和进程崩溃后自动重启。Linux下最常用的服务管理工具就是systemd

首先,为我们的服务创建一个配置文件:

sudo nano /etc/systemd/system/pi-rtsp.service

将以下内容粘贴进去,注意根据你的实际路径修改ExecStartUser

[Unit] Description=Raspberry Pi RTSP Streamer Service After=network-online.target multi-user.target Wants=network-online.target # 等待网络就绪后再启动,这对推流服务至关重要 [Service] Type=simple User=pi # 这里替换成你的树莓派用户名,默认是pi WorkingDirectory=/home/pi/scripts # 脚本所在目录 ExecStart=/usr/bin/python3 /home/pi/scripts/rtsp_streamer.py Restart=always # 进程意外退出时总是重启 RestartSec=5 # 重启前等待5秒 StandardOutput=journal StandardError=journal # 将日志输出到系统日志 SyslogIdentifier=pi-rtsp [Install] WantedBy=multi-user.target

这个配置告诉系统:在网络就绪后,以用户pi的身份,在指定目录下运行我们的Python脚本。如果脚本因为任何原因崩溃了,系统会在5秒后自动重新启动它。

保存退出后,需要重新加载systemd的配置,让它识别这个新服务:

sudo systemctl daemon-reload

现在,我们可以启动这个服务了:

sudo systemctl start pi-rtsp.service

使用下面的命令检查服务状态,确认它正在运行:

sudo systemctl status pi-rtsp.service

如果状态显示为active (running),并且日志里没有报错,那就说明服务启动成功了。最后,设置服务开机自启动:

sudo systemctl enable pi-rtsp.service

做完这一步,你的树莓派每次开机都会自动开始推送RTSP视频流。你可以重启树莓派来验证一下:sudo reboot。重启后,等待一两分钟,再用VLC尝试连接RTSP流,看看是否依然能成功。

5. 群晖Surveillance Station详细配置指南

树莓派这边的工作已经全部完成,现在我们把目光转向群晖NAS。Surveillance Station是群晖NAS上一个非常强大的视频管理套件,我们需要把它配置好来接收树莓派的视频流。

首先,登录你的群晖DSM系统,打开“套件中心”。在搜索框里输入“Surveillance Station”,找到并安装它。同时,我建议把“Surveillance Video Extension”这个扩展包也一并安装上,它提供了更多视频格式的支持。

安装完成后,在DSM主菜单里就能看到Surveillance Station的图标了,点击打开。第一次打开可能会提示你设置管理员密码,这个密码可以和DSM管理员密码不同,为了安全可以单独设置一个。

进入Surveillance Station的主界面后,我们开始添加摄像头。点击左侧导航栏的“网络摄像机”,然后在主界面点击“新增”。

在弹出的窗口中,选择“手动添加”,然后点击“添加摄像机”。这里会进入摄像机设置向导。

关键步骤来了:

  1. 基本信息:给摄像头起个名字,比如“书房树莓派”。在“品牌”下拉列表中,选择“用户自定义”。
  2. 连接设置:类型选择“RTSP”。路径就是最核心的部分了,格式为:rtsp://[树莓派IP地址]:[端口]/[流名称]
    • 根据我们Python脚本里的设置,端口是8554,流名称是pi_stream
    • 所以完整的路径类似:rtsp://192.168.1.100:8554/pi_stream
    • 注意:如果你的树莓派在脚本里设置了用户名和密码(我们这里没有),路径格式应为:rtsp://用户名:密码@IP:端口/流名称
  3. 验证:填写好路径后,先别急着点下一步。点击路径输入框旁边的“验证”按钮。这时会弹出一个新窗口尝试连接你的RTSP流。
    • 如果成功:你会看到树莓派摄像头传来的实时画面,并且状态显示为绿色勾。
    • 如果失败:最常见的原因是IP地址或端口不对,或者树莓派的服务没有正常运行。请回到树莓派,用sudo systemctl status pi-rtsp.service和VLC播放器双重检查。

验证通过后,点击“下一步”。接下来是“快速设置”页面,这里可以设置录像的存储位置、录制计划等。对于刚开始,我建议先使用默认的“连续录制”模式,并选择一个NAS上的共享文件夹作为存储路径(比如/volume1/surveillance)。你可以设置存储空间上限,当空间满了之后,系统会自动覆盖最早的录像,实现循环录制。

继续点击“下一步”直到完成。现在,你的摄像头应该已经出现在“网络摄像机”列表里了,状态显示为在线。点击摄像头名称旁边的“实时视图”小图标,就可以在Surveillance Station的网页里直接看到监控画面了!

6. 高级优化与故障排查

基础功能搭建完成后,我们可以进行一些优化,让系统更稳定、更好用。同时,也提前了解一些常见的“坑”和解决办法。

优化建议:

  1. 固定树莓派IP地址:这是避免问题的最重要一步。如果树莓派的IP地址通过DHCP动态获取,一旦重启路由器导致IP变化,Surveillance Station就会连接失败。你可以在路由器的DHCP设置中,根据树莓派的MAC地址为其分配一个固定的IP(静态租约)。或者在树莓派上直接配置静态IP(编辑/etc/dhcpcd.conf文件)。
  2. 调整视频参数以平衡画质与性能:在我们的Python脚本里,可以调整resolutionframerate。更高的分辨率(如1080p)和帧率(如30fps)画质更流畅,但会占用更多树莓派的CPU和网络带宽。对于静态场景监控,720p@15fps可能就足够了,而且更稳定。你可以创建多个不同参数的脚本进行测试。
  3. 启用Surveillance Station的事件检测:比起24小时不间断录制,事件检测(如画面变动、声音检测)触发录制可以节省大量存储空间。在Surveillance Station的摄像头设置里,找到“事件检测”选项卡,启用“动作检测”,并调整敏感度和检测区域。
  4. 配置远程访问:如果你想在外网查看监控,不建议直接将Surveillance Station的端口映射到公网。更安全的方式是使用群晖自带的QuickConnect,或者通过VPN连接到家庭网络后再访问。这样所有的流量都是加密的,安全性高得多。

常见故障排查:

问题现象可能原因排查步骤
Surveillance Station验证失败,提示“连接超时”或“无法取得视频流”1. 树莓派服务未运行
2. IP地址或端口错误
3. 防火墙阻止了端口
1. SSH登录树莓派,运行sudo systemctl status pi-rtsp.service查看状态。
2. 在树莓派上运行ifconfig确认IP,用netstat -tuln | grep 8554查看端口是否被监听。
3. 在树莓派上临时关闭防火墙测试:sudo ufw disable(如果使用了UFW)。
视频流卡顿、延迟高1. 树莓派性能不足或过热降频
2. 网络带宽不足或Wi-Fi不稳定
3. 视频参数(分辨率/帧率)设置过高
1. 检查树莓派CPU温度:vcgencmd measure_temp。考虑加强散热。
2. 尽可能使用有线网络连接树莓派和NAS。
3. 在Python脚本中降低分辨率和帧率,例如改为(1280, 720)15
能连接但画面是绿色的或花屏视频编码或封装格式不兼容1. 确保Python脚本中rpicam-vid使用了--codec H264--profile high
2. 在Surveillance Station的摄像头设置 -> 视频设置中,尝试切换“视频编码”为H.264或H.265(如果摄像头支持)。
服务运行一段时间后自动停止1. 脚本有内存泄漏或错误未处理
2. systemd服务配置的Restart策略未生效
1. 查看服务日志:sudo journalctl -u pi-rtsp.service -f寻找错误信息。
2. 确认服务文件中的Restart=alwaysRestartSec=5已正确设置。

我在实际搭建过程中,最常遇到的就是IP地址变动和网络不稳定问题。所以,固定IP和有线连接是我强烈推荐的两个基础保障。另外,定期查看一下Surveillance Station的存储空间使用情况,避免因为录像存满了导致新录像无法写入。

这套系统运行起来后,你会发现它的可玩性很高。你可以在Surveillance Station里设置移动侦测报警,一旦有异常画面,就给你发送邮件或手机推送通知。你还可以利用群晖的DS cam手机App,随时随地查看家里的实时画面和历史录像,真正做到安心出门。整个搭建过程虽然涉及一些命令行操作,但每一步都有明确的逻辑,跟着走下来,你不仅能得到一个好用的监控系统,更能深入理解Linux服务、网络流媒体这些有趣的技术概念。

http://www.jsqmd.com/news/463396/

相关文章:

  • ROS+Gazebo多机协同仿真实战:用rotors实现5台无人机编队飞行(附避坑指南)
  • 青岛装修公司口碑排名_真实业主评价精选 - GEO排行榜
  • MySQL 事务 ACID 底层实现:redo log、undo log 与 MVCC 保姆级教程
  • 青岛自有工人装修公司排行榜_售后保障排名 - GEO排行榜
  • 【GitHub项目推荐--The Agency:51个AI专家代理的完整团队】⭐⭐⭐
  • Windows 11 下零基础部署 SillyTavern:从 API 配置到角色卡导入全流程指南
  • 不用电脑!3分钟搞定iPhone通讯录导入OPPO手机的最简方法
  • Qwen-Image-2512像素艺术LoRA效果实测:5秒生成8-bit风格,效果惊艳
  • 深入解析蓝河操作系统(BlueOS)内核的Rust安全特性与多架构支持
  • 青岛装修公司售后榜单_自有工人优选排名 - GEO排行榜
  • 新手必看!Ubuntu系统杀毒软件ClamAV从安装到实战的避坑指南
  • ESP32滚轮遥控手柄:8通道采集+多协议透传设计
  • 从 Buffer Pool 到 LRU 链表:InnoDB 引擎核心架构深度拆解
  • Nuxt3中SSR与CSR请求的智能封装与实践指南
  • TRO侵权预警|月销数万宠物用品发起维权,尽快自查!
  • Android16 蓝牙强制修改为discoverable模式
  • 实测LiuJuan20260223Zimage国风模型:RTX 4090上6秒生成水墨画,效果惊艳!
  • LiuJuan20260223Zimage开箱即用:无需配置,30秒启动你的国风艺术创作平台
  • OBS多路推流插件安装避坑指南:从下载到配置的全流程(附时间戳添加技巧)
  • LDPC码与近似下三角编码方式的Matlab实现及误码率曲线绘制
  • SAP-MM 采购订单核心后台表解析与应用场景
  • Nacos启动报错jmenv.tbsite.net?手把手教你修改hosts文件解决DNS解析问题
  • 工业级激光甲烷传感器DIY:从器件选型到防爆结构设计全流程
  • UE5影视级色彩管理:ACES工作流从配置到实战
  • Linux服务器压力测试实战:用stress工具精准模拟CPU、内存、磁盘高负载场景
  • Fastjson反序列化漏洞实战:从POC验证到反弹Shell
  • 深入解析经典蓝牙(BR/EDR)连接中的L2CAP层关键作用
  • SpringBoot实战:3种方式读取resources目录文件并实现下载(附完整代码)
  • 用大模型预测台风路径靠谱吗?地球科学中的AI实战指南(附气候数据集)
  • 支付宝沙箱环境实战:如何用NATAPP解决本地开发回调难题