lizhengwei

jira:NYJ-1656 desc: config api_key

@@ -24,6 +24,7 @@ llm: @@ -24,6 +24,7 @@ llm:
24 base_url: http://192.168.1.59:11434/v1 24 base_url: http://192.168.1.59:11434/v1
25 model_name: Qwen3.6-35B-A3B-UD-Q8_K_XL.gguf 25 model_name: Qwen3.6-35B-A3B-UD-Q8_K_XL.gguf
26 temperature: 0.7 26 temperature: 0.7
  27 + api_key: "no_key"
27 28
28 common: 29 common:
29 cache_dir: ./videos_cache 30 cache_dir: ./videos_cache
@@ -22,12 +22,16 @@ class FootballReplayMatch: @@ -22,12 +22,16 @@ class FootballReplayMatch:
22 llm_base_url = value_or_default(settings.llm.base_url, None) 22 llm_base_url = value_or_default(settings.llm.base_url, None)
23 model_name = value_or_default(settings.llm.model_name, None) 23 model_name = value_or_default(settings.llm.model_name, None)
24 temperature = value_or_default(settings.llm.temperature, 0.7) 24 temperature = value_or_default(settings.llm.temperature, 0.7)
  25 + api_key = value_or_default(settings.llm.api_key, 'no_key')
  26 +
25 self.cache_dir = value_or_default(settings.common.cache_dir, None) 27 self.cache_dir = value_or_default(settings.common.cache_dir, None)
26 self.task_log_dir = value_or_default(settings.common.task_log_dir, None) 28 self.task_log_dir = value_or_default(settings.common.task_log_dir, None)
27 save_frames_enable = value_or_default(settings.save_frames_enable, False) 29 save_frames_enable = value_or_default(settings.save_frames_enable, False)
28 30
29 - self.videoEventRecognition = FootballReplayVideoEvent(llm_base_url, model_name, temperature, 'no_key', self.cache_dir, save_frames_enable)  
30 - self.videoMatchLive = FootballReplayMatchLive(llm_base_url, model_name, temperature, 'no_key', self.cache_dir, save_frames_enable) 31 +
  32 +
  33 + self.videoEventRecognition = FootballReplayVideoEvent(llm_base_url, model_name, temperature, api_key, self.cache_dir, save_frames_enable)
  34 + self.videoMatchLive = FootballReplayMatchLive(llm_base_url, model_name, temperature, api_key, self.cache_dir, save_frames_enable)
31 35
32 def match_by_time(self, replay, events): 36 def match_by_time(self, replay, events):
33 37
@@ -103,7 +107,10 @@ class FootballReplayMatch: @@ -103,7 +107,10 @@ class FootballReplayMatch:
103 # print(f"判断是否是进球耗时: {end_time - start_time} 秒") 107 # print(f"判断是否是进球耗时: {end_time - start_time} 秒")
104 replay_event_name = replay_det_info.get('event_name', '') 108 replay_event_name = replay_det_info.get('event_name', '')
105 if replay_event_name == '进球': 109 if replay_event_name == '进球':
  110 + start_time1 = time.time()
106 matched_event = self.match_by_llm(replay_info, goal_live_events, task_id) 111 matched_event = self.match_by_llm(replay_info, goal_live_events, task_id)
  112 + end_time1 = time.time()
  113 + logger.info(f"LLM_match_all_cost_time:{end_time1-start_time1:.2f}seconds")
107 if matched_event is None: 114 if matched_event is None:
108 logger.info(f"{task_id}_LLM_think_{replay_info['url']}_{replay_start_utc}_{replay_end_utc}_is_goal_but_no_matched_event") 115 logger.info(f"{task_id}_LLM_think_{replay_info['url']}_{replay_start_utc}_{replay_end_utc}_is_goal_but_no_matched_event")
109 # print(f"{task_id}_LLM认为视频{replay_info['url']}_{replay_start_utc}_{replay_end_utc} 是进球但是未能找到匹配的事件") 116 # print(f"{task_id}_LLM认为视频{replay_info['url']}_{replay_start_utc}_{replay_end_utc} 是进球但是未能找到匹配的事件")
@@ -45,8 +45,8 @@ def _fake_settings(match_by_time_threshold: int = 30, cache_dir_tag: str = "test @@ -45,8 +45,8 @@ def _fake_settings(match_by_time_threshold: int = 30, cache_dir_tag: str = "test
45 temperature=0.7, 45 temperature=0.7,
46 api_key='no_key' 46 api_key='no_key'
47 ), 47 ),
48 - common=SimpleNamespace(cache_dir=f"/root/lzw/tmp_0528_replay_cache_{cache_dir_tag}/videos_cache",  
49 - task_log_dir=f"/root/lzw/tmp_0528_replay_cache_{cache_dir_tag}/tasks_log" 48 + common=SimpleNamespace(cache_dir=f"/root/lzw/tmp_0601_replay_cache_{cache_dir_tag}/videos_cache",
  49 + task_log_dir=f"/root/lzw/tmp_0601_replay_cache_{cache_dir_tag}/tasks_log"
50 ), 50 ),
51 save_frames_enable=True, 51 save_frames_enable=True,
52 ) 52 )
@@ -112,6 +112,8 @@ def test_match_by_time_success(): @@ -112,6 +112,8 @@ def test_match_by_time_success():
112 replays_and_events_pair = get_replays_and_events_pair() 112 replays_and_events_pair = get_replays_and_events_pair()
113 113
114 for replays_mp4_dir, events_mp4_dir in replays_and_events_pair: 114 for replays_mp4_dir, events_mp4_dir in replays_and_events_pair:
  115 + # replays_mp4_dir = "/root/lzw/finished/69e5102bfd87d43d09bba90d-auto-10154993/replays/videos"
  116 + # events_mp4_dir = r"/root/lzw/finished/69e5102bfd87d43d09bba90d-auto-10154993/live/videos"
115 print(100*"=") 117 print(100*"=")
116 print(f"replays_mp4_dir: {replays_mp4_dir}, events_mp4_dir: {events_mp4_dir}") 118 print(f"replays_mp4_dir: {replays_mp4_dir}, events_mp4_dir: {events_mp4_dir}")
117 119
@@ -121,13 +123,15 @@ def test_match_by_time_success(): @@ -121,13 +123,15 @@ def test_match_by_time_success():
121 123
122 frm = FootballReplayMatch(settings) 124 frm = FootballReplayMatch(settings)
123 125
124 - # replays_mp4_dir = "/root/lzw/finished/69dd5845dd0412067b8d5587-auto-1776074760653/replays/videos" 126 +
125 relays_mp4_names = get_video_files_pathlib(replays_mp4_dir) 127 relays_mp4_names = get_video_files_pathlib(replays_mp4_dir)
126 128
127 129
128 - # events_mp4_dir = r"/root/lzw/finished/69dd5845dd0412067b8d5587-auto-1776074760653/live/videos" 130 +
129 event_list = get_event_list(events_mp4_dir) 131 event_list = get_event_list(events_mp4_dir)
130 132
  133 +
  134 +
131 all_time = 0.0 135 all_time = 0.0
132 max_time = 0.0 136 max_time = 0.0
133 for i, replay_name in enumerate(relays_mp4_names): 137 for i, replay_name in enumerate(relays_mp4_names):
@@ -4,15 +4,22 @@ import subprocess @@ -4,15 +4,22 @@ import subprocess
4 import sys 4 import sys
5 from pathlib import Path 5 from pathlib import Path
6 from typing import Optional 6 from typing import Optional
  7 +import time
7 import os 8 import os
8 from urllib.parse import urlparse 9 from urllib.parse import urlparse
9 import cv2 10 import cv2
10 from aabd.stream_chain import video2frames 11 from aabd.stream_chain import video2frames
11 import json 12 import json
12 -import logging 13 +
13 import hashlib 14 import hashlib
14 15
15 -logger = logging.getLogger(__name__) 16 +try:
  17 + from .my_logger import get_logger
  18 +except:
  19 +
  20 + from my_logger import get_logger
  21 +
  22 +logger = get_logger()
16 23
17 _IS_ABSOLUTE_UTC_THRESHOLD = 1_000_000_000 24 _IS_ABSOLUTE_UTC_THRESHOLD = 1_000_000_000
18 25
@@ -81,7 +88,10 @@ class Video2Frame: @@ -81,7 +88,10 @@ class Video2Frame:
81 if not download_video_path.exists(): 88 if not download_video_path.exists():
82 logger.info(f"download_video: {url} -> {download_video_path}") 89 logger.info(f"download_video: {url} -> {download_video_path}")
83 video_root_path.mkdir(parents=True, exist_ok=True) 90 video_root_path.mkdir(parents=True, exist_ok=True)
  91 + start_time = time.time()
84 download_to_mp4(url, str(download_video_path), duration=None) 92 download_to_mp4(url, str(download_video_path), duration=None)
  93 + end_time = time.time()
  94 + logger.info(f"download_video_cost_time:{end_time - start_time:.2f}seconds")
85 logger.info(f"video_path: {download_video_path}") 95 logger.info(f"video_path: {download_video_path}")
86 96
87 97
@@ -95,6 +105,7 @@ class Video2Frame: @@ -95,6 +105,7 @@ class Video2Frame:
95 with cache_name.open('r', encoding='utf-8') as f: 105 with cache_name.open('r', encoding='utf-8') as f:
96 return json.load(f) 106 return json.load(f)
97 else: 107 else:
  108 + start_time = time.time()
98 cache_dir.mkdir(parents=True, exist_ok=True) 109 cache_dir.mkdir(parents=True, exist_ok=True)
99 data = { 110 data = {
100 'fps': fps, 111 'fps': fps,
@@ -104,7 +115,7 @@ class Video2Frame: @@ -104,7 +115,7 @@ class Video2Frame:
104 cache_frames.mkdir(parents=True, exist_ok=True) 115 cache_frames.mkdir(parents=True, exist_ok=True)
105 for f in self.iter_mp4(str(download_video_path), start, end, fps): 116 for f in self.iter_mp4(str(download_video_path), start, end, fps):
106 frame = f['frame'] 117 frame = f['frame']
107 - time = f['src_frame_time'] 118 + duration = f['src_frame_time']
108 fps = f['fps'] 119 fps = f['fps']
109 data['fps'] = fps 120 data['fps'] = fps
110 if roi is not None: 121 if roi is not None:
@@ -116,10 +127,10 @@ class Video2Frame: @@ -116,10 +127,10 @@ class Video2Frame:
116 _, buffer = cv2.imencode('.jpg', frame) 127 _, buffer = cv2.imencode('.jpg', frame)
117 b64_str = base64.b64encode(buffer).decode('utf-8') 128 b64_str = base64.b64encode(buffer).decode('utf-8')
118 129
119 - data['frames'].append({'time': time, 'image': b64_str}) 130 + data['frames'].append({'time': duration, 'image': b64_str})
120 131
121 if self.save_frames_enable: 132 if self.save_frames_enable:
122 - frame_path = cache_frames / f"{time:015d}.jpg" 133 + frame_path = cache_frames / f"{duration:015d}.jpg"
123 cv2.imwrite(frame_path, frame) 134 cv2.imwrite(frame_path, frame)
124 135
125 cache_name.parent.mkdir(parents=True, exist_ok=True) 136 cache_name.parent.mkdir(parents=True, exist_ok=True)
@@ -127,6 +138,8 @@ class Video2Frame: @@ -127,6 +138,8 @@ class Video2Frame:
127 with cache_name.open('w', encoding='utf-8') as f: 138 with cache_name.open('w', encoding='utf-8') as f:
128 json.dump(data, f, indent=4) 139 json.dump(data, f, indent=4)
129 logger.info(f"save_cache: {cache_name}") 140 logger.info(f"save_cache: {cache_name}")
  141 + end_time = time.time()
  142 + logger.info(f"to_frames_cost_time:{end_time - start_time:.2f}seconds")
130 return data 143 return data
131 144
132 def to_llm_contents(self, url, cache=None, fps=None, start=None, end=None, roi=None, max_px_area=None, 145 def to_llm_contents(self, url, cache=None, fps=None, start=None, end=None, roi=None, max_px_area=None,
@@ -2,6 +2,7 @@ import os @@ -2,6 +2,7 @@ import os
2 import time 2 import time
3 import logging 3 import logging
4 from functools import lru_cache 4 from functools import lru_cache
  5 +from logging.handlers import TimedRotatingFileHandler # 引入按时间切割的处理器
5 6
6 @lru_cache(maxsize=1) 7 @lru_cache(maxsize=1)
7 def get_logger(): 8 def get_logger():
@@ -10,7 +11,6 @@ def get_logger(): @@ -10,7 +11,6 @@ def get_logger():
10 logger.setLevel(logging.INFO) 11 logger.setLevel(logging.INFO)
11 12
12 # 1. 配置日志输出格式 13 # 1. 配置日志输出格式
13 - # 修改点:增加了 %(filename)s:%(lineno)d 来显示文件名和行号  
14 formatter = logging.Formatter( 14 formatter = logging.Formatter(
15 '%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s', 15 '%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',
16 datefmt='%Y-%m-%d %H:%M:%S' 16 datefmt='%Y-%m-%d %H:%M:%S'
@@ -21,13 +21,27 @@ def get_logger(): @@ -21,13 +21,27 @@ def get_logger():
21 console_handler.setFormatter(formatter) 21 console_handler.setFormatter(formatter)
22 logger.addHandler(console_handler) 22 logger.addHandler(console_handler)
23 23
24 - # 3. 创建文件处理器 24 + # 3. 创建按天自动切割的文件处理器
25 log_dir = "logs" 25 log_dir = "logs"
26 if not os.path.exists(log_dir): 26 if not os.path.exists(log_dir):
27 os.makedirs(log_dir) 27 os.makedirs(log_dir)
28 28
29 - log_file = os.path.join(log_dir, f"run_{time.strftime('%Y%m%d')}.log")  
30 - file_handler = logging.FileHandler(log_file, encoding='utf-8') 29 + # 基础日志文件名
  30 + base_log_file = os.path.join(log_dir, "run.log")
  31 +
  32 + # TimedRotatingFileHandler 参数说明:
  33 + # when='midnight' : 每天凌晨自动切割
  34 + # interval=1 : 每1个单位(即每天)切割一次
  35 + # backupCount=30 : 保留最近30天的日志,超出的会自动删除(防止硬盘被写满)
  36 + # encoding='utf-8': 防止中文乱码
  37 + file_handler = TimedRotatingFileHandler(
  38 + base_log_file,
  39 + when='midnight',
  40 + interval=1,
  41 + backupCount=30,
  42 + encoding='utf-8'
  43 + )
  44 + file_handler.suffix = "%Y%m%d" # 切割后的旧日志会自动带上日期后缀,如 run.log.20260601
31 file_handler.setFormatter(formatter) 45 file_handler.setFormatter(formatter)
32 logger.addHandler(file_handler) 46 logger.addHandler(file_handler)
33 47