Local person timelapses for NAS. ARM64, Web UI, resumable tasks and multi-day videos.
3.4K
从小米摄像头等设备导出的 MP4 中筛选含有人物的时段,并生成延时摄影视频。适合将大量家庭监控录像留在 NAS 上本地处理。
原始录像始终以只读方式挂载:工具不会移动、改名或删除任何源文件。人物识别、缩略图、事件索引和成片都只写入独立的输出目录。
镜像已公开发布至 Docker Hub:tingfe/person-timelapse-nas。推荐使用 Compose 部署:
当前发布的镜像仅支持 Linux ARM64,适用于极空间 Z2 Pro 等 ARM64 设备;Intel/AMD 的 x86 NAS 暂不能直接使用此镜像。
services:
person-timelapse:
image: tingfe/person-timelapse-nas:latest
container_name: person-timelapse
environment:
# 使用强密码;也可留空,首次启动后在 output/.access-password 查看随机密码
- AUTH_PASSWORD=${AUTH_PASSWORD:-}
volumes:
# 改为你的录像目录;务必保留 :ro
- "/path/to/your/camera-recordings:/input:ro"
# Compose 项目目录下自动持久化结果和模型
- "./output:/output"
- "./models:/models"
ports:
- "8790:8790"
restart: unless-stopped
启动后在同一局域网打开:
http://NAS 的局域网 IP:8790
首次访问需要输入密码。推荐在极空间项目的环境变量中设置 AUTH_PASSWORD;若留空,服务会生成随机密码,并保存到持久化的 output/.access-password(也会打印在首次启动日志中)。
首次启动会后台读取录像目录并建立日期索引,索引元数据持久化为 output/inventory.sqlite3。有旧索引时会先显示旧索引,并在后台检查变化;没有索引时需等待首次索引发现录像日期后再创建任务。默认每小时检查录像目录,管理页的“检查新增录像 / 刷新索引”可立即触发检查。页面刷新和任务状态查询不会反复遍历整个录像目录。
在 Docker 的“创建项目 / Compose 配置”中粘贴上面的配置。录像目录请使用“查询路径”获得的真实容器宿主机路径,例如:
- "/tmp/zfsv3/磁盘标识/data/摄像头文件备份:/input:ro"
不要加入旧版本示例中的 working_dir 或 command。更新时点击“重新构建”;也可以固定版本以避免自动更新:
image: tingfe/person-timelapse-nas:sha-提交哈希
范围计划保存在原有的 output/tasks.json 中,旧的导出任务会根据已有日期和依赖记录自动归组,无需重新扫描。完成的范围任务只展示最近 12 项,所有有效成片仍可通过成片库筛选和翻页查找。自动刷新会保留正在选择的年份、月份、范围、筛选条件与页码。
任务队列始终只同时执行一个扫描或导出任务,运行中仍可追加新任务。点击“暂停队列”会停止当前任务并保留扫描检查点和已经校验的合成片段。NAS 或容器重启后,原任务会自动恢复排队,范围合成的前置依赖也会保留。
合成使用临时文件,校验通过才替换原成片;失败不会覆盖已有视频。坏文件会记录为失败而不是“已处理”。若只有部分素材可读,任务标记为“部分完成”,请查看日志后使用“重试 / 继续”。历史录像会先读取真实视频时长,将超出实际结尾的事件截断,并单独显示“时长校正”,不把这种偏差误报为解码损坏。
延时合成默认使用 关键帧快速抽样:每段事件批量抽帧,先缩小画面,再进行合成,避免为每张图片反复解码整段高分辨率 H.265。画面来自相邻关键帧,可能重复或有时间偏差,适合家庭回顾,不适合逐秒精准取证。需要精确解码时,在容器环境变量中设置 EXPORT_DECODE_MODE=accurate(速度会明显降低)。成片旁的 JSON 记录实际使用的 decode_mode。
单批最多抽取 30 帧,解码过程中持续更新心跳;超过 120 秒未完成的批次会停止并记录失败,其他素材继续处理。可通过 EXPORT_DECODE_TIMEOUT_SECONDS 调整此上限。原始录像不会被转码或修改。
延时合成也支持断点续做:每个源录像生成一个经过校验的 1280×720 片段(保持原比例,必要时补黑边),保存在 output/.export-cache/v1/。暂停或重启后只重做未完成的源录像;制作更大日期范围时,相同素材、事件和参数的片段也可复用,最后直接拼接,不重复编码。源文件大小/修改时间、事件、抽帧间隔、帧率或解码模式变化时会自动重做对应片段。读取不完整的片段不会被当作完整检查点复用。
片段缓存会额外占用磁盘空间,但不包含原录像副本。请保持 /output 持久化,运行任务时不要删除或移动缓存;备份整个 output 可同时保留队列、索引、扫描结果和合成检查点。旧版本运行中的合成没有片段检查点,升级无法恢复其尚未保存的中间帧;建议等旧任务结束后再更新。
output 目录;录像源目录不需要移动。/output、/models 挂载位置和访问密码。仅重启旧容器不会更新镜像。processed.json 与事件文件会继续读取,新扫描检查点保存在 output/scan-results/日期/,旧事件备份在 output/legacy-events/。不要只迁移 processed.json,也不要删除 scan-results。早期版本留下的任务会自动补齐进度文件、日期列表和扫描档位;没有记录档位的旧扫描使用“极速”。迁移前的完整队列保存在 output/tasks.pre-migration-*.json,原任务编号、范围合成依赖和已完成状态保持不变。任务配置或启动失败会明确显示错误,并允许后续任务继续,不再停留在无进度的“运行中”。
默认连续 300 秒没有进度会停止卡住的任务。扫描会记录该文件失败,并尝试继续剩余文件;连续超时次数有上限,避免无休止重启。确实需要更长单文件处理时间时,可在 Compose 的 environment 中加入 TASK_STALL_SECONDS=600。索引检查间隔可通过 INDEX_REFRESH_SECONDS 调整(单位:秒,默认 3600)。
旧镜像不认识新的文件级检查点;如需回退,请使用更新前的整份输出目录备份,避免重复扫描或状态不一致。不要用删除输出目录的方式排障。
镜像将 AI / FFmpeg 运行环境与程序代码分层保存。基础镜像固定到内容摘要,发布时从 Docker Hub 的上一版镜像恢复构建缓存;只修改程序代码时,NAS 可复用已下载的依赖层,只下载变化的代码层。首次安装、首次启用缓存、清理过本地镜像或升级依赖后,仍可能需要下载较大的依赖层。
拉取时 Already exists 表示该层已缓存,Downloading 是网络下载,Extracting 是本地解压。下载速度仍取决于 NAS 到 Docker Hub 的网络;不要为了加速而删除现有镜像缓存。浏览器或 Mac 上的代理不会自动应用到 NAS 的 Docker 服务,应在 NAS 支持的设置中单独配置可信代理或镜像源。
人物识别完全依赖 CPU 时,长时间监控录像的处理会很慢。建议先从“超极速(历史回放)”开始:120 秒抽帧、256px 推理,适合粗筛大量历史录像;只对需要复查的日期使用“极速”“平衡”或“精细”。
| 档位 | 适合场景 | 取舍 |
|---|---|---|
| 超极速 | 大量历史回放 | 速度最快,可能漏掉短暂出现的人物 |
| 极速 | 日常全天回顾 | Z2 等低配置 NAS 的折中选择 |
| 平衡 / 精细 | 短录像复查 | 更容易捕捉短事件,但耗时明显增加 |
如果超极速仍无法接受,最有效的方案是让 NAS 仅保存录像,在带 GPU 的电脑上挂载 NAS 目录执行识别。
Apple Silicon Mac 可用 Metal/MPS 参与计算。将 NAS 的录像目录与 延时摄影 输出目录通过 SMB 挂载到 Mac 后,在本仓库运行:
export INPUT_ROOT="/Volumes/camera-recordings"
export OUTPUT_ROOT="$INPUT_ROOT/延时摄影"
chmod +x mac-worker.sh
./mac-worker.sh 20000101 5
也可以启动仅限本机访问的可视化控制台:
sh mac-console.sh
/Volumes/camera-recordings 是通用示例,请先将 INPUT_ROOT 改为自己实际的 SMB 挂载目录;OUTPUT_ROOT 必须与 NAS 容器的 /output 指向同一目录。在同一个终端启动控制台和索引工具,以便继承这些环境变量。示例日期与文件名均为虚构,请换成自己的录像日期。
随后打开 http://127.0.0.1:8791,选择日期和本次最多处理的文件数,一键启动或停止;日志会直接显示在页面内。
第二个参数是本次最多处理的未处理 MP4 数量(例如 5),可随时按 Ctrl-C 停止;已完成文件会立即记录在 NAS 的 scan-results,下次运行自动续接。首次运行只会在仓库目录创建 .mac-worker-venv 独立虚拟环境,进度写入本地 .mac-worker-state,不修改系统 Python、Homebrew 或 Docker。NAS 与 Mac 应使用同一版本代码和相同的输出目录,文件锁会避免同时扫描同一文件。
Mac worker 默认会取得“计算优先权”:运行期间 NAS 不会启动新的扫描任务;Mac 正常结束、停止或离线超过 15 分钟后,NAS 队列自动恢复。已在 NAS 运行中的任务不会被强行中断。
Mac 也可以协助建立 NAS 日期索引,不需要安装 AI 依赖:
sh mac-index.sh
它会将共享的 inventory.sqlite3 写入 NAS 输出目录。索引锁会协调 NAS 与 Mac,已有节点建立索引时另一节点会提示稍后重试,不会并发改写数据库。
文件名时间用于归档,不依赖 NAS 的修改时间。支持例如:
00_20000101090000_20000101091000.mp4
video_0000_10_10_20000102090000_20000102093000.mp4
20000103090000_20000103090030.mp4
前两类中的 00、10 会作为不同摄像头;第三类历史文件会归入“历史录像”摄像头。
Web 管理页已覆盖常用操作。如需在容器终端运行:
python /opt/person-timelapse/person_timelapse.py scan /input /output --date 20000101
python /opt/person-timelapse/person_timelapse.py export /input /output /output/events-20000101.json --camera 0
多日导出可连续传入多个事件文件:
python /opt/person-timelapse/person_timelapse.py export /input /output \
/output/events-20000101.json /output/events-20000102.json --camera 0
8790 映射到公网;请仅在家庭局域网使用。推送到 main 后,GitHub Actions 会先运行可靠性回归测试,通过后才构建 ARM64 镜像并发布 latest 与 sha-提交哈希 标签。维护者需要在 GitHub Actions Secrets 中配置 DOCKERHUB_USERNAME 与 DOCKERHUB_TOKEN;使用者不需要任何 Docker Hub 凭据。
Docker Hub 的短介绍与 Overview 由独立的 Sync Docker Hub overview 流程维护:README 修改后自动同步,也可在 Actions 中手动运行。它复用上述 Secrets,不重建镜像;发布后读回内容校验,失败会明确报错。Docker Hub 上的文档链接会自动指向 GitHub,不依赖相对路径。出于隐私考虑,镜像不附带构建来源证明(provenance: false),构建记录附件和构建摘要也不公开;仍可通过 sha-提交哈希 标签对应源码版本。流水线会屏蔽事件中的邮箱,并在每次发布后自动检查所有公开镜像标签的配置、元数据和应用代码层。不要在流水线中打印完整环境变量、事件或凭据。
维护者也可手动运行 Audit public image privacy,只读检查公开镜像所有标签的配置、来源证明及应用代码层。检查结果不打印命中的邮箱或凭据;它不下载或审查第三方运行时大层,也不能代替完整的人工安全审计。
发布使用镜像内嵌缓存,不需要额外的缓存服务或缓存标签;请勿删除唯一的 latest 镜像缓存来源。需要刷新系统依赖时,在 Actions 手动运行发布流程并勾选 refresh_dependencies,该次会重新安装依赖,NAS 更新时也可能需要重新下载依赖层。升级 AI 基础环境时需审查并更新 Dockerfile 中的版本和摘要。构建上下文仅包含应用目录和构建说明,不上传录像、输出目录、模型、Mac 虚拟环境或根目录的凭据文件。缓存方案参考 Docker 官方说明。
本地测试:python3 -m unittest discover -s tests -v。真实编解码集成测试需要现有的 OpenCV 和 FFmpeg 环境,并设置 RUN_MEDIA_INTEGRATION=1;测试只使用生成的色块画面,不读取私人录像。
可选界面回归:使用已有的 Playwright 环境,在一个终端运行 python3 -m http.server 18879 --bind 127.0.0.1 --directory app,另一个终端运行 node tests/browser_console.cjs。该脚本只使用模拟数据,检查月历、跨年筛选、分页、刷新保持状态及手机布局,不连接 NAS、不启动实际计算。
Content type
Image
Digest
sha256:59d7d71c9…
Size
1.1 GB
Last updated
4 days ago
docker pull tingfe/person-timelapse-nas