Spaces:
Sleeping
Sleeping
""" | |
Deepfake Detection System - Gradio Application | |
""" | |
import gradio as gr | |
import os | |
from pathlib import Path | |
from utils.detect import DeepfakeDetector | |
import tempfile | |
def analyze_media(api_key, media_file, media_type): | |
""" | |
Analyze media file for deepfake content | |
Args: | |
api_key: Gemini API key | |
media_file: Uploaded file | |
media_type: "Image" or "Video" | |
Returns: | |
tuple: (result_html, confidence_score, verdict) | |
""" | |
# Validate API key | |
if not api_key or api_key.strip() == "": | |
return ( | |
"β οΈ **Error**: Please enter your Gemini API key first.", | |
None, | |
None | |
) | |
# Validate file upload | |
if media_file is None: | |
return ( | |
"β οΈ **Error**: Please upload a file to analyze.", | |
None, | |
None | |
) | |
try: | |
# Get file path | |
file_path = media_file.name if hasattr(media_file, 'name') else media_file | |
# Initialize detector | |
detector = DeepfakeDetector(api_key.strip()) | |
# Perform analysis based on media type | |
if media_type == "Image": | |
results = detector.analyze_image(file_path) | |
else: # Video | |
results = detector.analyze_video(file_path, max_frames=10) | |
# Check for errors | |
if 'error' in results: | |
return ( | |
f"β **Error during analysis**: {results['error']}\n\nPlease check your API key and try again.", | |
None, | |
None | |
) | |
# Format results | |
result_html = format_results(results, media_type) | |
confidence = results.get('confidence_score', 0) | |
verdict = "π΄ LIKELY DEEPFAKE" if results.get('is_deepfake', False) else "π’ LIKELY AUTHENTIC" | |
return result_html, confidence, verdict | |
except Exception as e: | |
return ( | |
f"β **Error**: {str(e)}\n\nPlease check your file and API key, then try again.", | |
None, | |
None | |
) | |
def format_results(results, media_type): | |
"""Format analysis results as HTML""" | |
is_fake = results.get('is_deepfake', False) | |
confidence = results.get('confidence_score', 0) | |
analysis = results.get('analysis', 'No analysis available.') | |
indicators = results.get('indicators', []) | |
# Build HTML output | |
#html = f""" | |
#<div style="font-family: Arial, sans-serif;"> | |
# <h2>π Analysis Results</h2>""" | |
# First, define the conditional style string | |
style = ( | |
"background-color: #fee; border-left: 4px solid #f00;" | |
if is_fake else | |
"background-color: #efe; border-left: 4px solid #0f0;" | |
) | |
# Then build the full HTML block using that style | |
html = f""" | |
<div style="font-family: Arial, sans-serif;"> | |
<h2>π Analysis Results</h2> | |
<div style="{style} padding: 15px; margin: 10px 0;"> | |
<h3>{'π΄ LIKELY DEEPFAKE/AI-GENERATED' if is_fake else 'π’ LIKELY AUTHENTIC'}</h3> | |
</div> | |
""" | |
html = f""" | |
<div style="background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px;"> | |
<h3>π Detection Metrics</h3> | |
<p><strong>Confidence Score:</strong> {confidence:.1f}%</p> | |
<p><strong>Authenticity:</strong> {100 - confidence:.1f}%</p> | |
<p><strong>Risk Level:</strong> {'High' if confidence > 70 else 'Medium' if confidence > 40 else 'Low'}</p> | |
</div> | |
<div style="background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px;"> | |
<h3>π Detailed Analysis</h3> | |
<p style="white-space: pre-wrap;">{analysis}</p> | |
</div> | |
""" | |
# Add indicators if found | |
if indicators: | |
html += """ | |
<div style="background: #fff3cd; padding: 15px; margin: 10px 0; border-radius: 5px; border-left: 4px solid #ffc107;"> | |
<h3>β οΈ Deepfake Indicators Detected</h3> | |
<ul> | |
""" | |
for indicator in indicators[:5]: | |
html += f"<li>{indicator}</li>" | |
html += """ | |
</ul> | |
</div> | |
""" | |
# Add video-specific results | |
if media_type == "Video" and 'frame_analysis' in results: | |
frame_data = results['frame_analysis'] | |
html += f""" | |
<div style="background: #e7f3ff; padding: 15px; margin: 10px 0; border-radius: 5px; border-left: 4px solid #2196F3;"> | |
<h3>π¬ Frame-by-Frame Analysis</h3> | |
<p><strong>Total Frames Analyzed:</strong> {frame_data.get('total_frames', 0)}</p> | |
<p><strong>Suspicious Frames:</strong> {frame_data.get('suspicious_frames', 0)}</p> | |
</div> | |
""" | |
# Add recommendations | |
html += """ | |
<div style="background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px;"> | |
<h3>π‘ Recommendations</h3> | |
""" | |
if is_fake: | |
html += """ | |
<p><strong>This media shows signs of manipulation or AI generation. Consider:</strong></p> | |
<ul> | |
<li>Verifying the source</li> | |
<li>Looking for corroborating evidence</li> | |
<li>Checking metadata</li> | |
<li>Consulting additional verification tools</li> | |
<li>Being cautious about sharing</li> | |
</ul> | |
""" | |
else: | |
html += """ | |
<p><strong>This media appears authentic, but remember:</strong></p> | |
<ul> | |
<li>No detection system is 100% accurate</li> | |
<li>Always verify important content through multiple sources</li> | |
<li>Check the original source when possible</li> | |
</ul> | |
""" | |
html += """ | |
</div> | |
</div> | |
""" | |
return html | |
# Create Gradio interface | |
def create_interface(): | |
"""Create and configure Gradio interface""" | |
with gr.Blocks(title="Deepfake Detection System", theme=gr.themes.Soft()) as demo: | |
# Header | |
gr.Markdown(""" | |
# π Deepfake Detection System | |
### Analyze images and videos for AI-generated or manipulated content | |
This system uses Google's Gemini AI to detect deepfakes and AI-generated content in media files. | |
""") | |
# API Key Section | |
with gr.Row(): | |
with gr.Column(scale=3): | |
api_key_input = gr.Textbox( | |
label="π Gemini API Key", | |
type="password", | |
placeholder="Enter your Google Gemini API key here...", | |
info="Get your free API key from https://makersuite.google.com/app/apikey" | |
) | |
with gr.Column(scale=1): | |
gr.Markdown(""" | |
### π How to get API Key: | |
1. Visit [Google AI Studio](https://makersuite.google.com/app/apikey) | |
2. Sign in with Google | |
3. Create API key | |
4. Paste it here | |
""") | |
gr.Markdown("---") | |
# Main Interface | |
with gr.Row(): | |
with gr.Column(scale=1): | |
# Media Type Selection | |
media_type = gr.Radio( | |
choices=["Image", "Video"], | |
value="Image", | |
label="π Select Media Type", | |
info="Choose the type of media you want to analyze" | |
) | |
# File Upload | |
media_file = gr.File( | |
label="π€ Upload Media File", | |
file_types=["image", "video"], | |
type="filepath" | |
) | |
# Analyze Button | |
analyze_btn = gr.Button( | |
"π Analyze Media", | |
variant="primary", | |
size="lg" | |
) | |
# Quick Stats | |
gr.Markdown(""" | |
### π Supported Formats | |
**Images:** JPG, PNG, WEBP | |
**Videos:** MP4, AVI, MOV, MKV | |
### β±οΈ Processing Time | |
**Images:** 5-15 seconds | |
**Videos:** 30-60 seconds | |
""") | |
with gr.Column(scale=2): | |
# Results Display | |
gr.Markdown("### π Analysis Results") | |
with gr.Row(): | |
verdict_output = gr.Textbox( | |
label="Verdict", | |
interactive=False, | |
scale=2 | |
) | |
confidence_output = gr.Number( | |
label="Confidence Score (%)", | |
interactive=False, | |
scale=1 | |
) | |
result_output = gr.HTML( | |
label="Detailed Analysis" | |
) | |
# Footer | |
gr.Markdown(""" | |
--- | |
### β οΈ Important Notes | |
- **Not 100% Accurate**: No detection system is perfect. Always verify through multiple sources. | |
- **Privacy**: Your API key and files are not stored. They're only used for analysis. | |
- **For Educational Use**: This tool is for educational and research purposes. | |
### π οΈ Technology Stack | |
Built with: Google Gemini AI β’ Gradio β’ OpenCV β’ Python | |
""") | |
# Connect the analyze button | |
analyze_btn.click( | |
fn=analyze_media, | |
inputs=[api_key_input, media_file, media_type], | |
outputs=[result_output, confidence_output, verdict_output] | |
) | |
# Examples section | |
gr.Markdown(""" | |
### π‘ Tips for Best Results | |
- Use high-quality images and videos | |
- Ensure good lighting in the media | |
- Videos should be at least 5 seconds long | |
- Check multiple suspicious areas if available | |
""") | |
return demo | |
# Launch the application | |
if __name__ == "__main__": | |
demo = create_interface() | |
demo.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=False | |
) |