# 赵府智家 · 视觉系统 运行在自有小电脑上的视频管理程序。Python 标准库负责对象、空间、配置与登录;MediaMTX 负责 RTSP 接入、HLS 实时预览、本机录像及回放;浏览器使用本地打包的 hls.js。 ## 对象与空间 - **空间档案**:家庭 / 公司 / 其他,所属家庭或单位,省、市、区县、街道、小区或园区、楼栋、单元、楼层、门牌和详细地址。 - **摄像头对象**:实体设备的稳定 ID、品牌、型号、序列号、镜头数、安装位置和空间引用。 - **镜头通道**:每个物理镜头一个通道,关联摄像头对象,配置主、子码流。双镜头摄像头的主、子码流不能当作两个物理镜头。 - **录像机**:独立的设备与凭据档案,通道可以引用录像机获取画面。也可以直接连接摄像头。 - **录像来源**:明确区分录像机原有录像与小电脑新保存的录像。 ## 当前功能与边界 源码包括空间 / 摄像头 / 录像机 / 镜头档案,局域网 RTSP 探测、ONVIF 设备信息与独立镜头媒体配置读取、同源 HLS 播放、本机可选持续录像、日期查询、录像时间轴、定位回放和片段下载、存储保护、管理员初始化与登录。 **录像机原有历史录像回放尚未实现。** 需要取得具体型号及合法设备账号,接入其录像检索和回放接口;实时 RTSP 地址不能代替录像检索接口。驱动选项目前仅表示路径模板与接入类型,不能视为某个品牌全系列已经兼容。实际通道号需要由设备确认,不能根据三台双镜头直接猜成通道 1–6。 本机录像默认关闭,用户逐通道开启。默认保留 7 天、容量 40 GB、磁盘预留 8 GB,界面可调整。保留期限到达后 MediaMTX 自动删除本机录像;配额达到后暂停录制,不删除录像机中的数据。配额每 20 秒观察一次,允许少量超出。文件路径及录像索引使用 UTC,界面按浏览器时区显示。 HLS 会有数秒延迟。网页清晰度仅提供“主码流”和“子码流”两个选项,默认主码流。主码流预览使用实际主码流,通过 Intel VAAPI 硬件解码、缩放及 H.264 Main 编码,最高 1920×1080、15 帧/秒。子码流预览使用实际子码流,由 FFmpeg 按需生成 H.264 Baseline / AAC 兼容画面,最高 768×432、10 帧/秒。高清预览需要可用的 Intel 核显、驱动及 render 设备权限,不自动退回高负载的软件高清转码。首开需要等待取流与缓冲。没有观看者后会停止转码;同一镜头的观看者共享一路转码。网页不提供原始编码直出的预览选项。本机录像保留原始主码流编码,兼容预览不改变录像及摄像头设置。网页回放按需转换为 H.264/AAC,最多同时两个会话,每段最多一小时;使用时间轴或定位时间跳转。关闭回放或切换页面后终止转换,不生成额外缓存文件。有可用 VAAPI 时回放最高 1080p/15 帧,否则使用 768×432/10 帧软件转换。下载保留原始录像编码,需支持该编码的播放器。设备状态基于 MediaMTX 实际码流状态;“正在录像”还要求观察到近期写入的本机录像文件。离线不会生成假画面或假录像。 实时预览按镜头独立恢复连接:普通状态轮询只更新标签,不重建播放器;断流后按 2–30 秒退避重连,画面长时间不前进时也会自动恢复。用户主动暂停会保留暂停状态,离开页面会清理播放器和重试任务。 ## Ubuntu x86_64 部署 先将源文件提交、公开发布,再部署同一 Git 提交的归档。建议放在 `/opt/zhaovision/releases//`。Python 3.11 以上,无 pip 运行依赖。 ```sh sudo VISION_BIND=<本机的Tailscale-IPv4> bash deploy/install.sh ``` 安装脚本从系统软件源安装 FFmpeg;检测到 Intel renderD128 时安装 Intel 媒体驱动,授予服务用户 render 组权限,并校验安装固定版本 MediaMTX v1.21.1,创建无登录权限的服务用户,数据写入 `/var/lib/zhaovision`,应用入口为 `http://:8790/`。可用逗号分隔的 `VISION_BIND` 同时指定本机局域网与 Tailscale 地址;已安装系统在 `/etc/zhaovision.env` 中修改并重启服务。视频服务的 HTTP、RTSP 与管理 API 全部仅监听回环地址,由应用进行登录鉴权并代理。 首次打开页面,读取服务器上的 `/var/lib/zhaovision/setup-code.txt`,输入初始化码,设置至少 8 位管理密码(初始用户名为 admin)。初始化后码文件删除。摄像头与录像机密码在自己的界面填写。 ```sh systemctl status zhaovision zhaovision-media journalctl -u zhaovision -u zhaovision-media --since '10 minutes ago' ``` 程序不自动修改网络、防火墙、Tailscale 子网路由或设备密码。录像机仍按其原有设置运行。 ## 开发 ```sh python3 app.py # 在另一个终端运行 MediaMTX,使用首次启动生成的配置 mediamtx ./data/mediamtx.yml ``` 回归测试:`python3 -m unittest -v test_app test_ptz` 和 `node --test test_live_player.js test_kinship.js test_calendar.js test_family_graph.js`。测试使用临时数据库和模拟播放器,不连接真实设备。 访问 `http://127.0.0.1:8790/`。后端配置变量:`VISION_BIND`、`VISION_PORT`、`VISION_DATA`、`VISION_RECORDINGS`;高清转码可用 `VISION_VAAPI_DEVICE` 指定渲染设备(默认 `/dev/dri/renderD128`)。HTTPS 反向代理场景可设 `VISION_SECURE_COOKIE=1`。当前管理 API 使用管理员与个人账号分权。 ## 数据与恢复 数据库和生成的 MediaMTX 配置含设备连接凭据,存于权限受限的本机目录,不进入 Git。系统管理员可以读取这些凭据;当前版本未提供硬盘加密。备份时停止两个服务并一并备份整个 `/var/lib/zhaovision`。恢复到同一路径、修正服务用户所有权后启动服务。升级时保留数据目录,发布目录按提交留存,回滚 `current` 符号链接并重启服务;后续涉及数据库版本变更时需遵循对应迁移说明。 本仓库不包含真实家庭地址、设备凭据、视频文件或部署主机凭据。 ## 第三方软件 - [MediaMTX](https://github.com/bluenviron/mediamtx) v1.21.1,MIT,部署时独立安装。 - [FFmpeg](https://ffmpeg.org/),通过系统软件源安装为独立进程,用于按需兼容预览。 - [hls.js](https://github.com/video-dev/hls.js) v1.7.3,Apache-2.0,浏览器构建与许可证位于 `web/vendor/`。 - 官方接口参考:[录像](https://mediamtx.org/docs/features/record)、[回放](https://mediamtx.org/docs/features/playback)、[配置](https://mediamtx.org/docs/references/configuration-file)。 [系统架构与对象关系](ARCHITECTURE.md)。 本项目源码以 MIT 许可证发布。v0.1.x 为初始版本,真实录像机的历史回放兼容性需完成型号适配后另行验证。 ## 账号与家谱(v0.1.11) - 管理员维护设备、空间、账号和权限。个人账号只可观看授权空间内的实时画面与本机回放,设备配置、网络发现和审计接口仅管理员可用。媒体播放请求逐次检查空间权限。 - 每个账号具有独立用户名和密码,密码使用 scrypt 散列存储;更新密码、角色、空间范围、家谱权限或停用状态会撤销该账号会话。亲属关系不自动授予权限。 - 管理员在“账号与关系”中设置显示名称、相对于哪个账号的称呼,以及关联的家谱人物。支持常用称呼与自定义称呼。默认新个人账号没有空间或家谱权限。 - 家谱是本部署内的一份家庭档案,具有独立的不可访问、查看、编辑权限。一个编辑账号可录入任意数量的祖先、亲属与后辈,无需为每位人物开户。未实现跨家庭租户隔离。 - 人物记录姓名/称呼、别名、性别、生卒日期、在世情况、籍贯、生平和信息来源。日期可按公历或农历录入,并自动换算;不确定日期可留空,在备注中保留原记载。 - 亲子关系按“父母一方 → 子女”逐条连接,支持亲生、收养、继亲和未注明;配偶关系为双向。禁止自我关系、重复关系、祖先循环、直系祖先与配偶冲突。关系可以停用后恢复,人物可归档后恢复。 - 支持关系参照人物、搜索、全家关系图、人物名册和 JSON 导出。孙辈、曾孙辈、玄孙辈等直系辈分由路径推算;旁系复杂称谓显示明确路径,缺少出生日期时不猜测兄弟姐妹的长幼。称谓用于辅助阅读,以录入关系为准。 - 并发编辑使用家谱修订号,旧表单提交会被拒绝,避免覆盖他人的更新。导出包含人物和关系,不含密码和设备凭据。当前导出用于保存副本,尚未提供 JSON 导入界面。 ### 从 v0.1.10 升级 部署前用 SQLite backup API 保存 `/var/lib/zhaovision/vision.db`。首次启动 v0.1.11 会将原有单密码账户迁移为 `admin`,保留原密码散列,并把既有会话关联到管理员;没有固定出厂密码。新增 `users`、`people`、`family_links` 表和 `sessions.user_id` 列。以后可以直接升级;若回退到 v0.1.10,必须同时恢复升级前数据库副本,因为旧版本使用旧账户模型。人物和实际账号数据仅在受限数据目录中,不包含在公开源码内。 ## 监控墙、云台与日期(v0.1.13) - 监控墙支持自适应(每页最多六路)、1/2/4/6/9/16 分屏、翻页、拖动和前移/后移排列。布局和顺序按账号保存在当前浏览器;不跨设备同步。排列和分屏只改 CSS 与可见性,不重建播放器。全屏使用浏览器 Fullscreen API,Esc 退出。属于网页全屏模式,尚非可离线运行的安装包。 - 当前监控页的通道保持连接,翻页隐藏的通道也继续播放,以便切回时不重复连接;大规模通道应评估转码和网络开销。浏览器处于前台并保持系统唤醒时可持续监看。 - 云台读取 ONVIF PTZ 能力,仅对有匹配媒体配置、标准连续方向速度空间和一秒超时支持的直连摄像头提供四方向短距离微调。每次移动明确设置 PT1S,随后发 Stop;同一物理节点串行控制,独立停止按钮不排队。设备未声明的变焦、回到原点等功能不显示。协议参考:[ONVIF PTZ](https://www.onvif.org/ver20/ptz/wsdl/)。ONVIF 服务端口默认为 80。 - 管理员具有云台权限;个人账号需同时具备空间访问和独立的云台控制权限。新账号默认不允许转动。两个镜头如果指向同一 PTZ 节点,控制的是同一物理云台,不能据镜头数量推断独立电机。 - 人物默认在世;只在“不在世”时显示去世日期,旧人物的“待确认”状态保持原样。出生/去世各使用一个日期输入,选择历法,农历可勾选闰月;数据库统一保存公历日期,避免两份日期不一致。使用浏览器 ICU Chinese calendar,不联网。公历转农历范围 1901–2100,农历录入范围 1901–2099。更早祖先生卒日期可填公历并保留原始记载;不对古代历法作精确推断。 - 站点与标签页图标为“赵”字的甲骨文风格原创设计,并非考古字形摹本。参考字库及生成说明见 [ICON.md](ICON.md)。 ## 完整关系图与家族记事(v0.1.16) ### 看全家 进入“家谱”默认打开完整关系图,包含有效的亲子和配偶关系;归档人物默认隐藏,可勾选显示。每位人物只出现一次,不按代数截断。父母在上、子女在下,配偶在不违反亲子方向时并列;跨层配偶和复杂多重关系保留连线及提示。尚未建立关系的人单独展示,不推测亲属身份。 暖金色和“本人”标识只用于当前账号关联的家谱人物,由管理员在“账号与关系 → 关联家谱人物”设置。关系参照和当前选中人物可另外切换,不改变本人身份。管理员未关联人物时会提示,不把其他人误标为本人。支持点击档案、名册、人物搜索、放大缩小、拖动空白处、滚动条、查看全谱、定位本人、全屏和 Esc 退出。浏览器拒绝原生全屏时使用网页内铺满显示。 ### 记事的完整流程 1. 在“家族时间线 → 写一则记事”,或人物档案“记一件事”开始记录。 2. 填写标题、发生日期、摘要、正文,并可关联多位人物、附报道来源和 HTTP/HTTPS 链接。发生日期支持公历或农历输入,沿用日期换算范围,统一存储公历。 3. 可保存草稿,编辑完成后发布。发布范围是拥有家谱权限的账号,不是互联网匿名访问。家谱编辑者及管理员可查看和维护草稿、已发布内容、归档记录;只读成员仅能查看未归档的已发布记事。 4. 时间线默认从近到远,按发生年份分组,支持年份、人物、关键词、顺序和发布状态筛选。人物筛选可额外包括其直接父母、配偶和子女;每条记事按关联人物追溯,全家记事在“全家”范围显示。 5. 点击记事阅读详情或跳转原始报道;点击关联人物返回图谱和档案。人物档案可以再进入该人物的时间线,形成双向浏览。关系图默认不展开记事内容。 6. 归档保留数据;在“已归档”打开记录并编辑,取消归档后保存即可恢复。记事与人物、关系共用修订号,并发旧表单拒绝覆盖新版本。正文是纯文本,不执行 HTML 或嵌入第三方页面。 JSON 导出升级为格式 version 2,包含人物、关系和当前账号有权看到的记事。导出用于保存副本,尚无导入界面。外部报道只保存链接和用户填写的内容,不自动抓取网页;链接失效时,已填写的正文仍保存在本机。 ### 升级及数据 启动时幂等创建 `family_events` 表,无需修改既有人物、账号、摄像头或录像记录。部署前使用 SQLite backup API 备份数据库。还原备份会回退备份后的数据,旧版本看不到记事表;应保留升级后的数据库备份,不以旧版本界面作为记事恢复工具。源码中不含真实家族记事和人物信息。 ### 代理缓存兼容(v0.1.17) 入口 HTML 禁止缓存;页面引用的脚本和样式自动带上发布版本号,避免 NPM 等反向代理为旧资源设置长缓存后,新页面混用旧脚本。升级时普通重新载入即可获取与页面一致的资源。