from pydantic import BaseModel, Field from typing import Optional, List from enum import Enum class HighlightStyle(str, Enum): DYNAMIC = "dynamic" BROADCAST = "broadcast" GOALS_ONLY = "goals_only" TACTICAL = "tactical" class OutputQuality(str, Enum): Q480 = "480p" Q720 = "720p" Q1080 = "1080p" QUALITY_MAP = {"480p": (854, 480), "720p": (1280, 720), "1080p": (1920, 1080)} class ProcessRequest(BaseModel): video_url: str = Field(..., description="URL (YouTube/direct/local path) of the match video") highlight_duration: int = Field(10, ge=3, le=20, description="Desired highlight duration in minutes") style: HighlightStyle = HighlightStyle.DYNAMIC output_quality: OutputQuality = OutputQuality.Q720 team_home: Optional[str] = None team_away: Optional[str] = None match_date: Optional[str] = None fast_mode: bool = Field(False, description="Audio-only analysis (no GPU needed, ~80% quality)") frame_sample_rate: int = Field(5, ge=1, le=30, description="Analyze every Nth frame") pre_buffer: float = Field(3.0, description="Seconds before event") post_buffer: float = Field(5.0, description="Seconds after event") fade_duration: float = Field(0.5, description="Fade transition duration") class SoccerEvent(BaseModel): timestamp: float event_type: str confidence: float = 0.0 description: str = "" class ScoredEvent(BaseModel): event: SoccerEvent score: float chunk_index: int = 0 class ClipSegment(BaseModel): start: float end: float score: float events: List[ScoredEvent] = [] class JobStatus(BaseModel): job_id: str status: str = "queued" progress: float = 0.0 stage: str = "" message: str = "" result: Optional[dict] = None class ChunkAnalysis(BaseModel): chunk_index: int start_time: float end_time: float events: List[ScoredEvent] = [] audio_excitement: List[tuple] = []