ericwyuan
2c5bf950c5
feat: 事件时间轴缩略帧 + 人物管理头像 + 人物合并硬规则校验
...
## 新架构:Oracle 集中计算 + NAS 代理展示
### Oracle 端 (fam-edge)
- 新增 frame_service: ffmpeg 视频抽帧 + VLM 人物定位裁剪头像(磁盘缓存)
- 新增 /api/oracle/frame: 按 video_id+ts 抽帧返回 jpeg(带 token)
- 新增 /api/oracle/avatar: 按 label 生成人物头像(VLM 定位人物 + 兜底整帧居中)
- 新增 person_identifier: 人物身份识别模块
- Gemini 适配器支持 flash/flash-lite 双模型切换,429 自动降级
- frame_service VLM 全模型 429 时进入 10 分钟熔断,避免每次请求白打配额
- 兜底头像不落缓存,配额恢复后自动重试 VLM 精确定位
### 人物合并硬规则校验(框架级修复)
- person_service: LLM 合并结果落库前加硬冲突检测
- 性别冲突 → 绝不合并
- 年龄档跨未成年/成年 → 绝不合并(防止把爷爷/宝宝并进同一人)
- oracle_db: upsert_person 入口剥离括号后缀(人物A(别名:人物B) → 人物A),消灭垃圾人物行
- 修复 set_canonical 丢弃 source 参数的 bug(旧代码硬编码 'manual' 导致错误合并被永久固化)
- get_events_for_label: 只提取该身份组的特征文本,头像定位更精准
### NAS 端 (fam-core)
- 新增 img_proxy: /api/proxy/frame 和 /api/proxy/avatar 代理 Oracle 图片
- app.py 注册 img_bp 蓝图
- oracle_sync / db_layer / member_manager 同步人物表
### UI 端 (fam-ui)
- 事件时间轴: 每条事件卡片加时间点缩略帧
- 人物管理: 每人卡片加头像(150x150 圆角)
- parse_persons: 剥离括号备注,与 Oracle 归一化一致
- 新增 EventItem 组件、Timeline 页改造
- Chat / ServiceStatus 页相应调整
### 数据库
- scripts/ddl.sql: 同步表结构更新
- Oracle people 表: features_json / display_uid / source 字段完善
2026-08-23 00:13:56 +08:00
ericwyuan
1dd9df34c2
[功能] 事件-片段一致性对账 - /api/oracle/activity 加 segment.consistency(事件总数/已结束/已分割/缺口+明细/素材覆盖范围), 服务状态页展示一致性数字
2026-08-22 13:40:42 +08:00
ericwyuan
cbcc5d0325
[功能] 服务状态页新增「视频分割」状态 - Oracle /api/oracle/activity 加 segment(运动片段 done/pending/failed/文件数/最近分割活动), ServiceStatus.vue 加视频分割卡片
2026-08-22 13:18:57 +08:00
ericwyuan
4cf4fc4bc2
[功能] 人物管理按运动视频重设计 - 人物卡新增「运动片段」区块(缩略图/时间/摘要/事件数,点击跳时间轴定位); 新增 GET /api/ui/people/clips 后端接口(按 label/canonical_name 查关联运动片段,含 first_ts/clip_events); Timeline 支持 ?video= 定位
2026-08-22 12:55:30 +08:00
ericwyuan
708b6365f4
feat(fam-edge): Gemini key 分配改真随机 + 按项目名标注统计
...
用户明确要求: 每次调用应该是 1/n 概率的真随机抽取,而不是上一版的顺序轮转
(round-robin 在当前单消费者串行处理场景下已经是数学最优均匀分配,但用户想要
"数组里随机取一个,每次都是四分之一概率"这种更直观的随机语义)。_rotated_keys()
去掉持久的轮转下标,改用 random.randrange 每次调用随机选起点,仍保留"起点 key
全部模型失败就级联到下一个 key"的兜底逻辑不变。
同时新增 key_labels 配置:4 个 key 分别对应用户在 Google Cloud 上开的 4 个项目
(智能摄像头-1/2/3/4),model_calls 统计现在按项目名而不是泛化的 key1/key2
展示,ModelStats 页面的 Key 列/拆分逻辑同步改为按最后一个 "·" 分隔(原来写死
按 "·key" 前缀查找,项目名场景下不适用)。
新增/重写 7 个单测覆盖:随机起点级联顺序、randrange 调用范围正确性、大样本
随机分布均匀性、key_labels 默认值/自定义值/key 被丢弃时的对齐。
2026-08-22 07:37:33 +08:00
ericwyuan
22df28f2d3
feat(fam-ui): 各页面加载状态 - 数据到达前不再是空白/半截页面
...
新增 Spinner 组件,接入时间轴/AI对话历史/人物管理/统计图表/模型统计/
服务状态 6 个页面。People.vue 特殊处理:命名或合并后触发的刷新不重新
显示整页 Spinner(此时列表已有数据,会闪一下丢失滚动位置),只有首次
加载(列表为空)才转圈。ServiceStatus.vue 同理,手动点刷新只变按钮文
字,不重新蒙一层 Spinner。
2026-08-22 07:19:32 +08:00
ericwyuan
7579782daf
refactor(fam-ui): 重构第三阶段 - Streamlit 换成 Vue3+Vite+Tailwind 完全重写
...
范围变更:原计划是给 Streamlit 界面做视觉美化,用户中途要求换新框架完全重新实现。
最终方案:Vue 3 + Vite + Tailwind CSS v4,本地 npm run build 出静态文件,NAS 不装
Node.js,由 fam-core 的 Flask 直接提供(send_from_directory),原来独立跑在 :8501
的 Streamlit 进程整个退休,前端和 API 合并到 fam-core 的 :8000 一个进程。
fam-core 新增只读 API(ui_api.py):全部包装 db_layer.py 里已有的查询函数,没有
新写查询逻辑(除了下面两处真实缺口)。新增 static_app.py 做 SPA 静态文件服务
(assets 直出 + 非 API 路径回退 index.html 供前端路由接管),app.py 注册顺序上
必须排在其他 /api/* 蓝图之后。
顺带补的两个功能缺口(旧 Streamlit 版本自己绕开 db_layer 写了裸 SQL 才有的功能,
db_layer 本身不支持):
- get_chat_history 补 offset 参数(分页)
- 新增 get_attention_events(统计图表页"关注事件"表格)
fam-ui 完全重写为 Vue 3 项目:7 个页面 1:1 迁移功能(事件时间轴/AI对话/对话历史/
人物管理/统计图表/模型统计/服务状态),深色主题设计系统(Inter+JetBrains Mono
字体、蓝紫渐变强调色、语义色 token)。用本地 npm run dev 代理到真实 NAS 数据做
了完整联调,过程中发现并修了两个真 bug:
- URLSearchParams 把 undefined 转成字符串 "undefined" 传给后端,导致日期筛选失效
- MariaDB SUM() 返回 Decimal,Flask 默认序列化成字符串,前端字符串拼接出乱码数字
(ui_api.py::_ser 统一转 int/float 修复)
移动端 H5 补了响应式:原来的固定宽度侧边栏 + flex-wrap 导航在手机宽度下会把每个
按钮挤到文字逐字换行;改成 lg 以上桌面侧边栏、lg 以下移动端顶栏 + 横向可滑动导航
胶囊;人物管理页命名表单(输入框+命名按钮+合并下拉)在窄屏下改为纵向堆叠。
已部署 NAS 并验证:curl 确认 index.html/assets/深层路由/API 路由全部 200;
Browser 工具在桌面宽度和手机宽度下把 7 个页面点了一遍(含真实提问一次 AI 对话、
人物头像/事件缩略图加载、命名合并表单),旧 Streamlit 进程已停止。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-08-22 06:48:25 +08:00
ericwyuan
ff01d14c79
feat(v3): 人物模块重构 - 大模型结构化特征值替代 OpenCV 帧定位。prompt 增加 person_appearances(uid+7特征+action)并重写合并 prompt(稳定特征优先比对);gemini 透传特征字段;oracle_db events/people 加 person_appearances_json/features_json/display_uid + _merge_features;video_processor 去 cv2 改 ffprobe 校验、_store_result 聚合 uid 特征落 people、删缩略图/事件截图;person_service 聚合特征后基于特征文本 LLM 合并;api_gateway 删 3 个图接口;NAS 镜像+DDL 加新字段;fam-ui 特征卡替代头像、事件时间线人物特征块
2026-08-21 18:06:21 +08:00
ericwyuan
2ba3478291
fix(头像): 人物头像改为'出现事件画面'而非视频首帧 - 新增 /api/oracle/person/avatar(在该人物所有出现事件中返回第一个有截图的事件画面,JSON 精确匹配);撤销 event_thumb 的视频首帧兜底(首帧可能无人/非本人);fam-ui 人物页改调 avatar 接口
2026-08-21 16:13:05 +08:00
ericwyuan
0d0a7f6ef8
feat(监控): 实时服务状态界面 - Oracle 新增 service_activity 活动表(只保留7天,写入时清理)与 /api/oracle/activity 接口(队列实时状态/当前处理视频/模型调用/rclone/人物合并/最近50条活动);VideoQueue 打点+当前处理跟踪+status();PersonService 打点;rclone_sync.sh 同步结果写活动表;fam-ui 新增'🖥 服务状态'页(状态卡+活动时间流,直连 Oracle 实时拉取)
2026-08-21 15:52:36 +08:00
ericwyuan
da7631976d
fix(ui): 日期维度改用视频录制时间 - 前端事件时间轴/统计/关注事件与后端 db_layer 统一按 event_start_time(文件名解析) 分组排序,空值回退 processed_at;修复全量重分析导致处理时间(8/21)把 8/15-8/20 视频全堆同一天、与文件名对不上的问题
2026-08-21 15:00:41 +08:00
ericwyuan
92ef9fe163
feat(ui): 人物管理显示人物代表画面 - 每个身份取其一 label 出现事件的截图作为头像(Oracle event thumb 接口)
2026-08-21 14:03:43 +08:00
ericwyuan
05f727a9ef
feat(events): 每个事件生成对应时间点画面截图 - oracle_db.mark_video_processed 返回 event_ids;video_processor 按事件时间戳-视频起始时间偏移跳帧截图存 ev_{id}.jpg;新增 /api/oracle/event/{id}/thumb 接口;fam-ui 事件列表每条显示对应截图
2026-08-21 13:44:16 +08:00
ericwyuan
41485072bf
fix(ui): sync_events 查询补 JOIN sync_videos 取 camera_name(修 1054 报错);feat(缩略图): Oracle 处理成功后抽首帧存 thumbs/{id}.jpg + /api/oracle/video/{id}/thumb 带 token 接口;fam-ui 视频会话显示缩略图(oracle_url+token);start_ui.sh 注入 .env
2026-08-21 13:37:23 +08:00
ericwyuan
3e94c2a8b0
feat(nas): 模型调用统计镜像与界面 - sync_model_calls 表+拉取+聚合统计;fam-ui 新增' 🤖 模型统计'页(按模型成功/失败/成功率/平均耗时 + 最近调用明细含失败原因)
2026-08-21 12:23:32 +08:00
ericwyuan
44026b65ea
[阶段3] FAM-Core 瘦身为管理后台+Oracle-Sync 同步引擎,FAM-UI 改读同步镜像 - 删除 scheduler/dispatcher/poller/event_receiver/video_server,新增 oracle_sync 每30分钟拉增量写 sync_* 镜像表;member_manager/chat_handler 改走同步数据;UI 移除帧图改为事件时间线;DDL 新增 sync_videos/events/people/cursor
2026-08-21 10:38:26 +08:00
ericwyuan
ae1c13589f
fix(人物管理): 头像优先选独照帧,避免双人图当头像
...
人物卡片头像挑选策略调整:
1. 优先『独照』帧——该帧只有当前人物一个标签且 face_count=1(双人图不再作为某人头像)
2. 无独照时退而求其次用 face_count 最大的帧
3. 最后按时间序第一张兜底
修复: 一张图出现两人时(如 event_21/frame_3 '人物1, 人物2'),两人卡片都拿双人图做头像、无法区分的问题
2026-08-21 05:54:38 +08:00
ericwyuan
73f6c77544
feat(人物管理): 头像优先选有人脸帧 + 人物合并到操作
...
1. person_photo 读 event 的 meta.json(face_count),优先挑人脸数最多的帧做头像,无 meta 时按时间序第一张兜底
2. 人物卡片新增「合并到」下拉框+按钮,调 /api/member/merge(source=当前人物,target=所选人物),展示替换明细数
3. 至此设计文档 8 项需求全部落地(Edge 画框/mark_frames 端点/meta.json/backfill/merge_member/merge 路由/UI 头像+合并)
2026-08-21 00:57:20 +08:00
ericwyuan
43b3178a9d
feat(人物管理/红框标记): 关键帧人脸标记 + 人物命名重命名回溯 + 人物管理页改版
...
1. fam-edge 新增 frame_marker.py: Edge 端人脸检测画红框+统计人脸数(NAS ARM 太弱只存图零计算),orchestrator 分析后回传前标记,新增 /api/edge/mark_frames 批量补标端点
2. fam-core 新增 tools/backfill_mark_frames.py: 存量关键帧批量补红框(幂等+备份 frames_orig)
3. db_layer.name_member 增强: 支持自动注册新标签/重命名回溯(旧真名一并替换)/多人组合字符串 REPLACE
4. fam-ui 成员命名页改为人物管理页: 所有人物照片墙+命名重命名+统计去重
5. event_receiver/member_manager 配套适配
2026-08-21 00:53:30 +08:00
ericwyuan
3fb86ee449
fix: 出现人物统计去重 + 导航移至页面顶部
...
- person 字段是自由文本,一帧可为多人组合且带括号特征描述
('张三 (红色T恤), 汤圆, 人物3'),COUNT(DISTINCT person) 把每种
组合字符串当一个人物,全局误报 20 人。新增 resolve_persons:
去括号描述 -> 按中英逗号/顿号/斜杠拆分 -> family_members
抽象标签映射真名,去重后全局实际 6 人
- 导航从侧边栏 radio 改为顶部 segmented_control:窄屏下
Streamlit 侧边栏自动收起,页面入口藏进汉堡菜单导致
"成员命名/问答界面不见了";放主区域顶部任何屏宽可见
2026-08-21 00:22:24 +08:00
ericwyuan
f50f98e292
ui: 事件列表条目带年月日 — 跨天事件可区分
...
跨多天的事件列表仅显示 HH:MM 无法区分日期。按钮标签加 MM-DD
前缀,摘要行加浅蓝 YYYY-MM-DD 前缀,摘要截断 26→30 字适配。
2026-08-20 23:50:31 +08:00
ericwyuan
0d5173f442
feat: UI 时间轴重构 + 关键帧图片全链路持久化
...
界面重做(深色监控面板主题):
- 事件时间轴页: 左侧事件列表卡片 + 右侧关键帧时间轴
(时间点 + 视频帧 + 人物/动作/衣着摘要 + 关注标记)
- 全局 CSS: 深色主题、卡片化按钮、统计卡、对话气泡、成员卡片
- 侧边栏任务队列状态徽章; 历史帧无图时优雅降级占位
关键帧持久化链路:
- Edge orchestrator: process_push_task 成功后把 keyframes
base64 注入 frame_details[i].frame_image (位置对齐视觉输入帧)
- NAS event_receiver: 落库前 base64 解码写盘到
fam-ui/static/frames/event_{id}/frame_{idx}.jpg
- payload 增量 ~300KB/事件 (6帧 jpeg q80), 队列/拉取均无压力
配置: fam-core/fam-ui 新增 storage.frame_image_dir
2026-08-20 19:50:36 +08:00
ericwyuan
94a8805045
feat: FAM-Edge chat proxy + PyMySQL migration for FAM-UI + config update
...
- FAM-Edge: add /api/edge/chat proxy endpoint forwarding to local Ollama
(Ollama port 11434 not exposed externally, FAM-Edge acts as reverse proxy)
- FAM-Core config: edge_url and ollama_url switched from Tailscale IP to
Oracle public IP (Tailscale firewall blocking between NAS and Oracle)
- FAM-UI: migrate mysql.connector to PyMySQL (same as FAM-Core)
- FAM-UI: cursor(dictionary=True) replaced with cursorclass=DictCursor
- End-to-end chat verified: FAM-Core -> FAM-Edge proxy -> Ollama -> response
Answer: 今天没有观察到张三 (no events in DB yet, expected)
2026-08-19 23:59:28 +08:00
ericwyuan
4cfb327455
[4.1-5.4] FAM-UI Streamlit - 事件列表/筛选/明细/AI对话/对话历史/成员命名/统计图表 + 配置
2026-08-19 22:26:56 +08:00