Ai_video_detector / api /predict.py
Chethanand's picture
Upload 24 files
eb3afa1 verified
Raw
History Blame Contribute Delete
3.56 kB
import os
import sys
import time
import tempfile
import uuid
import torch
import numpy as np
from flask import Blueprint, request, jsonify, current_app
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from config import config
from utils.video_utils import load_video_frames, normalize_frames, validate_video
predict_bp = Blueprint("predict", __name__)
ALLOWED_EXTENSIONS = {".mp4", ".avi", ".mkv", ".mov", ".webm"}
def _allowed_file(filename: str) -> bool:
return os.path.splitext(filename.lower())[1] in ALLOWED_EXTENSIONS
@predict_bp.route("/predict", methods=["POST"])
def predict():
# ── Validate upload ───────────────────────────────────────────────────────
if "video" not in request.files:
return jsonify({"error": "No video file provided"}), 400
file = request.files["video"]
if file.filename == "":
return jsonify({"error": "Empty filename"}), 400
if not _allowed_file(file.filename):
exts = ", ".join(ALLOWED_EXTENSIONS)
return jsonify({"error": f"Unsupported format. Allowed: {exts}"}), 415
# ── Save to temp path ─────────────────────────────────────────────────────
suffix = os.path.splitext(file.filename)[1]
tmp_path = os.path.join(tempfile.gettempdir(), f"aivd_{uuid.uuid4().hex}{suffix}")
try:
file.save(tmp_path)
except Exception as e:
return jsonify({"error": f"Could not save file: {e}"}), 500
# ── Inference ─────────────────────────────────────────────────────────────
t_start = time.time()
try:
model = current_app.model
device = current_app.device
if not validate_video(tmp_path):
return jsonify({"error": "Invalid or corrupted video file"}), 422
frames = load_video_frames(
tmp_path,
num_frames=config.FRAMES_PER_VIDEO,
frame_size=(config.FRAME_HEIGHT, config.FRAME_WIDTH),
frame_skip=config.FRAME_SKIP,
)
if frames is None:
return jsonify({"error": "Could not extract frames from video"}), 422
frames = normalize_frames(frames)
frames_tensor = torch.from_numpy(frames).float()
frames_tensor = frames_tensor.permute(0, 3, 1, 2) # (T, 3, H, W)
frames_tensor = frames_tensor.unsqueeze(0) # (1, T, 3, H, W)
frames_tensor = frames_tensor.to(device)
with torch.no_grad():
output = model(frames_tensor)
prob = torch.sigmoid(output).item()
threshold = config.PREDICTION_THRESHOLD
is_ai = prob > threshold
verdict = "AI GENERATED" if is_ai else "REAL VIDEO"
confidence = prob if is_ai else (1.0 - prob)
elapsed = round(time.time() - t_start, 2)
return jsonify({
"verdict": verdict,
"is_ai": is_ai,
"probability": round(prob, 6),
"confidence": round(confidence * 100, 2),
"processing_time": elapsed,
"threshold": threshold,
})
except Exception as e:
return jsonify({"error": str(e)}), 500
finally:
try:
os.remove(tmp_path)
except OSError:
pass