Skip to content

Trace Thumbnail Regenerate API 使用指南 — Studio 團隊參考

版本: v1.0 日期: 2026-08-12 狀態: 已實作(Core)


概述

修復「key_frame 正常、key_face bbox 正常、但 key_face 縮圖異常」之現象。

根因: bbox 部分越過 frame 邊界(如 trace 355b 案例)時,crop 未 clamp 到 frame 尺寸,ffmpeg 靜默 clamp/位移,導致縮圖內容錯位。由於縮圖端點優先回傳 key_face.jpg cache,異常內容被持久化顯示。

修復: 本端點重新選取該 trace 之 best-confidence face,將 bbox clamp 至影片尺寸後重新裁切,覆寫 key_face.jpg,並同步更新 .faces cache。


API 端點

POST /api/v1/file/{file_uuid}/trace/{trace_id}/regenerate-thumbnail

功能: 重新產生單一 trace 的 face thumbnail(覆寫 cache) Auth: Required Body: 可為空。

Response 200:

{
  "success": true,
  "file_uuid": "...",
  "trace_id": 355,
  "frame": 1835,
  "bbox": { "x": 65, "y": 301, "width": 70, "height": 59 }
}
- frame / bbox 為重新裁切使用的(clamp 後)frame 與 bbox。

Error Responses: | Status | 說明 | |--------|------| | 404 | Video not found(該 file_uuid 無影片)或 No face found for this trace(該 trace 無 face 資料) | | 400 | Video width/height unavailable — 影片未記錄尺寸,無法 clamp,拒絕重切 |


行為說明

  1. 讀取該 trace 最高 confidence 的 frame + bbox(不重跑 blur 優化,取既有 best face 復原同一區域)
  2. 將 bbox clamp 到影片 width/height 內(clamp_crop)
  3. ffmpeg 自影片以 decoded frame index 切出該 frame → crop face 區域
  4. 覆寫 {OUTPUT_DIR}/{file_uuid}/trace_{trace_id}/key_face.jpg
  5. 若 .faces/{file_uuid}/{trace_id}/{frame}.jpg 已存在則同步覆寫

不影響: Qdrant、trace_profiles DB、tkg_nodes、影片檔 — 僅重寫縮圖 cache。


Studio 整合步驟

1. apiCall (src/api/index.ts)

新增 case:

case 'regenerate_trace_thumbnail': {
  return { url: `/api/v1/file/${a.fileUuid}/trace/${a.traceId}/regenerate-thumbnail`, method: 'POST' }
}

2. Face detail modal 加「Re-gen」按鈕 (src/views/PeopleView.vue)

於 ms-face-detail-thumb 附近加入按鈕,呼叫上方 apiCall,in-flight 時 disabled。

3. 觸發後 refresh(重要)

Face detail 縮圖顯示的是 faceThumbsCache(key = ${file_uuid}-${trace_id})。loadTraceThumb 對已有 cache 的 key 會直接 return,單獨 bumpThumbCacheBust() 無法刷新 face detail 縮圖。正確順序:

await apiCall('regenerate_trace_thumbnail', { fileUuid, traceId })   // 1. 呼叫 regenerate
delete faceThumbsCache.value[`${fileUuid}-${traceId}`]                // 2. 清除該 key 的 blob cache
bumpThumbCacheBust()                                                  // 3. bump 版本(避 HTTP cache)
loadTraceThumb({ file_uuid: fileUuid, trace_id: traceId })            // 4. 重新載入縮圖

candidateThumbs 即 faceThumbsCache 的 alias(PeopleView.vue:722),delete 後無需額外處理。 若想一次清空全部縮圖可用 clearFaceThumbs()(較重,不建議單一 trace 場景)。


測試指示

# 使用已知越界案例(trace 355b 一類)驗證:
# 1) regenerate 前:GET thumbnail 顯示位移內容
# 2) 呼叫 regenerate → 回 success,含 clamp 後 bbox
# 3) 再次 GET thumbnail → 內容正確對齊 bbox
curl -X POST "http://localhost:3002/api/v1/file/<FILE_UUID>/trace/<TRACE_ID>/regenerate-thumbnail" \
  -H "X-API-Key: <KEY>"

參考

  • 根因 crop 修正:src/core/thumbnail/validator.rs::clamp_crop、src/core/processor/tkg.rs
  • 端點 handler:src/api/trace_agent_api.rs::regenerate_trace_thumbnail

版本歷史

版本 日期 變更
v1.0 2026-08-12 初版