""" MatchMe Studio - Ingest Module (Video Processing) """ import cv2 import os import logging from pathlib import Path from typing import List, Tuple import config from modules import storage logger = logging.getLogger(__name__) def process_uploaded_video(video_path: str) -> Tuple[List[str], str]: """ Process uploaded video: 1. Upload raw video to R2. 2. Extract 3 keyframes (10%, 50%, 90%). 3. Return local frame paths and R2 video URL. """ if not Path(video_path).exists(): raise FileNotFoundError(f"Video not found: {video_path}") logger.info(f"Processing video: {video_path}") # 1. Upload to R2 video_url = storage.upload_file(video_path) if not video_url: raise RuntimeError("Failed to upload video to R2") # 2. Extract Frames cap = cv2.VideoCapture(video_path) if not cap.isOpened(): raise IOError(f"Cannot open video: {video_path}") total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) frame_indices = [ int(total_frames * 0.1), int(total_frames * 0.5), int(total_frames * 0.9) ] frame_urls = [] for i, idx in enumerate(frame_indices): cap.set(cv2.CAP_PROP_POS_FRAMES, idx) ret, frame = cap.read() if ret: frame_name = f"frame_{Path(video_path).stem}_{i}.jpg" frame_path = config.TEMP_DIR / frame_name cv2.imwrite(str(frame_path), frame) # Upload frame to R2 immediately frame_url = storage.upload_file(str(frame_path)) if frame_url: frame_urls.append(frame_url) cap.release() logger.info(f"Extracted and uploaded {len(frame_urls)} frames") return frame_urls, video_url