Micam 多容器太吃资源?用 Go2RTC + EasyNVR 给小米摄像头换一套轻量本地录像方案
前言
之前为了把小米摄像头录像留在自己的 NAS 里,我已经试过 Micam 这类多容器方案。功能能实现,但放到 N1 这种只有 2GB 内存的小设备上,常驻容器一多,资源压力很快就能感觉出来。对我来说,监控系统最重要的不是“组件越多越专业”,而是视频流能稳定出来、录像能真正落盘、回放时找得到,长期跑着也别把盒子拖得太累。现在 Go2RTC 已经能直接处理小米摄像头这一侧的接入,整条链路就有机会做得更短。监控这类长期运行的服务,我尤其不喜欢为了一个结果叠太多中间层,因为一旦某个容器异常,最后往往连“到底是谁没工作”都要重新排查。
这次我用 N1 刷 ARM 版飞牛 NAS,在 Docker 里分别部署 Go2RTC 和 EasyNVR:先让 Go2RTC 登录小米账号、拉取摄像头流并整理成 RTSP,再把 RTSP 交给 EasyNVR 做录像、回放和时间段下载。存储目录直接落到外置盘 /vol1/EasyNVR。局域网跑通以后,再用 cpolar 把 EasyNVR 的 10000 Web 页面提供到公网,先验证随机地址,最后配置固定二级子域名 easynvr。我更在意的是这两只容器各自干什么、RTSP 地址怎么来的、录像到底写到哪里,而不是单纯用“容器更少”去代替整条链路的实际验证。
1. 为什么这次从 Micam 方案换成 Go2RTC + EasyNVR?
前一套方案已经能让小米摄像头进入飞牛 NAS,但对低配设备来说,问题主要出在常驻组件偏多。
这次调整的思路很直接:
Go2RTC 负责摄像头流 → EasyNVR 负责录像和回放。
这样把“拉流 / 转成标准协议”和“录像 / 管理”拆成两层。
原材料里把这次变化写成从 4 个容器缩到 2 个,同时前文又称旧方案为 Micam 三件套。两种表述我不强行合并,真正需要关注的是:当前新方案实际部署的就是 Go2RTC + EasyNVR 两个容器。
2. Go2RTC 在这里扮演什么角色?

Go2RTC 在这套方案里不是录像软件。
它更像一个流媒体入口:先和摄像头侧通信,再把视频整理成后面更容易接入的标准流。
当前介绍中提到了 RTSP、RTMP、HTTP-FLV、WebRTC、MSE、HLS、MJPEG 等协议;但这篇真正继续往下用的是:
小米摄像头 → Go2RTC → RTSP。
所以我把注意力放在这条已经实际跑过的路径上。
3. 先准备 N1 + 飞牛 NAS 环境
本期教程以用N1刷入arm版的飞牛Nas系统为例,其他Nas系统支持Docker均可(如:绿联Nas、极空间Nas,群晖Nas等)。
这次环境是 N1 刷 ARM 版飞牛 NAS。
原步骤里还写到:
- ARM 版飞牛固件支持无线网卡驱动;
- 可以连接 Wi-Fi;
- 可刷 453 版固件,再 OTA 到 1.1.18。
这些都按当前环境保留。
3.1 启动 Docker
先在飞牛 NAS 首页打开 Docker,并确认 Docker 服务处于启动状态。

原步骤建议把 Docker 存储位置放到挂载的外部存储空间。
3.2 打开 SSH
进入飞牛 NAS 系统设置,启用 SSH。

Windows 端按 Win + X,打开终端或 PowerShell。

连接飞牛 NAS:
# ssh 你的Nas用户名@你的Nas系统IP地址
ssh n1@192.168.50.228

登录以后切换到 root:
sudo -i

到这里后面的 Docker 部署都可以直接在 SSH 终端里完成。
4. Docker 部署 Go2RTC
执行:
mkdir -p $(pwd)/go2rtc/config && touch $(pwd)/go2rtc/config/go2rtc.yaml && docker run -d –name go2rtc –restart always –network host -v $(pwd)/go2rtc/config:/config alexxit/go2rtc

这条命令同时完成了几件事:
- 创建 go2rtc/config 目录;
- 创建 go2rtc.yaml;
- 使用 –network host;
- 把配置目录挂载到容器 /config;
- 启动 alexxit/go2rtc。
部署以后检查状态:
docker ps

当前状态显示为 UP。
浏览器访问:
http://192.168.50.228:1984

页面能打开以后,Go2RTC 这一层先算启动成功。
5. 登录小米账号,把摄像头流接进 Go2RTC
进入 Go2RTC 顶部的:
add
菜单。

滚动到下面展开:
Xiaomi
填写小米账号信息并加载设备。

这里得到摄像头对应的 URL 后,再进入顶部:
config
把配置写进 YAML。
当前配置原样如下:
# =================================================================
# GO2RTC 示例配置文件
# —————————————————————–
# 【使用说明】
# 1. 访问后台:http://宿主机IP:1984 (默认账号: admin / 密码: password)
# 2. RTSP构造:若取消rtsp段落注释,播放地址如下:
# – 4K流: rtsp://admin:password@宿主机IP:8554/cam_4k
# – 标准: rtsp://admin:password@宿主机IP:8554/cam_std
# 3. 参数说明:
# – subtype=3: 锁定 4K 极清分辨率
# – subtype=2: 锁定 1080P/2K 高清分辨率
# – #audio=pcmu: 强制音频解码,解决部分设备无声问题
# =================================================================
api:
listen: ":1984"
username: admin
password: "password"
# rtsp:
# listen: ":8554"
# username: admin
# password: "password"
streams:
xiaomi:
– "you_xiaomi_url&subtype=2#video=copy#audio=pcmu"
xiaomi_4k:
– "you_xiaomi_url&subtype=3#video=copy#audio=pcmu"
xiaomi:
"USER_ID": V1:EXAMPLE_TOKEN

这里能看出两条流:
- xiaomi:subtype=2
- xiaomi_4k:subtype=3
配置里还使用:
#audio=pcmu
处理音频。
保存时点击:
Save & Restart
然后回到首页进入 stream 测试。

能看到画面以后,说明摄像头流已经被 Go2RTC 拉起来。

6. RTSP 地址这里有一处需要实际核对
接下来要把 Go2RTC 的流交给 EasyNVR,所以需要 RTSP 地址。
当前文章给出的构造方式是:
# 无密码的构建方式
rtsp://宿主机IP:8554/xiaomi_4k
# 开启密码认证的构建方式
rtsp://admin:123456@宿主机IP:8554/xiaomi_4k
随后使用 PotPlayer,按:
Ctrl + U
打开网络地址。

输入 RTSP 地址以后,当前测试可以播放。
这一层验证的是:
小米摄像头 → Go2RTC → RTSP → PotPlayer。
不过这里有一个技术细节我会特别留意:
前面的 YAML 里 rtsp: 整段仍然是注释状态,并且注释中的示例密码写的是 password;后面的 RTSP 示例又写成 admin:123456。
这几处并不完全一致。
我不替换现有代码,真正复现时需要以自己实际启用的 RTSP 配置、用户名和密码为准。
7. EasyNVR 接手录像和回放

到了这里,Go2RTC 已经把摄像头流整理成 RTSP。
EasyNVR 接下来负责的是:
- 接入 RTSP 流;
- 录像;
- 回放;
- 按时间段查找和下载录像。
对我来说,这比让 Go2RTC 同时承担所有工作更清楚:
Go2RTC 管“流”,EasyNVR 管“录像”。
8. 先确认外置盘,再创建录像目录
回到 N1 终端,查看磁盘:
df -h

当前外置存储显示:
239G
挂载根路径为:
vol1
所以创建 EasyNVR 目录:
mkdir -p /vol1/EasyNVR
cd /vol1/EasyNVR
这里后面会把:
/vol1/EasyNVR
挂进 EasyNVR 容器作为录像存储位置。
9. Docker 部署 EasyNVR
执行:
docker run -d –name easynvr –restart always –network host –log-opt max-size=50M -v "$PWD/configs:/app/configs" -v "$PWD/logs:/app/logs" -v "$PWD/temporary:/app/temporary" -v /vol1/EasyNVR:/app/r -v "$PWD/stream:/app/stream" registry.cn-shanghai.aliyuncs.com/rustc/easynvr_arm64:latest

这条命令里值得记住的是:
- 容器名:easynvr
- –network host
- 日志限制:max-size=50M
- 录像目录:/vol1/EasyNVR:/app/r
- 镜像:registry.cn-shanghai.aliyuncs.com/rustc/easynvr_arm64:latest
部署完成以后,在浏览器打开:
飞牛 NAS IP + 10000

页面能正常打开以后,EasyNVR 服务已经起来。
10. 初始化 EasyNVR
第一次进入 EasyNVR,先点击登录,然后把语言切成简体中文。

属性配置里使用当前局域网地址,原流程这里直接保持自动获取结果。

开放端口页面也按当前默认配置继续。

然后在重置账号页面创建新的管理员账号。

完成初始化以后,用新账号进入 EasyNVR 首页。

我会把这一步和后面的公网访问分开看:
EasyNVR 本身的账号负责登录,cpolar 后面只是负责公网入口。
11. 把 Go2RTC 的 RTSP 流接进 EasyNVR
进入 EasyNVR:
设备列表 → 添加

这里因为使用的是 RTSP 地址,所以当前接入方式选择:
PULL
然后填写拉流地址。

确认以后,设备出现在列表中,并显示在线。

接着进入设备播放页面。
当前录像计划一开始显示:
未录像
这里把录像计划设置为持续录制。

再点击:
直播中
进入观看页面。


到这里,这条核心链路已经完整了:
小米摄像头 → Go2RTC → RTSP → EasyNVR → /vol1/EasyNVR 本地录像。
原说明还提到 EasyNVR 页面可以切换 WebRTC、HTTP-FLV、RTMP、RTSP 等播放方式,并显示分辨率、编码、码率等信息。
至于云台控制,当前接入的是 RTSP PULL;能否控制还取决于源和协议是否提供相应能力,所以我不把“页面有按钮”直接写成这台摄像头已经验证了 PTZ 控制。
12. 真正检查录像:回放和时间段下载
录像计划启用以后,回到:
录像回放

点击查看,进入回放页面。

当前还可以按指定时间段下载录像。

这一步对我来说比“直播能看”更重要。
因为这篇真正想解决的是:
摄像头录像有没有持续留在自己的存储里。
直播成功,只能证明流通了;能看到历史回放、还能按时间段取录像,才说明录像链已经真正工作。
13. 局域网录像跑通以后,再给 EasyNVR 加公网入口
如果只在家里看,直接访问:
NAS IP + 10000
就够了。
人在外面时,想看实时画面或回放历史录像,再增加公网入口。

这里 cpolar 的职责非常单一:
把 EasyNVR 的 10000 Web 页面提供到公网。
它不负责拉取小米摄像头、不负责 RTSP 转换,也不负责录像写盘。
所以整条职责链是:
Go2RTC 拉流 → EasyNVR 录像 → cpolar 提供远程 Web 入口。
14. 在飞牛 NAS 安装 cpolar
仍然在前面的飞牛终端中执行:
sudo curl https://get.cpolar.sh | sh

安装完成以后查看服务状态:
sudo systemctl status cpolar

然后注册 cpolar 账号。

完成注册。

浏览器打开:
http://192.168.50.228:9200/

登录以后进入 Web UI。

15. 把 EasyNVR 的 10000 页面映射到公网
进入:
隧道管理 → 隧道列表
当前默认有两条隧道:
- ssh → 22 / TCP
- website → 8080 / HTTP

编辑 website。
当前修改为:
- 隧道名称:easynvr
- 本地地址:10000
- 地区:China Top

更新以后进入在线隧道列表。

复制 HTTPS 地址到浏览器。

EasyNVR 页面可以正常打开。
这一层验证的是:
EasyNVR 10000 → cpolar 公网地址 → 外部浏览器。
真正进入系统时,仍然由 EasyNVR 自己的账号负责登录权限。
16. 随机地址能用,再切固定二级子域名
随机公网地址适合先测试。
如果后面要长期在外面看录像、回放历史记录,我更希望入口本身保持不变。
进入 cpolar 预留页面:
https://dashboard.cpolar.com/reserved
选择保留二级子域名。

当前保留结果为:
- 地区:China Top
- 二级域名:easynvr
然后回到隧道列表,找到:
easynvr

点击编辑,把域名类型修改成:
二级子域名
再填写已经保留成功的名称。

更新以后,到在线隧道列表查看。

然后继续使用 HTTPS 地址测试。

页面可以打开。
再登录一次。

固定公网访问链就跑通了。
总结
这次换成 Go2RTC + EasyNVR,我最看重的不是“少了几个容器”这一个数字,而是整条链终于比较容易讲清楚了:
小米摄像头负责产生画面,Go2RTC 负责把流接出来并整理成 RTSP,EasyNVR 负责录像和回放,飞牛 NAS 的外置盘负责存储,cpolar 最后只负责把 EasyNVR Web 页面提供到公网。
这次实际跑通的主线是:
N1 → ARM 飞牛 NAS → Docker → Go2RTC → 小米账号 / 摄像头流 → RTSP → PotPlayer 测试 → EasyNVR → /vol1/EasyNVR → PULL 接入 → 持续录像 → 回放 / 时间段下载 → cpolar → 随机公网 → 固定二级子域名 easynvr。
几个边界需要特别留意:
- 当前新方案实际部署的是 Go2RTC 和 EasyNVR 两个容器;
- 原文同时出现“Micam 三件套”和“从 4 个容器减少到 2 个”两种描述,本文不强行替它们统一;
- Go2RTC YAML 中 rtsp: 段仍是注释状态,而后面又给出了带认证 RTSP 地址,真正使用时要确认自己是否实际启用了 RTSP;
- YAML 注释示例中的密码是 password,后面的认证 RTSP 示例使用的是 123456,两处应按实际配置对应;
- EasyNVR 的录像目录当前映射到 /vol1/EasyNVR;
- cpolar 只负责 EasyNVR 10000 的公网 Web 入口,不参与视频转换和录像;
- 页面能公网打开,不等于录像权限可以忽略,EasyNVR 仍然有自己的管理员账号。
对 N1 这种资源有限的小盒子来说,我更喜欢这种“每个组件只做一件事”的方案。只要 RTSP 稳定、录像能落盘、历史记录能回放,系统就已经完成了它最重要的工作;至于以后再接更多摄像头、做告警或换存储,至少不需要先把整个链路重新猜一遍。



