from flask import Flask, request, jsonify, render_template_string
from flask_cors import CORS
from model import predict_deepfake
import os
import cv2
import math
app = Flask(__name__)
CORS(app)
# Increase max upload size to 500MB for long videos
app.config['MAX_CONTENT_LENGTH'] = 500 * 1024 * 1024
# --- FRONTEND ---
HTML_PAGE = """
DeepGuard Pro - Long Video Scanner
🛡️ DeepGuard Pro
Scanner for Images & Long Videos (up to 10 mins)
Uploading file... (This may take a minute for large videos)
"""
@app.route('/')
def home():
return render_template_string(HTML_PAGE)
def analyze_video_smartly(video_path):
"""
Scans a video by checking frames at different intervals.
Returns the WORST result found (if any frame is fake, the video is fake).
"""
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
return {"error": "Could not open video"}
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
fps = cap.get(cv2.CAP_PROP_FPS)
if fps == 0: fps = 30
# STRATEGY: Check 6 frames spread evenly across the video
num_checks = 6
fake_detected = False
highest_fake_confidence = 0.0
# We will store the confidence of every 'Real' frame to calculate a true average
real_confidences = []
frames_checked = 0
for i in range(num_checks):
# Calculate position (0% to 100%)
frame_pos = int((i / (num_checks - 1)) * (total_frames - 1))
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_pos)
ret, frame = cap.read()
if ret:
frames_checked += 1
# Save temporary frame
temp_frame_path = f"temp_frame_{i}.jpg"
cv2.imwrite(temp_frame_path, frame)
# Predict
try:
pred = predict_deepfake(temp_frame_path)
# Extract the number from "87.5%" -> 87.5
try:
current_conf_val = float(pred['confidence'].replace('%','').strip())
except:
current_conf_val = 0.0
# If this specific frame is FAKE
if pred['is_fake']:
fake_detected = True
# Keep track of how confident we are it's fake
if current_conf_val > highest_fake_confidence:
highest_fake_confidence = current_conf_val
else:
# If it's REAL, add to our list to calculate average later
real_confidences.append(current_conf_val)
except Exception as e:
print(f"Frame {i} failed: {e}")
# Cleanup frame
if os.path.exists(temp_frame_path):
os.remove(temp_frame_path)
# Optimization: If we found a very obvious fake, stop scanning.
if fake_detected and highest_fake_confidence > 90:
break
cap.release()
if fake_detected:
return {
"is_fake": True,
"message": "Suspicious content detected in video segments.",
"confidence": f"{highest_fake_confidence:.2f}%",
"frames_checked": frames_checked
}
else:
# --- CALCULATION FIX ---
# Calculate the actual average confidence of the scanned frames
if len(real_confidences) > 0:
avg_conf = sum(real_confidences) / len(real_confidences)
display_conf = f"{avg_conf:.2f}% (Avg)"
else:
display_conf = "Unknown"
return {
"is_fake": False,
"message": "No deepfake anomalies detected across video timeline.",
"confidence": display_conf,
"frames_checked": frames_checked
}
@app.route('/analyze', methods=['POST'])
def analyze():
if 'file' not in request.files:
return jsonify({"error": "No file uploaded"}), 400
file = request.files['file']
filename = file.filename.lower()
temp_path = "temp_upload_file"
file.save(temp_path)
result = {}
try:
# VIDEO MODE
if filename.endswith(('.mp4', '.mov', '.avi', '.webm', '.mkv')):
result = analyze_video_smartly(temp_path)
# IMAGE MODE
else:
result = predict_deepfake(temp_path)
result['frames_checked'] = 1
except Exception as e:
return jsonify({"error": str(e)}), 500
finally:
if os.path.exists(temp_path):
os.remove(temp_path)
return jsonify(result)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860)