[重构] 运动事件驱动架构 - 整段素材按 ss_motion_events 分割运动片段再分析(不再整段送云端): oracle_db 加 motion_event_id/camera_id 列 + get_motion_events_in_range/has_unfinished_motion_in_range/get_video_by_motion_event_id; video_processor 素材→分割/片段→分析双分支(ffmpeg -c:v copy -c:a aac 保留音频); video_queue 片段入队; config 加 motion_segment 块

This commit is contained in:
ericwyuan
2026-08-22 12:19:17 +08:00
parent 2d9d96de56
commit a1523b46c8
5 changed files with 372 additions and 59 deletions

View File

@@ -47,18 +47,24 @@ video_processing:
# 降级顺序:先 gemini 整视频,失败再 nvidia 整视频;两者都失败 -> 标记 failed
vision_order: ["gemini", "nvidia"]
# 运动侦测预过滤2026-08-22 重构2026-08-22 补心跳
# - 甲骨文【不再反向访问 NAS】。原 dsm_motion_client甲骨文主动查 SS API已停用
# 改由 NAS 端 fam-core 的 MotionNotifier 接收 SS Webhook 后,主动 POST 推送到
# 甲骨文 /api/ss/motion落库 ss_motion_eventsNAS 侧还会定期用空 events 单纯
# 调一次这个接口当心跳(不要求真的有事件),证明推送链路还活着。
# - video_processor 分析前调用 db.has_motion_in_range_local()(本地运动事件表)做
# 预过滤窗口内无运动事件则跳过云端分析compute_provider=skipped_no_motion
# - 安全阀门: 距上次心跳超过 max_heartbeat_age_sec 没更新NAS 服务挂了/网络断了/
# DSM Webhook 规则被误关,历史数据表非空但推送链路已经死了),一律 fail-open
# (照常分析),不能仅凭"表里曾经有数据"就信任"这段时间确认无运动"的结论。
# 运动事件2026-08-22 运动事件驱动架构
# - NAS 端 fam-core MotionNotifier 轮询 SS 事件后POST 推送到甲骨文
# /api/ss/motion落库 ss_motion_eventsstart_time/duration 为 Unix epoch
# 并定期用空 events 调接口当心跳,证明推送链路存活。
# - video_processor 不再整段分析:整段素材按 ss_motion_events 中【已结束】的
# 运动事件分割成运动片段motion_segment 配置),只分析运动片段。
dsm_motion_prefilter:
max_heartbeat_age_sec: 900 # 心跳超过 15 分钟没更新 -> 判定推送链路可能已死fail-open
max_heartbeat_age_sec: 900 # 心跳超过 15 分钟没更新 -> 判定推送链路可能已死
# 运动片段分割运动事件驱动架构2026-08-22 新增):
# 整段素材视频rclone 同步落地)按 ss_motion_events 分割成运动片段再分析。
# 只分割已结束事件start_time+duration 落在当前时刻附近),进行中的事件
# 等结束后的下一轮再分割;素材保持 pending 直到窗口内事件全部结束。
motion_segment:
clips_dir: "/opt/fam-edge/motion_clips" # 分割产物目录
keep_audio: true # 保留音频pcm_alaw -> aac 64k 转码false 则 -an 去音频
min_duration_sec: 1 # 短于该时长的事件不分割
unfinished_grace_sec: 10 # start_time+duration 距当前 ≤ 该秒视为"已结束"容差
# 智能问答降级链与视频分析独立Gemini -> NVIDIA -> 本地 Ollama
models: