from fastapi import APIRouter, BackgroundTasks, Depends from app.clients.llm.base import LLMClient from app.clients.storage.base import StorageClient from app.core.config import get_config from app.core.dependencies import get_llm_client, get_storage_client from app.core.exceptions import VideoTooLargeError from app.models.video_models import ( ExtractFramesRequest, VideoAcceptedResponse, VideoToTextRequest, ) from app.services import video_service router = APIRouter(tags=["Video"]) async def _check_video_size(storage: StorageClient, bucket: str, file_path: str, max_mb: int) -> None: size_bytes = await storage.get_object_size(bucket, file_path) if size_bytes > max_mb * 1024 * 1024: raise VideoTooLargeError( f"视频文件大小超出限制(最大 {max_mb}MB,当前 {size_bytes // 1024 // 1024}MB)" ) @router.post("/video/extract-frames", response_model=VideoAcceptedResponse, status_code=202) async def extract_frames( req: ExtractFramesRequest, background_tasks: BackgroundTasks, storage: StorageClient = Depends(get_storage_client), ) -> VideoAcceptedResponse: cfg = get_config() bucket = cfg["storage"]["buckets"]["source_data"] max_mb = cfg["video"]["max_file_size_mb"] callback_url = cfg.get("backend", {}).get("callback_url", "") await _check_video_size(storage, bucket, req.file_path, max_mb) background_tasks.add_task( video_service.extract_frames_task, req, storage, callback_url, ) return VideoAcceptedResponse(message="任务已接受,后台处理中", job_id=req.job_id) @router.post("/video/to-text", response_model=VideoAcceptedResponse, status_code=202) async def video_to_text( req: VideoToTextRequest, background_tasks: BackgroundTasks, storage: StorageClient = Depends(get_storage_client), llm: LLMClient = Depends(get_llm_client), ) -> VideoAcceptedResponse: cfg = get_config() bucket = cfg["storage"]["buckets"]["source_data"] max_mb = cfg["video"]["max_file_size_mb"] callback_url = cfg.get("backend", {}).get("callback_url", "") await _check_video_size(storage, bucket, req.file_path, max_mb) background_tasks.add_task( video_service.video_to_text_task, req, llm, storage, callback_url, ) return VideoAcceptedResponse(message="任务已接受,后台处理中", job_id=req.job_id)