
简介Moonfire NVR是一套开源的网络视频录像机实现适合自建安防监控、希望轻量保存IP摄像机录像的开发者或运维人员。它基于Rust与JavaScript实现把H.264-over-RTSP流写入混合格式视频帧落盘为按时间组织的目录SQLite保存索引与元数据并能按任意时间范围动态生成MP4由于不解析、分析或重编码视频帧CPU占用很低可在树莓派、老旧PC等低成本设备上稳定运行。整个源码压缩包共116个文件大小5.22MB以48个Rust源文件、24个JavaScript文件为主另有SQL建库脚本、proto协议描述、Dockerfile、部署脚本等覆盖后端录像服务、前端回放界面、数据库初始化与容器化运行配置模块边界清晰便于定位核心录像与转封装代码。当前Web界面支持片段过滤与时间段修剪运动检测、HTTPS等能力仍处演进中正好为后续二次开发预留了空间。已有1400人学习下载适合想研究RTSP取流、SQLite存储索引与动态MP4合成等实现的读者。 说实话这几年我折腾过的 NVR 方案不算少。从几百块的家用盒子到群晖 Surveillance Station再到各类商业软件基本都试过一圈。最后留在生产环境里长期跑的反而是一个相对小众的开源项目Moonfire NVRmoonfire-nvr。Moonfire NVR 是一个用 Rust 写的安全摄像机网络视频录像机目标很纯粹——把 IP 摄像头的 RTSP 视频流稳定录下来再给你一个快速的时间线回放界面。没有花哨的智能分析没有云服务绑定也没有厂商锁死。它解决的核心问题就两个录像不掉帧、回放不等待。如果你正要搭建一套自己的监控存储服务或者对现有商业 NVR 不满想找一个可自托管、可长期维护的方案这篇文章值得看完。下面按项目拆解、选型规划、部署实操、机制解析、问题排查五个部分来写基本还原我完整落地一套 Moonfire NVR 的过程。1. 项目定位拆解Moonfire NVR 到底做了什么1.1 核心能力与设计取舍Moonfire NVR 在 NVR 圈子里有点像“偏科生”它不做移动侦测、不做人形识别、不支持多平台客户端。它把所有精力放在录像生命周期上——从 RTSP 拉流、编码复用、分段存储、索引再到浏览器端按秒级时间线回放。这套逻辑和许多商业产品正好相反商业产品喜欢堆功能而它选择把“录像回放”这一件事做到极致。底层技术也值得一提。整个项目用 Rust 编写数据库用的是 SQLite录像索引设计得非常精细。早期我跑在一台低功耗 NUC 上四路摄像头同时写入CPU 占用基本可以忽略。相比那些动不动就满载、风扇呼呼转的 Windows 平台 NVR 软件这个体验差距很大。1.2 和商业 NVR、群晖 Surveillance Station 的对比我拍了张对比表方便直观感受差异对比项Moonfire NVR群晖 Surveillance Station商业盒子 NVR 传统方案授权成本免费开源随摄像头数量额外收费购买硬件附带授权摄像头兼容性依赖 RTSP/ONVIF 标准兼容性好但绑定群晖型号自家生态优化回放体验秒级时间线非常流畅大录像查询有卡顿看品牌差异大AI 功能无完全不做智能分析有基础侦测各有方案多数另收费部署门槛需要 Linux 基础套件点击安装开箱即用长期维护依赖社区更新依赖厂家支持依赖厂商更新如果你只是想要一个插上电源就能用的设备商业盒子还是有存在价值的。但如果你已经有一台常开的 Linux 服务器又不想给摄像头数量买授权Moonfire NVR 几乎是成本最低的路线。1.3 这套方案适合谁我的经验是Moonfire NVR 适合这几类场景第一家里或小办公室已有 2 到 8 路网络摄像头且摄像头支持标准 RTSP 流第二你愿意花半小时做一次命令行部署而不是点安装向导第三你担心云监控的隐私问题希望录像数据完全在自己手里。反过来如果你需要人脸识别、车牌识别、报警推送这些功能那它暂时不适合你建议直接用商业 NVR或者 Frigate 这类带 AI 的方案。2. 选型与规划动手之前的三个关键决策2.1 硬件配置怎么定Moonfire NVR 对硬件要求出奇地低因为真正的编码工作是在摄像头端完成的NVR 只做存储和索引。理论上一颗双核低功耗 CPU、2GB 内存、一个支持 trim 的 SSD 加一块大容量机械盘就能稳定跑 4 到 8 路 1080p。具体来说我建议按这个底线来配入门配置树莓派 4B 或同级别 ARM 板子适合 2 到 4 路 720p/1080p。推荐配置使用 Intel N100/N305 或老款 i3 的低功耗迷你主机适合 8 路以内 1080p。进阶配置二手服务器或桌面机适合 16 路以上并留出转码余量。注意一点内存不用太大但磁盘千万别省。Moonfire NVR 的索引是高频随机读写录像文件是顺序写入如果你的存储盘是机械硬盘建议把系统盘和录像盘分开否则索引查询会和录像写入互相抢 I/O。2.2 磁盘容量与码率估算很多新手最容易犯的错就是不看摄像头的实时码率直接按“大概一天多少 GB”的想象买硬盘结果两周就把盘录满了。Moonfire NVR 没有像商业机器那样帮你做复杂的分级存储所以容量规划要自己做。推荐用这个公式估算单路每小时大小(GB) 码率(Mbps) × 3600 ÷ 8 ÷ 1024以常见的 1080p、H.264、平均 4Mbps 码率为例4Mbps 4 × 3600 ÷ 8 ÷ 1024 ≈ 1.76 GB/小时单路一天 24 小时连续录就是约 42 GB。如果是四路摄像头同时录一天就是 168 GB2TB 硬盘大概只能撑 12 天。所以我个人建议按“全码率录像保留 30 天”做容量规划并且尽量买监控级硬盘CMR 类型避免家用 SMR 盘在长时间写入后性能暴跌。2.3 网络拓扑与 RTSP 地址获取Moonfire NVR 的输入源只有一个摄像头的 RTSP 地址。这意味着摄像头和 NVR 服务器之间必须在同一个二层网络内可互通且不建议把 RTSP 流暴露到公网。我习惯搞一张独立的 VLAN或者至少用单独的网段隔离摄像头避免 IoT 设备被外部扫描到。RTSP 地址格式一般是这样的rtsp://用户名:密码摄像头IP:554/某一路流路径不同品牌的默认路径差别很大。常见的有海康的/Streaming/Channels/101主码流、大华的/cam/realmonitor?channel1subtype0有些 ONVIF 摄像头则是/onvif1或/live/main。最好的办法是查到型号官方文档或者用 VLC 的“打开网络串流”功能逐个试。一个实用技巧先在浏览器或 VLC 里把 RTSP 地址完整测试一遍确认能出画面、能出声再填进 Moonfire NVR。别等到配置完才发现填了个半截地址排查起来很浪费时间。3. 从零部署一条完整的实操路线3.1 拿到二进制与初始化数据库官方编译好的二进制包比较干净也可以用源码自己编。Rust 项目编译时间不算短如果没有改代码的需求我更推荐直接下载 Release 产物。两个核心目录要先规划好db放 SQLite 数据库文件sample放录像片段。假设所有文件都放在/var/lib/moonfire-nvr下sudo mkdir -p /var/lib/moonfire-nvr/db /var/lib/moonfire-nvr/sample sudo chown -R 当前用户 /var/lib/moonfire-nvr然后执行初始化moonfire-nvr init --db-dir/var/lib/moonfire-nvr/db这一步会创建数据库结构并提示你设置运行用户。我后面实际使用的是--allow-other-users之类的配置来放开多用户但单用户场景保持默认就行。3.2 创建系统用户与运行环境Moonfire NVR 的登录方式和普通 Web 应用不一样它不维护密码表而是直接映射到操作系统用户。这听起来奇怪但用起来很顺手——你只需要在 Linux 里创建一个专用用户比如叫moonfiresudo useradd -r -s /usr/sbin/nologin moonfire sudo chown -R moonfire:moonfire /var/lib/moonfire-nvr运行时通过服务文件或者sudo -u moonfire moonfire-nvr run ...启动。每次浏览器登录时输入你创建好的用户名程序会校验发起请求的客户端 IP 是否可信并生成 session。这种方式彻底省掉了“忘记管理后台密码”这种破事。另外录像片段目录的写权限必须给足否则服务能启动但录不进任何数据日志里会一直刷权限报错。建议用下面的快速自检ls -ld /var/lib/moonfire-nvr/sample确保 owner 是你接下来要 launch 服务的用户。3.3 配置摄像头一条命令搞定配置摄像头是命令行的重头戏远程交互式编辑器模式回车进入moonfire-nvr config --db-dir/var/lib/moonfire-nvr/db进入配置界面后先选Cameras再选Add camera填写摄像头名称比如FrontDoor用户名、密码RTSP 地址如果支持 ONVIF可以填 ONVIF 主机端口方便自动抓取流地址。保存后还要做一次Assign stream操作把它关联到对应的视频流上。主码流通常叫main子码流叫sub。大多数场景只录主码流子码流留给以后如果想做局域网预览用。3.4 启动服务并验证录像配置完成后就是启动moonfire-nvr run --db-dir/var/lib/moonfire-nvr/db --http-addr0.0.0.0:8080浏览器打开http://服务器IP:8080输入刚才配置的 Linux 用户名登录。前端界面主要有三块下方录像时间轴、左侧摄像头列表、中间回放窗口。首次进入时如果已经录了几分钟时间轴上应该能看到对应的色块。我测试时的第一件事是盯着一路实况流看 5 分钟然后在时间轴上点回放确认从第 1 分钟到第 5 分钟都能连续播放、没有绿屏和跳帧。这一步通过之后再进config增加其他摄像头效率最高。4. 核心机制解析用了半年才理解的设计4.1 文件级与数据库级双重索引Moonfire NVR 最特别的设计是把“录像文件”和“录像索引”彻底分离。摄像头传过来的 H.264 流会被切成一段段 MP4 文件每个文件时长默认在 60 秒到 5 分钟左右存放在sample目录。文件本身不需要特意命名真正的时间关系都记录在 SQLite 里。这种设计带来的好处是查询某一天某个时间点的录像时不需要扫描整段大文件数据库索引会直接告诉你“这个时间点对应的文件是这个偏移量是多少”于是浏览器端就能秒级跳到目标帧附近。后期即使某个文件损坏也只是损失那一段不会把整条录像链拖垮。4.2 时间线回放的实现思路它的前端时间轴不是拉一张 JPEG 缩略图而是直接向服务端发起按时间范围查询。服务端返回该时间范围内所有录像片段的时间戳、时长和文件路径前端再用 HTTP Range 请求按需拉取流媒体数据。早期我用群晖的时候回放一整天的高清录像时加载时间轴经常卡顿。换到 Moonfire NVR 之后哪怕数据库里已经积累了 4000 多个小时录像拖动时间轴依然很跟手。说明这个索引模型在高数据量下是扛得住的这是我最欣赏它的一点。4.3 用户与登录模型前面说到它把 Unix 用户映射到浏览器登录用户这里展开讲一下细节。Moonfire NVR 启动时会读取发起登录请求的 IP 地址并校验这个 IP 是否被系统认为是可信任的。如果你有反向代理要注意给请求带上正确的X-Forwarded-For否则程序可能认为请求来自代理 IP校验失败导致登录不上。权限层面也有区分普通用户只能看回放无法修改配置。管理员用户则能通过 Web 界面进行一部分摄像头管理。我建议日常使用建一个只读用户避免误操作改动配置。4.4 存储保留策略Moonfire NVR 默认不会无限堆积文件它内置了“按时间保留”的策略。配置管理窗口里可以设定每个流保留多少天。超过时间后服务端在删除录像文件的同时也会清理数据库索引形成一套完整的回收闭环。有一点要留意录像保留策略是按“每个流”单独设置的。如果你给主码流设置了 30 天保留但子码流没有设置子码流可能就一直不删。多台摄像头、多路流混合的情况下最好在配置完成后统一检查一遍保留时间否则硬盘容易被某个漏配置的流悄悄写满。5. 常见问题与排查技巧实录5.1 RTSP 拉流不稳定录像断断续续这是最常遇到的情况。我一般按下面几步排查现象可能原因解决思路部分时段没录到摄像头和服务器网络抖动改用有线连接避免 Wi-Fi 传输大幅波动某个流一直黑屏RTSP 地址不对或需要认证先用 VLC 验证地址和账号密码录像文件存在但回放卡顿存储 I/O 跟不上检查磁盘是否 SMR 盘必要时换 CMR/SSD我想额外提醒一句不要同时给多个软件拉同一路 RTSP 流。某些家用摄像头的 RTSP 服务非常脆弱并发拉流会导致流中断。我在部署客户端预览时只保留了 Moonfire NVR 这一路其他预览一律不开启。5.2 磁盘写满导致索引不完整如果你在录像保留策略没配好之前就长时间运行很容易把磁盘写满。SQLite 在磁盘满的时候会先报database or disk is full然后整个服务尝试自动恢复但部分索引可能丢失。处理办法是立刻停服务清理出一部分空间然后启动服务让它自动修复。用 SQLite 的PRAGMA integrity_check可以快速验证数据库是否完好。这里要强调的是千万别在磁盘写满时直接删 sample 目录里的 .mp4 文件那样会让数据库里的索引变成悬空引用整个时间轴都会乱掉。正确做法是进 config 界面把保留时间调小让程序自己清理。5.3 版本升级与数据库迁移Moonfire NVR 迭代速度不算慢版本升级时偶尔需要数据库迁移。官方发布说明里会注明当前版本是否兼容旧数据库。升级前最安全的操作是把整个db目录冷备一份然后运行新版本二进制让它在启动时自动执行迁移。我踩过一次坑升级时没有备份新版本迁移中途因为权限问题失败了导致数据库锁死。从那以后我养成了“升级前必备份 SQLite 文件”的习惯哪怕只是打一个 tar 包tar -czf moonfire-db-backup.tar.gz -C /var/lib/moonfire-nvr db这个档案很小但能救命的概率很大。5.4 低功耗长期运行的一些调优如果你也打算把 moonfire-nvr 放在一台迷你主机或者 ARM 开发板上长跑有几个细节值得关注。第一用 SSD 做数据库文件所在盘机械盘只放录像文件这样能明显降低回放卡顿第二摄像头尽量让它们在设备端直接输出主码流不要让 Moonfire NVR 转码它本身也没有转码能力省掉这部分就能省大量 CPU第三定时任务别在每小时整点时集中执行避免和录像分段写入撞车我一般把备份任务分散在凌晨 3 点到 5 点之间。最后再分享一个小技巧如果你想给 Moonfire NVR 配一个外网访问入口不要直接暴露 8080 端口用反向代理加 HTTPS 证书。登录时把代理的透传 IP 配置好普通用户只读权限设好这套自建安全摄像机网络视频录像机就能安安静静跑上一年半载不用再管。本文还有配套的精品资源点击获取