#!/usr/bin/env python3 """ MULTI-GAME DETECTOR Detecta múltiples partidas/juegos en el stream y extrae highlights de cada uno. """ import json import numpy as np from pathlib import Path def detect_game_boundaries(transcription_file): """ Detecta dónde empieza y termina cada juego/partida. Señales de cambio de juego: - Cambios grandes en el timeline (>5 min sin actividad) - Palabras como "victoria", "derrota", "gg", "fin" - Selección de campeones seguida de gameplay """ print("=" * 60) print("MULTI-GAME DETECTOR") print("=" * 60) with open(transcription_file, "r") as f: trans = json.load(f) segments = trans["segments"] # Encontrar cambios de juego games = [] current_game_start = 0 last_activity = 0 for i, seg in enumerate(segments): text = seg["text"].lower() current_time = seg["start"] # Detectar fin de juego if any( word in text for word in [ "victoria", "derrota", "gg wp", "buena partida", "fin del juego", "game over", "terminamos", ] ): if current_time - current_game_start > 600: # Mínimo 10 min de juego games.append( { "start": current_game_start, "end": current_time, "finish_type": "victoria/derrota", "text": text[:50], } ) current_game_start = current_time last_activity = current_time # Detectar gaps grandes (cambio de juego) if i > 0: gap = current_time - segments[i - 1]["end"] if gap > 300: # Gap de 5+ minutos if current_time - current_game_start > 600: games.append( { "start": current_game_start, "end": segments[i - 1]["end"], "finish_type": "gap", "text": f"Gap de {gap:.0f}s", } ) current_game_start = current_time last_activity = current_time # Agregar último juego if segments[-1]["end"] - current_game_start > 300: games.append( { "start": current_game_start, "end": segments[-1]["end"], "finish_type": "final", "text": "Último juego", } ) print(f"\nJuegos detectados: {len(games)}") for i, game in enumerate(games, 1): mins_start = int(game["start"]) // 60 secs_start = int(game["start"]) % 60 mins_end = int(game["end"]) // 60 secs_end = int(game["end"]) % 60 dur = game["end"] - game["start"] print( f"{i}. {mins_start:02d}:{secs_start:02d} - {mins_end:02d}:{secs_end:02d} " f"({dur // 60}m {dur % 60}s) - {game['finish_type']}" ) return games def find_highlights_in_game(game, transcription, chat_data, min_score=6): """Encuentra highlights dentro de un juego específico.""" # Patrones de rage/highlights rage_patterns = [ (r"\bputa\w*", 10, "RAGE"), (r"\bme mataron\b", 12, "DEATH"), (r"\bme mori\b", 12, "DEATH"), (r"\bmierda\b", 8, "RAGE"), (r"\bjoder\b", 8, "RAGE"), (r"\bretrasad\w*", 9, "INSULT"), (r"\bimbecil\b", 9, "INSULT"), (r"\bla cague\b", 8, "FAIL"), (r"\bnooo+\b", 6, "FRUSTRATION"), ] highlights = [] # Buscar en transcripción de este juego for seg in transcription["segments"]: if seg["start"] < game["start"] or seg["end"] > game["end"]: continue text = seg["text"].lower() score = 0 reasons = [] for pattern, points, reason in rage_patterns: import re if re.search(pattern, text, re.IGNORECASE): score += points if reason not in reasons: reasons.append(reason) if score >= min_score: highlights.append( { "time": seg["start"], "score": score, "text": seg["text"][:60], "reasons": reasons, } ) # Ordenar y tomar top 3 de este juego highlights.sort(key=lambda x: -x["score"]) return highlights[:3] def create_game_summary(games, transcription, chat_data): """Crea un resumen con highlights de cada juego.""" print("\n" + "=" * 60) print("RESUMEN POR JUEGO") print("=" * 60) all_clips = [] for i, game in enumerate(games, 1): print(f"\nJuego {i}:") highlights = find_highlights_in_game(game, transcription, chat_data) if not highlights: print(" Sin highlights destacados") continue # Tomar el mejor highlight de este juego best = highlights[0] # Crear clip extendido (10s antes, 15s después) clip_start = max(game["start"], best["time"] - 10) clip_end = min(game["end"], best["time"] + 20) # Asegurar que no incluya selección de campeones if clip_start < game["start"] + 30: # Primeros 30s suelen ser selección clip_start = game["start"] + 30 if clip_end - clip_start >= 15: all_clips.append( { "game": i, "start": int(clip_start), "end": int(clip_end), "score": best["score"], "text": best["text"], "reasons": best["reasons"], } ) mins = int(clip_start) // 60 secs = int(clip_start) % 60 print(f" {mins:02d}:{secs:02d} - {best['text'][:50]}...") print(f" Score: {best['score']} - {'/'.join(best['reasons'])}") # Ordenar clips por tiempo all_clips.sort(key=lambda x: x["start"]) print(f"\n" + "=" * 60) print(f"Total clips: {len(all_clips)}") total_dur = sum(c["end"] - c["start"] for c in all_clips) print(f"Duración total: {total_dur}s ({total_dur // 60}m {total_dur % 60}s)") return all_clips if __name__ == "__main__": # Detectar juegos games = detect_game_boundaries("transcripcion_rage.json") # Cargar datos with open("transcripcion_rage.json", "r") as f: trans = json.load(f) with open("elxokas_chat.json", "r") as f: chat = json.load(f) # Crear resumen clips = create_game_summary(games, trans, chat) # Guardar highlights = [[c["start"], c["end"]] for c in clips] with open("highlights_multi_game.json", "w") as f: json.dump(highlights, f) print("\nTimeline final:") for i, c in enumerate(clips, 1): mins, secs = divmod(c["start"], 60) dur = c["end"] - c["start"] print( f"{i}. {mins:02d}:{secs:02d} - {dur}s (Juego {c['game']}) [{'/'.join(c['reasons'])}]" ) print(f"\nGuardado en highlights_multi_game.json")