from firebase_admin import firestore import os from ..core.config import settings from ..core.firebase import db from huggingface_hub import HfApi, create_repo import tempfile from .video_processing.hf_upload import HFUploader from .video_processing.compression import compress_video from .video_processing.scene_detection import SceneDetector from .video_processing.scene_classifier import SceneClassifier from .video_processing.clip_generator import ClipGenerator from .video_processing.scrape_hf import extract_video_urls import time async def process_video(video_uuid: str, content: bytes, user_id: str, sport_id: str): temp_files = [] try: video_ref = db.collection('videos').document(video_uuid) video_data = video_ref.get().to_dict() hf_uploader = HFUploader() sport_id = video_data['sport_id'] # Ensure folder structure exists hf_uploader.ensure_folder_structure(sport_id) # Create temp files temp_raw_file = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) temp_compressed_file = tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) temp_files.extend([temp_raw_file.name, temp_compressed_file.name]) # Write raw video and close file temp_raw_file.write(content) temp_raw_file.close() # Compress video compress_video(temp_raw_file.name, temp_compressed_file.name) temp_compressed_file.close() # Detect scenes scene_detector = SceneDetector() scene_classifier = SceneClassifier() scenes_data = scene_detector.detect_scenes(temp_compressed_file.name) # Classify each scene for scene in scenes_data["scenes"]: classification = scene_classifier.classify_scene( temp_compressed_file.name, scene ) scene["recognized_sport"] = classification["recognized_sport"] scene["confidence"] = classification["confidence"] # Generate clips clip_generator = ClipGenerator() generated_clips = clip_generator.generate_clips( temp_compressed_file.name, scenes_data["scenes"], sport_id ) # Create and upload clips final_clips_data = [] user_ref = db.collection("users").document(user_id) user_data = user_ref.get().to_dict() or {"clips": []} if "clips" not in user_data: user_data["clips"] = [] # Upload both versions first raw_path = f"{sport_id}/raw/{video_uuid}.mp4" compressed_path = f"{sport_id}/compressed/{video_uuid}.mp4" hf_uploader.upload_video(temp_raw_file.name, raw_path) hf_uploader.upload_video(temp_compressed_file.name, compressed_path) # Attendre que HF indexe les fichiers time.sleep(3) # Construire l'URL de base pour le scraping base_viewer_url = f"https://huggingface.co/datasets/{hf_uploader.repo_id}/viewer/default/files" # Récupérer toutes les URLs max_retries = 3 raw_url = None compressed_url = None for attempt in range(max_retries): try: urls = extract_video_urls(base_viewer_url) # Chercher les URLs correspondantes raw_url = next((url for url in urls if raw_path in url), None) compressed_url = next((url for url in urls if compressed_path in url), None) if raw_url and compressed_url: print(f"[SUCCESS] URLs trouvées à la tentative {attempt + 1}") break print(f"[RETRY] Tentative {attempt + 1}/{max_retries}") time.sleep(2) except Exception as e: print(f"[ERROR] Tentative {attempt + 1} échouée: {str(e)}") if attempt == max_retries - 1: raise e time.sleep(2) # Process clips for clip_data in generated_clips: clip_number = clip_data["clip_number"] clip_file_path = clip_data["file_path"] temp_files.append(clip_file_path) clip_path = f"{sport_id}/clips/{video_uuid}_clip_{clip_number}.mp4" hf_uploader.upload_video(clip_file_path, clip_path) # Attendre et scraper l'URL du clip time.sleep(2) clip_url = None for attempt in range(max_retries): try: urls = extract_video_urls(base_viewer_url) clip_url = next((url for url in urls if clip_path in url), None) if clip_url: break time.sleep(2) except Exception: if attempt == max_retries - 1: raise time.sleep(2) if clip_url: final_clips_data.append({ "clip_id": f"{video_uuid}_clip_{clip_number}", "video_uuid": video_uuid, "url": clip_url, "duration": clip_data["duration"], "confidence": clip_data["confidence"], "segments": clip_data["segments"] }) clip_ref = db.collection("clips").document(f"{video_uuid}_clip_{clip_number}") clip_ref.set({ "clip_id": f"{video_uuid}_clip_{clip_number}", "sport_id": sport_id, "url": clip_url, "duration": clip_data["duration"] }) # Update user data user_ref.set(user_data) # Update video data with scraped URLs update_data = { "scenes": scenes_data, "clips": final_clips_data, "clips_count": len(final_clips_data), "status": "ready", "last_updated": firestore.SERVER_TIMESTAMP } if raw_url: update_data["raw_video_url"] = raw_url if compressed_url: update_data["compressed_video_url"] = compressed_url video_ref.update(update_data) except Exception as e: print(f"Erreur lors du traitement de la vidéo {video_uuid}: {str(e)}") video_ref.update({"status": "error", "error": str(e)}) finally: # Clean up temp files for temp_file in temp_files: try: if os.path.exists(temp_file): os.unlink(temp_file) except Exception as e: print(f"[WARNING] Erreur lors de la suppression du fichier temporaire {temp_file}: {str(e)}")