新模块功能:蚕茧视频识别

This commit is contained in:
BBIT-Kai
2025-11-18 16:32:09 +08:00
parent 530cede0bd
commit 7a5e29be1c
10 changed files with 304 additions and 127 deletions
+4 -5
View File
@@ -15,7 +15,6 @@ from routers.RabbitMQ import rqRouter
from routers.Report import reportRouter
from routers.Service import serviceRouter
from routers.Vision import visionRouter
from service.Analyze import mq_pull_analysis_async
async def ai_lab():
@@ -47,7 +46,7 @@ async def ai_lab():
app.include_router(r, prefix="/llm", tags=["llm"])
app.include_router(visionRouter, prefix="/cv", tags=["cv"])
app.include_router(publicRouter, prefix="/api/public", tags=["api"])
config = Config(app=app, host="0.0.0.0", port=13011, log_level="info")
config = Config(app=app, host="0.0.0.0", port=13011, log_level="debug")
server = Server(config)
await server.serve()
@@ -59,7 +58,7 @@ async def main():
task_api = asyncio.create_task(ai_lab())
# MCP服务-ailab
endpoint_url_ai_lab = "wss://ai.ronsunny.cn:8090/aimcp/mcp_endpoint/mcp/?token=TsSP9lBq6Oa1WMkachHoS2TtNt4GKV/Gli24pk5Rjpk%3D"
# endpoint_url_ai_lab = "wss://ai.ronsunny.cn:8090/aimcp/mcp_endpoint/mcp/?token=TsSP9lBq6Oa1WMkachHoS2TtNt4GKV/Gli24pk5Rjpk%3D"
# endpoint_url_ai_lab = "ws://ce_bot_mcp:8004/mcp_endpoint/mcp/?token=TsSP9lBq6Oa1WMkachHoS2TtNt4GKV/Gli24pk5Rjpk%3D"
# task_mcp1 = asyncio.create_task(init_mcp_server(endpoint_url_ai_lab))
@@ -68,10 +67,10 @@ async def main():
task_mcp2 = asyncio.create_task(init_mcp_server(endpoint_url_ql))
# RabbitMQ服务
task_mq = asyncio.create_task(mq_pull_analysis_async())
# task_mq = asyncio.create_task(mq_pull_analysis_async())
# await asyncio.gather(task_api, task_mcp1, task_mcp2, task_mq)
await asyncio.gather(task_api, task_mcp2, task_mq)
await asyncio.gather(task_api, task_mcp2)
if __name__ == "__main__":
+2 -3
View File
@@ -22,11 +22,10 @@ def push_file(bucket_name, object_name, file_bytes, contents, content_type):
)
def get_upload_token(bucket_name, object_name, xpires=timedelta(hours=1)):
upload_url = minio_client.presigned_put_object(
def get_upload_token(user_id, bucket_name, object_name, xpires=timedelta(minutes=15)):
return minio_client.presigned_put_object(
bucket_name=bucket_name, object_name=object_name, expires=xpires
)
return {"upload_url": upload_url, "object_name": object_name}
def get_temp_url(bucket_name, object_name):
+94
View File
@@ -753,3 +753,97 @@ def get_sca_image_list(user_id, name, page=1, page_size=10):
)
return total, result
def get_sca_video_list(name, page=1, page_size=10):
"""
获取用户已分析视频列表,带分页
"""
offset = (page - 1) * page_size
with pg_pool.getConn() as conn:
with conn.cursor() as cursor:
# 1️⃣ 查询总条数
cursor.execute(
"""
SELECT COUNT(*)
FROM sca_videos
WHERE (%s = '' OR name LIKE '%%' || %s || '%%')
""",
(name, name),
)
total = cursor.fetchone()[0]
# 2️⃣ 查询当前页数据
cursor.execute(
"""
SELECT id, name, raw_object_name, ai_object_name, duration, size, video_codec, audio_codec,
overall_bit_rate, resolution, sc_analysis_time, sc_analysis_total_count, sc_analysis_max_count,
sc_analysis_primary_type, sc_analysis_secondary_type, other_info, created_at
FROM sca_videos
WHERE (%s = '' OR name LIKE '%%' || %s || '%%')
ORDER BY created_at DESC
LIMIT %s OFFSET %s
""",
(name, name, page_size, offset),
)
rows = cursor.fetchall()
result = []
for row in rows:
result.append(
{
"id": row[0],
"name": row[1],
"raw_video_url": get_temp_url("video-sca", "raw/" + row[2]),
"ai_video_url": get_temp_url("video-sca", "ai/" + row[3]),
"duration": MyUtils.safe_round(row[4], 2),
"size_kb": MyUtils.safe_round(row[5] / 1024, 2),
"video_codec": row[6],
"audio_codec": row[7],
"overall_bit_rate": row[8],
"resolution": row[9],
"sc_analysis_time": MyUtils.safe_round(row[10], 2),
"sc_analysis_total_count": row[11],
"sc_analysis_max_count": row[12],
"sc_analysis_primary_type": row[13],
"sc_analysis_secondary_type": row[14],
"other_info": json.loads(row[15]),
"created_at": MyUtils.format_datetime(row[16]),
}
)
return total, result
def get_sca_video_details(v_id):
"""
获取指定视频的分析明细列表
"""
with pg_pool.getConn() as conn:
with conn.cursor() as cursor:
cursor.execute(
"""
SELECT id, v_id, time_stamp, other_info
FROM sca_video_details
WHERE v_id = %s
ORDER BY time_stamp ASC
""",
(v_id,),
)
rows = cursor.fetchall()
result = []
for row in rows:
# other_info 从 JSON 字符串解析回字典
result.append(
{
"id": row[0],
"v_id": row[1],
"time_stamp": row[2],
"other_info": row[3],
}
)
return result
+36 -3
View File
@@ -153,8 +153,41 @@ def getSilkwormCocoonAnalysisTasks(
)
@visionRouter.post("/getIVASCUploadToken")
def getIVASCUploadToken():
# ————————————————————————————————蚕茧视频识别任务————————————————————————————————————————————————
@visionRouter.get("/getIVASCUploadToken")
def getIVASCUploadToken(
user_id: UUID = Depends(get_user_id_from_token),
):
# 生成唯一文件名,避免覆盖
object_name = f"raw/{uuid.uuid4()}"
return get_upload_token("video-sca", object_name)
return BaseResponse(data=get_upload_token(user_id, "video-sca", object_name))
@visionRouter.get("/getScVideoList")
def getScVideoList(
user_id: UUID = Depends(get_user_id_from_token),
name: str = "",
page: int = Query(1, ge=1),
page_size: int = Query(10, ge=1, le=100),
):
if not user_id:
return {"error": "userId is required"}
total, items = pg.get_sca_video_list(name, page=page, page_size=page_size)
return BaseResponse(
data={
"total": total,
"items": items,
}
)
@visionRouter.get("/getAnalyticsDetailBySCVideoId")
def getAnalyticsDetailBySCVideoId(
user_id: UUID = Depends(get_user_id_from_token),
vId: str = "",
):
if not user_id:
return {"error": "userId is required"}
return BaseResponse(data=pg.get_sca_video_details(vId))
-12
View File
@@ -132,18 +132,6 @@ def process_silkworm_cocoon_image(
# YOLO检测
img_bytes_out, results_json = YOLOSingleton.detect(img_bytes)
# results_json = {
# "total_objects": "",
# "max_confidence": "",
# "min_confidence": "",
# "avg_confidence": "",
# "class_counts": "",
# "speed_ms": {
# "preprocess": "",
# "inference": "",
# "postprocess": "",
# },
# }
speed_json = results_json.get("speed_ms")
file_bytes_out = BytesIO(img_bytes_out)