From 67c13f626d12b9c01080a28029f260e1a8e633c5 Mon Sep 17 00:00:00 2001 From: ymq Date: Wed, 12 Aug 2026 11:10:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=A5=E5=BA=93=E6=97=B6=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E4=BA=BA=E8=84=B8bbox=E5=92=8C=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=88=B3=E5=88=B0chunk=20metadata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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转完整路径 --- wwwroot/knowledge_bases_list/upload_file.dspy | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/wwwroot/knowledge_bases_list/upload_file.dspy b/wwwroot/knowledge_bases_list/upload_file.dspy index 91c1add..5bebc4a 100644 --- a/wwwroot/knowledge_bases_list/upload_file.dspy +++ b/wwwroot/knowledge_bases_list/upload_file.dspy @@ -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)