feat: 入库时存储人脸bbox和视频时间戳到chunk metadata

- upload_file: 图片/视频人脸检测保存face_bboxes
- upload_file: 视频帧chunk INSERT加metadata列(start_time+bboxes)
- search_result: 检索结果显示bbox坐标和视频时间戳
- init.py: chunk INSERT加metadata列
- media_cards: 标签同时读media_tags表和metadata.tags
- search_result: 媒体URL用entire_url转完整路径
This commit is contained in:
ymq 2026-08-12 11:10:50 +08:00
parent 631b2da7a4
commit 67c13f626d

View File

@ -106,7 +106,10 @@ async def ingest_doc(doc_id, kb_id, file_name, ext_l, real_path):
fd = json.loads(resp)
results = fd.get("results", [])
if results and isinstance(results[0], dict):
face_count = len(results[0].get("faces", results[0].get("detections", [])))
faces = results[0].get("faces", results[0].get("detections", []))
face_count = len(faces)
if faces and isinstance(faces[0], dict):
meta_parts['face_bboxes'] = [f.get("bbox", {}) for f in faces[:10]]
meta_parts['face'] = face_count
except: pass
@ -133,13 +136,16 @@ async def ingest_doc(doc_id, kb_id, file_name, ext_l, real_path):
with open(tmp_img, 'rb') as fi:
frame_data = fi.read()
img_b64 = base64.b64encode(frame_data).decode()
frame_bboxes = []
try:
client = StreamHttpClient()
resp = await client.request('POST', 'https://media.opencomputing.net:10443/face/api/detect', json={"images": [img_b64]})
fd = json.loads(resp)
results = fd.get("results", [])
if results and isinstance(results[0], dict):
face_count = len(results[0].get("faces", results[0].get("detections", [])))
faces = results[0].get("faces", results[0].get("detections", []))
face_count = len(faces)
frame_bboxes = [f.get("bbox", {}) for f in faces[:10]] if faces else []
except: pass
# --- CLIP image embedding for video frame ---
try:
@ -158,12 +164,16 @@ async def ingest_doc(doc_id, kb_id, file_name, ext_l, real_path):
{"id": doc_id + "_c0", "vector": img_embeddings[0], "text": file_name}
]}
await client3.request('POST', 'https://vectordb.opencomputing.net:10443/v1/upsert', json=vdb_data)
chunk_meta = {"start_time": 0}
if frame_bboxes:
chunk_meta["bboxes"] = frame_bboxes
async with db.sqlorContext('rag') as sor:
await sor.sqlExe(
"INSERT INTO document_chunks (id, doc_id, kb_id, chunk_index, content, vector_id, created_at) "
"VALUES (${id}$, ${doc_id}$, ${kb_id}$, 0, ${content}$, ${vid}$, NOW())",
"INSERT INTO document_chunks (id, doc_id, kb_id, chunk_index, content, vector_id, metadata, created_at) "
"VALUES (${id}$, ${doc_id}$, ${kb_id}$, 0, ${content}$, ${vid}$, ${meta}$, NOW())",
{"id": doc_id + "_c0", "doc_id": doc_id, "kb_id": kb_id,
"content": file_name, "vid": doc_id + "_c0"})
"content": file_name, "vid": doc_id + "_c0",
"meta": json.dumps(chunk_meta, ensure_ascii=False)})
except:
pass
os.remove(tmp_img)