In [ ]:
# ============================================================
# TRON: Early Earthquake Warning via Animal Behavior Analysis
# Rutube → ffmpeg → OpenCV → Gemma 4
# ============================================================

!pip install -q google-genai opencv-python-headless
!apt-get -q -y install ffmpeg
print("✅ Зависимости установлены")
In [ ]:
# ── ПОДКЛЮЧЕНИЕ К GEMMA 4 ──────────────────────────────────────
from kaggle_secrets import UserSecretsClient
from google import genai
from google.genai import types
import requests, subprocess, cv2, json
from pathlib import Path

secret = UserSecretsClient()
api_key = secret.get_secret("GOOGLE_API_KEY")
client = genai.Client(api_key=api_key)

Path("/kaggle/working/tron/videos").mkdir(parents=True, exist_ok=True)
Path("/kaggle/working/tron/frames").mkdir(parents=True, exist_ok=True)

print("✅ Gemma 4 подключена")# ── ПОДКЛЮЧЕНИЕ К GEMMA 4 ──────────────────────────────────────
from kaggle_secrets import UserSecretsClient
from google import genai
from google.genai import types
import requests, subprocess, cv2, json
from pathlib import Path

secret = UserSecretsClient()
api_key = secret.get_secret("GOOGLE_API_KEY")
client = genai.Client(api_key=api_key)

Path("/kaggle/working/tron/videos").mkdir(parents=True, exist_ok=True)
Path("/kaggle/working/tron/frames").mkdir(parents=True, exist_ok=True)

print("✅ Gemma 4 подключена")
In [ ]:
# ── СКАЧИВАНИЕ ВИДЕО С RUTUBE ──────────────────────────────────
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Referer": "https://rutube.ru/",
}

def download_video(video_id, seconds=30):
    out_path = f"/kaggle/working/tron/videos/{video_id}.mp4"
    if Path(out_path).exists():
        print(f"  [=] Уже скачано")
        return out_path
    resp = requests.get(
        f"https://rutube.ru/api/play/options/{video_id}/",
        headers=headers, timeout=10
    )
    m3u8_url = resp.json()["video_balancer"]["m3u8"]
    subprocess.run(
        ["ffmpeg", "-i", m3u8_url, "-c", "copy", "-t", str(seconds), out_path, "-y"],
        capture_output=True
    )
    size = Path(out_path).stat().st_size // 1024
    print(f"  ✅ Скачано: {size} KB")
    return out_path

def extract_frames(video_path, video_id, every_seconds=5, max_frames=6):
    frames_dir = Path(f"/kaggle/working/tron/frames/{video_id}")
    frames_dir.mkdir(parents=True, exist_ok=True)
    cap = cv2.VideoCapture(video_path)
    fps = cap.get(cv2.CAP_PROP_FPS) or 25
    saved, count = [], 0
    while len(saved) < max_frames:
        ret, frame = cap.read()
        if not ret: break
        if count % int(fps * every_seconds) == 0:
            path = str(frames_dir / f"frame_{count:06d}.jpg")
            cv2.imwrite(path, frame)
            saved.append(path)
        count += 1
    cap.release()
    print(f"  ✅ Кадров: {len(saved)}")
    return saved

print("✅ Функции загрузки готовы")
In [ ]:
# ── ДИНАМИЧЕСКИЙ АНАЛИЗ ЧЕРЕЗ GEMMA 4 ─────────────────────────
def analyze_dynamic(frames, video_id):
    contents = []
    for i, fp in enumerate(frames):
        contents.append(types.Part.from_bytes(
            data=open(fp, "rb").read(), mime_type="image/jpeg"
        ))
        contents.append(f"Кадр {i+1}")
    
    contents.append("""
Ты — система TRON: раннее предупреждение землетрясений через поведение животных.
Перед тобой последовательные кадры с интервалом 5 секунд.

Проанализируй ДИНАМИКУ поведения от кадра к кадру:
- Как меняется расстояние между животными?
- Есть ли синхронные реакции?
- Есть ли защитное поведение, паника, скопление?

Временная шкала: опиши что происходит на каждом кадре.

Итог строго в формате:
СТАТУС: NORMAL / SUSPICIOUS / ANOMALY
УВЕРЕННОСТЬ: HIGH / MEDIUM / LOW
КЛЮЧЕВОЙ ПАТТЕРН: (одна фраза)
ОБОСНОВАНИЕ: (2-3 предложения)
""")
    
    response = client.models.generate_content(
        model="gemma-4-31b-it",
        contents=contents
    )
    return response.text

print("✅ Функция анализа готова")
In [ ]:
# ── ЗАПУСК TRON ────────────────────────────────────────────────
# Слоны во время землетрясения — наш ключевой тест
VIDEOS = {
    "a373489a111867d1f5ac7e0ebba5456c": "🐘 Слоны (землетрясение)",
    "398399360ba36dc12230f2321b0ebfc6": "🐱 Кошка с котятами (норма)",
    "d28d17606082b9bf719338e007b7f93d": "🐱 Кошка (норма)",
}

results = []

for video_id, label in VIDEOS.items():
    print(f"\n{'='*55}")
    print(f"📹 {label}")
    print(f"{'='*55}")
    
    video_path = download_video(video_id)
    frames = extract_frames(video_path, video_id)
    
    if not frames:
        print("  ❌ Кадры не извлечены")
        continue
    
    print("  🔍 Анализирую динамику...")
    analysis = analyze_dynamic(frames, video_id)
    print(analysis)
    
    # Определяем итоговый статус
    status = "🟢 NORMAL"
    if "ANOMALY" in analysis.upper():
        status = "🔴 ANOMALY"
    elif "SUSPICIOUS" in analysis.upper():
        status = "🟡 SUSPICIOUS"
    
    results.append({"label": label, "status": status})

print(f"\n{'='*55}")
print("📊 ИТОГИ TRON:")
for r in results:
    print(f"  {r['status']} | {r['label']}")