api.py 3.92 KB
import logging
from aabd.base.enhance_dict import value_or_default

logger = logging.getLogger(__name__)

from utils.football_replay_video_event_by_llm import FootballReplayVideoEvent
from utils.football_replay_match_live import FootballReplayMatchLive

class FootballReplayMatch:
    def __init__(self, settings):
        self.settings = settings
        self.match_by_time_threshold = value_or_default(settings.match_by_time_threshold, 30) * 1000
        
        llm_base_url = value_or_default(settings.llm.base_url, None)
        model_name = value_or_default(settings.llm.model_name, None)
        temperature = value_or_default(settings.llm.temperature, 0.7)
        self.cache_dir = value_or_default(settings.common.cache_dir, None)
        save_frames_enable = value_or_default(settings.save_frames_enable, False)
        
        self.videoEventRecognition = FootballReplayVideoEvent(llm_base_url, model_name, temperature, 'no_key', self.cache_dir, save_frames_enable)
        self.videoMatchLive = FootballReplayMatchLive(llm_base_url, model_name, temperature, 'no_key', self.cache_dir)
        
    def match_by_time(self, replay, events):
        start_utc = replay.get('start_utc')

        events = [(start_utc - e.get('event_utc'), e) for e in events]
        events.sort(key=lambda x: abs(x[0]))
        time_diff, event = events[0]
        if time_diff < self.match_by_time_threshold:
            return event
        else:
            return None

    def det_goal_replay(self, replay):
        return self.videoEventRecognition.video_event(replay, cache_dir=self.cache_dir)
            

    def match_by_llm(self, replay, events):
        return self.videoMatchLive.match_batch(replay, events, max_parallel=2, cache_dir=self.cache_dir)

    def replay_match_event(self, data):
        """

        :param data:
        {
          id:xx,
          match_id: 比赛id,
          replay:{
            id:,
            url:,
            start_utc:,
            end_utc:,
            }
          events:[{
            id:xx,
            type:xx,
            url:xx,
            event_utc,
          }]
        }
        :return:
        """
        task_id = data.get("id")
        match_id = data.get("match_id")
        replay_id = replay_info.get('id')
        matched_event_id = None
    
        # 该时间段附近是否有进球事件
        replay_info = data['replay']
        live_events = data['events']
        goal_live_events = [e for e in live_events if str(e.get('type', '')) == '1']

        matched_event = self.match_by_time(replay_info, goal_live_events)

        if matched_event is None:
            replay_det_info = self.det_goal_replay(replay_info)
            replay_event_name = replay_det_info.get('event_name', '')
            if replay_event_name == '进球':
                matched_event = self.match_by_llm(replay_info, goal_live_events)
                if matched_event is None:
                    logger.info(f"{task_id}_LLM认为视频{replay_info['url']}_{replay_info['start_utc']}_{replay_info['end_utc']} 是进球但是未能找到匹配的事件")
                else:
                    matched_event_id = matched_event.get('video_id')
                    logger.info(f"{task_id}_LLM认为视频{replay_info['url']}_{replay_info['start_utc']}_{replay_info['end_utc']} 对应的进球的事件视频是{matched_event_id}")
            else:
                logger.info(f"{task_id}_LLM判断{replay_info['url']}_{replay_info['start_utc']}_{replay_info['end_utc']} 不是进球,无需匹配")
        else:
            matched_event_id = matched_event.get('id')
            logger.info(f"{task_id}_通过时间找到匹配认为视频{replay_info['url']}_{replay_info['start_utc']}_{replay_info['end_utc']} 对应的进球的事件视频是{matched_event_id}")
        return {
                "id": task_id,
                "match_id": match_id,
                "replay_id": replay_id,
                "event_id": matched_event_id
            }