Files
twitch-highlight-detector/smart_detector.py
renato97 00180d0b1c Sistema completo de detección de highlights con VLM y análisis de gameplay
- Implementación de detector híbrido (Whisper + Chat + Audio + VLM)
- Sistema de detección de gameplay real vs hablando
- Scene detection con FFmpeg
- Soporte para RTX 3050 y RX 6800 XT
- Guía completa en 6800xt.md para próxima IA
- Scripts de filtrado visual y análisis de contexto
- Pipeline automatizado de generación de videos
2026-02-19 17:38:14 +00:00

180 lines
5.2 KiB
Python

#!/usr/bin/env python3
"""
SMART GAME DETECTOR
Combina análisis de transcripción + reglas temporales para detectar gameplay real.
"""
import json
import re
import numpy as np
def detect_games_smart(trans_file):
"""Detecta juegos considerando patrones de League of Legends."""
with open(trans_file, "r") as f:
trans = json.load(f)
print("=" * 60)
print("SMART GAME DETECTOR")
print("=" * 60)
# Buscar inicios de juego
game_starts = []
for i, seg in enumerate(trans["segments"]):
text = seg["text"].lower()
# Inicio típico de partida LoL
if any(
phrase in text
for phrase in [
"bienvenidos",
"invocadores",
"welcome",
"empezamos",
"vamos allá",
"arrancamos",
]
):
if seg["start"] > 120: # Después de intro
game_starts.append(seg["start"])
print(
f"Posible inicio de juego en {seg['start'] // 60}m {seg['start'] % 60:.0f}s: {text[:50]}..."
)
# También buscar por cambios de personaje/campeón
champ_mentions = {}
for seg in trans["segments"]:
text = seg["text"].lower()
# Buscar menciones de campeones
champs = [
"warwick",
"diana",
"mundo",
"yasuo",
"zed",
"lee sin",
"jhin",
"lucian",
]
for champ in champs:
if champ in text:
if champ not in champ_mentions:
champ_mentions[champ] = []
champ_mentions[champ].append(seg["start"])
print(f"\nMenciones de campeones:")
for champ, times in champ_mentions.items():
if (
len(times) > 5
): # Mencionado varias veces = probablemente jugando ese campeón
first = min(times)
last = max(times)
print(
f" {champ}: {len(times)} veces, desde {first // 60}m hasta {last // 60}m"
)
return game_starts, champ_mentions
def extract_best_moments(trans_file, min_timestamp=455):
"""Extrae los mejores momentos considerando contexto."""
with open(trans_file, "r") as f:
trans = json.load(f)
# Dividir en bloques de 30 minutos (aprox duración de partida LoL)
block_size = 30 * 60 # 30 minutos
duration = trans["segments"][-1]["end"]
print(f"\nAnalizando {duration / 60:.0f} minutos en bloques de 30 min...")
all_moments = []
for block_start in range(int(min_timestamp), int(duration), block_size):
block_end = min(block_start + block_size, int(duration))
# Buscar mejor momento en este bloque
best_moment = None
best_score = 0
for seg in trans["segments"]:
if seg["start"] < block_start or seg["end"] > block_end:
continue
text = seg["text"].lower()
score = 0
reasons = []
# Rage
if re.search(r"\bputa\w*", text):
score += 10
reasons.append("RAGE")
elif re.search(r"\bmierda\b", text):
score += 7
reasons.append("RAGE")
# Acción de juego
if any(
word in text
for word in ["me mataron", "me mori", "kill", "mate", "muere"]
):
score += 8
reasons.append("KILL")
if any(word in text for word in ["ulti", "flash", "teamfight", "pelea"]):
score += 5
reasons.append("SKILL")
# Frustración
if any(word in text for word in ["joder", "hostia", "no puede ser"]):
score += 4
reasons.append("FRUSTRATION")
if score > best_score:
best_score = score
best_moment = {
"time": seg["start"],
"score": score,
"text": seg["text"][:60],
"reasons": reasons,
"block": block_start,
}
if best_moment and best_score >= 8:
all_moments.append(best_moment)
mins = int(best_moment["time"]) // 60
secs = int(best_moment["time"]) % 60
print(
f" Bloque {len(all_moments)}: {mins:02d}:{secs:02d} [Score {best_score}] {'/'.join(reasons)}"
)
return all_moments
if __name__ == "__main__":
# Detectar estructura
game_starts, champs = detect_games_smart("transcripcion_rage.json")
# Extraer mejores momentos
moments = extract_best_moments("transcripcion_rage.json")
print(f"\nTotal momentos encontrados: {len(moments)}")
# Crear clips
clips = []
for m in moments[:8]: # Máximo 8
start = max(455, int(m["time"]) - 12)
end = min(8237, int(m["time"]) + 20)
clips.append([start, end])
# Guardar
with open("highlights_smart.json", "w") as f:
json.dump(clips, f)
print(f"\nClips guardados: {len(clips)}")
for i, (s, e) in enumerate(clips, 1):
mins, secs = divmod(s, 60)
print(f"{i}. {mins:02d}:{secs:02d} - {e - s}s")