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
This commit is contained in:
@@ -171,6 +171,18 @@ class AIOrchestrator:
|
||||
adapter.get_circuit_breaker().record_failure()
|
||||
return model_outputs
|
||||
|
||||
@staticmethod
|
||||
def _attach_frame_images(frame_details: List[dict], frame_paths: List[str]) -> None:
|
||||
"""把关键帧图片 base64 附加到 frame_details(按位置对齐视觉分析输入帧)"""
|
||||
for i, fd in enumerate(frame_details):
|
||||
if i >= len(frame_paths):
|
||||
break
|
||||
try:
|
||||
with open(frame_paths[i], 'rb') as f:
|
||||
fd['frame_image'] = base64.b64encode(f.read()).decode('ascii')
|
||||
except OSError as e:
|
||||
logger.warning(f"关键帧图片读取失败: {frame_paths[i]}: {e}")
|
||||
|
||||
def format_cloud_result(self, provider: str, raw_result: dict,
|
||||
known_members_context: str = '',
|
||||
task_id: int = 0) -> dict:
|
||||
@@ -481,6 +493,10 @@ class AIOrchestrator:
|
||||
fusion_result = self.format_cloud_result(
|
||||
provider, model_outputs[provider], known_members, task_id)
|
||||
|
||||
# 5. 附加关键帧图片(NAS 落盘后供 UI 时间轴展示)
|
||||
frame_details = fusion_result.get('frame_details', [])
|
||||
self._attach_frame_images(frame_details, compressed_frames)
|
||||
|
||||
total_ms = int((time.time() - start_time) * 1000)
|
||||
log_task(logger, task_id, 'overall', '推送任务完成', duration_ms=total_ms)
|
||||
|
||||
@@ -492,7 +508,7 @@ class AIOrchestrator:
|
||||
"camera_name": task_data.get('camera_name', ''),
|
||||
"global_summary": fusion_result.get('global_summary', ''),
|
||||
"entities_json": fusion_result.get('entities_json', []),
|
||||
"frame_details": fusion_result.get('frame_details', []),
|
||||
"frame_details": frame_details,
|
||||
"compute_provider": fusion_result.get('compute_provider', []),
|
||||
"error_message": None
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user