Nithyashreel commited on
Commit
205d024
·
verified ·
1 Parent(s): f058306

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +1394 -0
  2. requirements-minimal.txt +42 -0
app.py ADDED
@@ -0,0 +1,1394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Streamlit Web Interface for DeepFake Detection System
3
+ Main application file with all pages and features
4
+ """
5
+
6
+ # CRITICAL: Set up Python path FIRST (before any other imports)
7
+ import os
8
+ import sys
9
+ project_root = os.path.dirname(os.path.abspath(__file__))
10
+ if project_root not in sys.path:
11
+ sys.path.insert(0, project_root)
12
+ print(f"✓ Project root added to path: {project_root}")
13
+ print(f"✓ Python path: {sys.path[:3]}")
14
+
15
+ # Now import standard libraries
16
+ import streamlit as st
17
+ import subprocess
18
+ import numpy as np
19
+ from PIL import Image
20
+ import tempfile
21
+ import time
22
+ from datetime import datetime
23
+ import cv2
24
+
25
+ # Import detection modules (now path is set correctly)
26
+ from detection.image_detection import ImageDeepFakeDetector
27
+ from detection.video_detection import VideoDeepFakeDetector
28
+ from detection.audio_detection import AudioDeepFakeDetector
29
+ from detection.webcam_detection import WebcamDeepFakeDetector
30
+
31
+ # Import analysis modules
32
+ from analysis.heatmap_visualization import HeatmapVisualizer
33
+
34
+ # Import authentication
35
+ from auth.login import AuthenticationManager
36
+
37
+ # Import report generation
38
+ from reports.generate_report import PDFReportGenerator
39
+
40
+
41
+ # Page configuration
42
+ st.set_page_config(
43
+ page_title="DeepFake Detection System",
44
+ page_icon="🔍",
45
+ layout="wide",
46
+ initial_sidebar_state="expanded"
47
+ )
48
+
49
+ # Custom CSS
50
+ st.markdown("""
51
+ <style>
52
+ .main-header {
53
+ font-size: 3rem;
54
+ font-weight: bold;
55
+ color: #1a1a2e;
56
+ text-align: center;
57
+ margin-bottom: 1rem;
58
+ }
59
+ .sub-header {
60
+ font-size: 1.2rem;
61
+ color: #666666;
62
+ text-align: center;
63
+ margin-bottom: 2rem;
64
+ }
65
+ .result-box {
66
+ padding: 1rem;
67
+ border-radius: 0.5rem;
68
+ margin: 1rem 0;
69
+ }
70
+ .fake-result {
71
+ background-color: #ffe6e6;
72
+ border-left: 5px solid #ff4444;
73
+ }
74
+ .real-result {
75
+ background-color: #e6ffe6;
76
+ border-left: 5px solid #44ff44;
77
+ }
78
+ .metric-card {
79
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
80
+ padding: 1rem;
81
+ border-radius: 0.5rem;
82
+ color: white;
83
+ text-align: center;
84
+ }
85
+ </style>
86
+ """, unsafe_allow_html=True)
87
+
88
+
89
+ # Initialize session state
90
+ if 'authenticated' not in st.session_state:
91
+ st.session_state.authenticated = False
92
+ if 'current_user' not in st.session_state:
93
+ st.session_state.current_user = None
94
+ if 'detectors' not in st.session_state:
95
+ st.session_state.detectors = {}
96
+
97
+
98
+ def initialize_detectors():
99
+ """Initialize detection models"""
100
+ if not st.session_state.detectors:
101
+ with st.spinner("Loading AI models..."):
102
+ try:
103
+ st.session_state.detectors['image'] = ImageDeepFakeDetector()
104
+ st.session_state.detectors['video'] = VideoDeepFakeDetector(
105
+ model_path='models/video_model_fast.h5',
106
+ img_size=(224, 224),
107
+ max_frames=30
108
+ )
109
+ st.session_state.detectors['audio'] = AudioDeepFakeDetector(
110
+ model_path='models/audio_model.h5',
111
+ sr=16000,
112
+ duration=5
113
+ )
114
+ st.session_state.detectors['heatmap'] = HeatmapVisualizer()
115
+
116
+ # Store model info for display
117
+ st.session_state.model_info = {
118
+ 'video': {
119
+ 'path': 'video_model_fast.h5',
120
+ 'frames': 30,
121
+ 'note': 'Optimized for speed with calibration'
122
+ },
123
+ 'audio': {
124
+ 'path': 'audio_model.h5',
125
+ 'duration': '5 seconds',
126
+ 'note': 'Calibrated for reduced false positives'
127
+ }
128
+ }
129
+
130
+ st.success("✓ All models loaded successfully!")
131
+ except Exception as e:
132
+ st.warning(f"⚠ Some models could not be loaded: {e}")
133
+
134
+
135
+ def login_page():
136
+ """Login and registration page"""
137
+ auth = AuthenticationManager()
138
+
139
+ col1, col2, col3 = st.columns([1, 2, 1])
140
+
141
+ with col2:
142
+ st.markdown("<h1 class='main-header'>🔐 User Authentication</h1>", unsafe_allow_html=True)
143
+
144
+ tab1, tab2 = st.tabs(["Login", "Register"])
145
+
146
+ with tab1:
147
+ st.subheader("Login to Your Account")
148
+ username = st.text_input("Username", key="login_username")
149
+ password = st.text_input("Password", type="password", key="login_password")
150
+
151
+ if st.button("Login", type="primary", use_container_width=True):
152
+ success, message, user = auth.login(username, password)
153
+
154
+ if success:
155
+ st.session_state.authenticated = True
156
+ st.session_state.current_user = user
157
+ st.success(message)
158
+ time.sleep(1)
159
+ st.rerun()
160
+ else:
161
+ st.error(message)
162
+
163
+ with tab2:
164
+ st.subheader("Create New Account")
165
+ new_username = st.text_input("Choose Username", key="reg_username")
166
+ new_email = st.text_input("Email Address", key="reg_email")
167
+ new_password = st.text_input("Password", type="password", key="reg_password")
168
+ confirm_password = st.text_input("Confirm Password", type="password", key="reg_confirm")
169
+
170
+ if st.button("Register", type="primary", use_container_width=True):
171
+ success, message, user_id = auth.register(
172
+ new_username, new_email, new_password, confirm_password
173
+ )
174
+
175
+ if success:
176
+ st.success(message)
177
+ st.info("Please login with your credentials")
178
+ else:
179
+ st.error(message)
180
+
181
+
182
+ def main_app():
183
+ """Main application interface"""
184
+ auth = AuthenticationManager()
185
+
186
+ # Sidebar navigation
187
+ with st.sidebar:
188
+ st.title("🎯 Navigation")
189
+
190
+ # User info
191
+ if st.session_state.current_user:
192
+ st.success(f"👤 {st.session_state.current_user['username']}")
193
+ if st.button("Logout", use_container_width=True):
194
+ st.session_state.authenticated = False
195
+ st.session_state.current_user = None
196
+ st.rerun()
197
+
198
+ st.divider()
199
+
200
+ # Navigation menu
201
+ pages = {
202
+ "🏠 Home": home_page,
203
+ "🖼️ Image Detection": image_detection_page,
204
+ "🎥 Video Detection": video_detection_page,
205
+ "🎵 Audio Detection": audio_detection_page,
206
+ "📹 Webcam Detection": webcam_detection_page,
207
+ "📊 Detection History": history_page,
208
+ "📥 Download Reports": reports_page
209
+ }
210
+
211
+ selected_page = st.radio("Navigate", list(pages.keys()), index=0)
212
+
213
+ st.divider()
214
+
215
+ # Quick stats
216
+ if st.session_state.current_user:
217
+ st.subheader("📈 Your Statistics")
218
+ try:
219
+ stats = auth.get_user_statistics(st.session_state.current_user['id'])
220
+ if stats and stats.get('total_detections', 0) > 0:
221
+ st.metric("Total Detections", stats['total_detections'])
222
+ st.metric("Fake Detected", stats['fake_count'])
223
+ st.metric("Accuracy Rate", f"{stats['average_confidence']*100:.1f}%")
224
+ else:
225
+ st.info("No detections yet. Start analyzing to see your statistics!")
226
+ except Exception as e:
227
+ st.error(f"Error loading statistics: {e}")
228
+
229
+ # Main content
230
+ page_func = pages[selected_page]
231
+ page_func()
232
+
233
+
234
+ def home_page():
235
+ """Home page"""
236
+ st.markdown("<h1 class='main-header'>🔍 DeepFake Detection System</h1>", unsafe_allow_html=True)
237
+ st.markdown("<p class='sub-header'>AI-Powered Media Authentication Platform | Military-Grade Encryption | Instant Response</p>", unsafe_allow_html=True)
238
+
239
+ # Hero section
240
+ col1, col2, col3 = st.columns(3)
241
+
242
+ with col1:
243
+ st.markdown("""
244
+ ### 🎯 What We Do
245
+ Advanced deepfake detection using cutting-edge AI to identify manipulated images, videos, and audio with 90%+ accuracy.
246
+ """)
247
+
248
+ with col2:
249
+ st.markdown("""
250
+ ### 🛡️ Features
251
+ - Multi-modal detection (Image/Video/Audio)
252
+ - Real-time webcam analysis
253
+ - Facial landmark analysis
254
+ - Lip-sync verification
255
+ - Eye blink detection
256
+ - PDF report generation
257
+ """)
258
+
259
+ with col3:
260
+ st.markdown("""
261
+ ### 💡 Technology
262
+ - CNN + ResNet50 for images
263
+ - CNN + LSTM for videos
264
+ - Mel Spectrogram CNN for audio
265
+ - Grad-CAM heatmaps
266
+ - FaceNet embeddings
267
+ """)
268
+
269
+ st.divider()
270
+
271
+ # Quick actions
272
+ st.subheader("🚀 Quick Start")
273
+
274
+ col1, col2, col3 = st.columns(3)
275
+
276
+ with col1:
277
+ if st.button("🖼️ Detect Image", use_container_width=True, type="primary"):
278
+ st.session_state.selected_page = "🖼️ Image Detection"
279
+
280
+ with col2:
281
+ if st.button("🎥 Detect Video", use_container_width=True, type="primary"):
282
+ st.session_state.selected_page = "🎥 Video Detection"
283
+
284
+ with col3:
285
+ if st.button("🎵 Detect Audio", use_container_width=True, type="primary"):
286
+ st.session_state.selected_page = "🎵 Audio Detection"
287
+
288
+ st.divider()
289
+
290
+ # Model information
291
+ st.subheader("📊 Model Performance")
292
+
293
+ col1, col2, col3 = st.columns(3)
294
+
295
+ with col1:
296
+ st.metric("Image Detection Accuracy", "92-96%", delta="High Confidence")
297
+
298
+ with col2:
299
+ st.metric("Video Detection Accuracy", "90%+", delta="Temporal Analysis")
300
+
301
+ with col3:
302
+ st.metric("Audio Detection Accuracy", "91%+", delta="Spectrogram Analysis")
303
+
304
+ # Information
305
+ with st.expander("ℹ️ How It Works"):
306
+ st.markdown("""
307
+ ### DeepFake Detection Process
308
+
309
+ 1. **Upload Media**: Submit your image, video, or audio file
310
+ 2. **Preprocessing**: Our system normalizes and prepares the input
311
+ 3. **Feature Extraction**: AI models extract relevant features
312
+ 4. **Analysis**: Multiple detection algorithms analyze the content
313
+ 5. **Results**: Get instant results with confidence scores
314
+ 6. **Report**: Download detailed PDF analysis report
315
+
316
+ ### Technologies Used
317
+
318
+ - **Convolutional Neural Networks (CNN)**: For spatial feature detection
319
+ - **Long Short-Term Memory (LSTM)**: For temporal pattern analysis in videos
320
+ - **Facial Landmark Detection**: 68-point facial analysis
321
+ - **Grad-CAM**: Visualization of manipulated regions
322
+ - **Mel Spectrograms**: Audio frequency analysis
323
+ """)
324
+
325
+
326
+ def image_detection_page():
327
+ """Image deepfake detection page"""
328
+ st.markdown("<h1 class='main-header'>🖼️ Image DeepFake Detection</h1>", unsafe_allow_html=True)
329
+
330
+ initialize_detectors()
331
+
332
+ # File uploader
333
+ uploaded_file = st.file_uploader(
334
+ "Upload an image to analyze",
335
+ type=['jpg', 'jpeg', 'png'],
336
+ help="Supported formats: JPG, JPEG, PNG"
337
+ )
338
+
339
+ if uploaded_file:
340
+ # Display uploaded image
341
+ col1, col2 = st.columns(2)
342
+
343
+ with col1:
344
+ image = Image.open(uploaded_file)
345
+ st.image(image, caption="Uploaded Image", use_container_width=True)
346
+
347
+ with col2:
348
+ with st.spinner("🔍 Analyzing image..."):
349
+ # Save to temp file
350
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as tmp_file:
351
+ tmp_file.write(uploaded_file.getvalue())
352
+ tmp_path = tmp_file.name
353
+
354
+ # Perform detection
355
+ detector = st.session_state.detectors.get('image')
356
+
357
+ if detector and detector.model:
358
+ result = detector.detect(tmp_path)
359
+
360
+ if result['success']:
361
+ # Display result
362
+ prediction = result['prediction']
363
+ confidence = result['confidence'] * 100
364
+
365
+ if prediction == 'Fake':
366
+ st.error(f"❌ DEEPFAKE DETECTED\n\nConfidence: {confidence:.1f}%")
367
+ else:
368
+ st.success(f"✅ AUTHENTIC IMAGE\n\nConfidence: {confidence:.1f}%")
369
+
370
+ # Detailed metrics
371
+ st.json({
372
+ "Prediction": prediction,
373
+ "Confidence": f"{confidence:.2f}%",
374
+ "Real Probability": f"{result['real_probability']*100:.2f}%",
375
+ "Fake Probability": f"{result['fake_probability']*100:.2f}%"
376
+ })
377
+
378
+ # Generate heatmap
379
+ if st.button("Generate Heatmap", type="primary"):
380
+ with st.spinner("Creating visualization..."):
381
+ heatmap_result = st.session_state.detectors['heatmap'].generate_grad_cam(tmp_path)
382
+
383
+ if heatmap_result['success']:
384
+ st.image(heatmap_result['overlay'],
385
+ caption="Grad-CAM Heatmap (Red = Manipulated)",
386
+ use_container_width=True)
387
+
388
+ # Show manipulation details
389
+ manip_info = heatmap_result['manipulation_regions']
390
+ st.write(f"**Manipulation Severity:** {manip_info['severity'].upper()}")
391
+ st.write(f"**Affected Area:** {manip_info['manipulation_ratio']*100:.1f}%")
392
+
393
+ # Save to history
394
+ if st.session_state.current_user:
395
+ from auth.database import DatabaseManager
396
+ db = DatabaseManager()
397
+
398
+ db.add_detection_record(
399
+ user_id=st.session_state.current_user['id'],
400
+ file_name=uploaded_file.name,
401
+ file_type='image',
402
+ prediction=prediction,
403
+ confidence=result['confidence'],
404
+ is_fake=(prediction == 'Fake'),
405
+ file_path=tmp_path,
406
+ analysis_details=str(result)
407
+ )
408
+
409
+ # Download report
410
+ if st.button("📥 Download PDF Report"):
411
+ generator = PDFReportGenerator()
412
+
413
+ with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as pdf_file:
414
+ report_path = generator.generate_report(
415
+ detection_result=result,
416
+ user_info=st.session_state.current_user,
417
+ save_path=pdf_file.name
418
+ )
419
+
420
+ if report_path:
421
+ with open(report_path, 'rb') as f:
422
+ st.download_button(
423
+ label="Download Report",
424
+ data=f.read(),
425
+ file_name=f"deepfake_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf",
426
+ mime="application/pdf"
427
+ )
428
+ else:
429
+ st.error(f"Detection failed: {result.get('error', 'Unknown error')}")
430
+ else:
431
+ st.warning("⚠ Image detection model not loaded. Please train the model first.")
432
+
433
+ # Cleanup
434
+ os.unlink(tmp_path)
435
+
436
+ else:
437
+ st.info("👆 Upload an image to begin analysis")
438
+
439
+ # Sample information
440
+ st.markdown("""
441
+ ### What to Look For
442
+
443
+ DeepFake images often show:
444
+ - Unnatural skin textures
445
+ - Inconsistent lighting
446
+ - Blurred boundaries
447
+ - Asymmetric facial features
448
+ - Strange artifacts around edges
449
+
450
+ ### Supported Formats
451
+ - **JPG/JPEG**: Most common image format
452
+ - **PNG**: Lossless compression
453
+ - Maximum size: 10MB
454
+ """)
455
+
456
+
457
+ def video_detection_page():
458
+ """Video deepfake detection page"""
459
+ st.markdown("<h1 class='main-header'>🎥 Video DeepFake Detection</h1>", unsafe_allow_html=True)
460
+
461
+ initialize_detectors()
462
+
463
+ uploaded_file = st.file_uploader(
464
+ "Upload a video to analyze",
465
+ type=['mp4', 'avi', 'mov'],
466
+ help="Supported formats: MP4, AVI, MOV"
467
+ )
468
+
469
+ if uploaded_file:
470
+ st.video(uploaded_file)
471
+
472
+ if st.button("🔍 Analyze Video", type="primary"):
473
+ with st.spinner("Processing video... This may take a few minutes."):
474
+ # Save to temp file
475
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as tmp_file:
476
+ tmp_file.write(uploaded_file.getvalue())
477
+ tmp_path = tmp_file.name
478
+
479
+ detector = st.session_state.detectors.get('video')
480
+
481
+ if detector and detector.model:
482
+ result = detector.detect(tmp_path)
483
+
484
+ if result['success']:
485
+ prediction = result['prediction']
486
+ confidence = result['confidence'] * 100
487
+
488
+ if prediction == 'Fake':
489
+ st.error(f"❌ DEEPFAKE VIDEO DETECTED\n\nConfidence: {confidence:.1f}%")
490
+ else:
491
+ st.success(f"✅ AUTHENTIC VIDEO\n\nConfidence: {confidence:.1f}%")
492
+
493
+ st.json({
494
+ "Prediction": prediction,
495
+ "Confidence": f"{confidence:.2f}%",
496
+ "Frames Analyzed": result.get('frames_analyzed', 'N/A'),
497
+ "Real Probability": f"{result['real_probability']*100:.2f}%",
498
+ "Fake Probability": f"{result['fake_probability']*100:.2f}%"
499
+ })
500
+
501
+ # Save to history
502
+ if st.session_state.current_user:
503
+ from auth.database import DatabaseManager
504
+ db = DatabaseManager()
505
+
506
+ db.add_detection_record(
507
+ user_id=st.session_state.current_user['id'],
508
+ file_name=uploaded_file.name,
509
+ file_type='video',
510
+ prediction=prediction,
511
+ confidence=result['confidence'],
512
+ is_fake=(prediction == 'Fake')
513
+ )
514
+ else:
515
+ st.error(f"Detection failed: {result.get('error', 'Unknown error')}")
516
+
517
+ os.unlink(tmp_path)
518
+
519
+ else:
520
+ st.info("👆 Upload a video to begin analysis")
521
+
522
+
523
+ def audio_detection_page():
524
+ """Audio deepfake detection page"""
525
+ st.markdown("<h1 class='main-header'>🎵 Audio DeepFake Detection</h1>", unsafe_allow_html=True)
526
+
527
+ initialize_detectors()
528
+
529
+ uploaded_file = st.file_uploader(
530
+ "Upload an audio file to analyze",
531
+ type=['wav', 'mp3', 'flac'],
532
+ help="Supported formats: WAV, MP3, FLAC"
533
+ )
534
+
535
+ if uploaded_file:
536
+ st.audio(uploaded_file)
537
+
538
+ if st.button("🔍 Analyze Audio", type="primary"):
539
+ with st.spinner("Analyzing audio spectrogram..."):
540
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file:
541
+ tmp_file.write(uploaded_file.getvalue())
542
+ tmp_path = tmp_file.name
543
+
544
+ detector = st.session_state.detectors.get('audio')
545
+
546
+ if detector and detector.model:
547
+ result = detector.detect(tmp_path)
548
+
549
+ if result['success']:
550
+ prediction = result['prediction']
551
+ confidence = result['confidence'] * 100
552
+
553
+ if prediction == 'Fake':
554
+ st.error(f"❌ SYNTHETIC AUDIO DETECTED\n\nConfidence: {confidence:.1f}%")
555
+ else:
556
+ st.success(f"✅ AUTHENTIC AUDIO\n\nConfidence: {confidence:.1f}%")
557
+
558
+ st.json({
559
+ "Prediction": prediction,
560
+ "Confidence": f"{confidence:.2f}%",
561
+ "Duration": f"{result.get('duration_analyzed', 'N/A')} seconds",
562
+ "Sample Rate": f"{result.get('sample_rate', 'N/A')} Hz"
563
+ })
564
+
565
+ # Save to history
566
+ if st.session_state.current_user:
567
+ from auth.database import DatabaseManager
568
+ db = DatabaseManager()
569
+
570
+ db.add_detection_record(
571
+ user_id=st.session_state.current_user['id'],
572
+ file_name=uploaded_file.name,
573
+ file_type='audio',
574
+ prediction=prediction,
575
+ confidence=result['confidence'],
576
+ is_fake=(prediction == 'Fake')
577
+ )
578
+ else:
579
+ st.error(f"Detection failed: {result.get('error', 'Unknown error')}")
580
+
581
+ os.unlink(tmp_path)
582
+
583
+ else:
584
+ st.info("👆 Upload audio to begin analysis")
585
+
586
+
587
+ def webcam_detection_page():
588
+ """Webcam detection page"""
589
+ st.markdown("<h1 class='main-header'>📹 Real-Time Webcam Detection</h1>", unsafe_allow_html=True)
590
+
591
+ initialize_detectors()
592
+
593
+ st.info("📹 Choose detection mode below")
594
+
595
+ # Mode selection
596
+ detection_mode = st.radio(
597
+ "Select Detection Mode:",
598
+ ["📸 Photo Capture", "🎥 Live Video Streaming"],
599
+ horizontal=True
600
+ )
601
+
602
+ if detection_mode == "📸 Photo Capture":
603
+ st.success("**Photo Mode**: Take a single picture for analysis")
604
+
605
+ # Use Streamlit's native webcam input
606
+ img_file_buffer = st.camera_input("Take a picture")
607
+
608
+ if img_file_buffer is not None:
609
+ with st.spinner("Analyzing frame..."):
610
+ try:
611
+ from PIL import Image
612
+ import numpy as np
613
+ import cv2
614
+
615
+ image = Image.open(img_file_buffer)
616
+ image_np = np.array(image)
617
+ image_bgr = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
618
+
619
+ if 'detectors' in st.session_state and 'image' in st.session_state.detectors:
620
+ detector = st.session_state.detectors['image']
621
+ result = detector.detect(image_bgr)
622
+
623
+ if result['success']:
624
+ col1, col2 = st.columns(2)
625
+
626
+ with col1:
627
+ st.image(image_np, caption="Captured Frame", width=400)
628
+
629
+ with col2:
630
+ if result['is_fake']:
631
+ st.error(f"**⚠ FAKE Detected**")
632
+ st.metric("Fake Probability", f"{result['fake_probability']*100:.1f}%")
633
+ else:
634
+ st.success(f"**✓ REAL Verified**")
635
+ st.metric("Real Probability", f"{result['real_probability']*100:.1f}%")
636
+
637
+ st.metric("Confidence", f"{result['confidence']*100:.1f}%")
638
+ st.caption(f"Raw Score: {result.get('raw_score', 'N/A')}")
639
+ if 'reliability' in result:
640
+ rel_badge = "🔴" if result['reliability'] == 'low' else "🟡" if result['reliability'] == 'medium' else "🟢"
641
+ st.caption(f"Reliability: {rel_badge} {result['reliability'].upper()}")
642
+
643
+ from auth.database import DatabaseManager
644
+ db = DatabaseManager()
645
+ db.add_detection_record(
646
+ user_id=st.session_state.current_user['id'],
647
+ file_name="webcam_capture.jpg",
648
+ file_type="webcam",
649
+ prediction=result['prediction'],
650
+ confidence=result['confidence'],
651
+ is_fake=result['is_fake']
652
+ )
653
+ else:
654
+ st.error(f"Detection failed: {result.get('error', 'Unknown error')}")
655
+ else:
656
+ st.error("Detector not initialized. Please refresh the page.")
657
+ except Exception as e:
658
+ st.error(f"Error processing frame: {str(e)}")
659
+
660
+ elif detection_mode == "🎥 Live Video Streaming":
661
+ st.success("**Live Mode**: Automatic real-time streaming with instant analysis!")
662
+
663
+ # Try enhanced webcam streaming first
664
+ try:
665
+ from utils.webcam_streamer import run_enhanced_webcam_detection
666
+
667
+ # Get detector
668
+ detector = None
669
+ if 'detectors' in st.session_state and 'image' in st.session_state.detectors:
670
+ detector = st.session_state.detectors['image']
671
+
672
+ run_enhanced_webcam_detection(detector=detector)
673
+
674
+ except Exception as e:
675
+ st.warning(f"⚠️ Enhanced streaming unavailable: {e}")
676
+ st.info("Falling back to standard auto-capture mode...")
677
+
678
+ # Fallback to existing auto-capture code
679
+ import time
680
+ from PIL import Image
681
+ import numpy as np
682
+ import cv2
683
+
684
+ # Initialize detector
685
+ if 'detectors' not in st.session_state:
686
+ initialize_detectors()
687
+
688
+ # State management
689
+ if 'auto_stream_active' not in st.session_state:
690
+ st.session_state.auto_stream_active = False
691
+ if 'session_start_time' not in st.session_state:
692
+ st.session_state.session_start_time = 0
693
+
694
+ # Control panel
695
+ start_col, stop_col = st.columns([3, 1])
696
+
697
+ with start_col:
698
+ start_btn = st.button("🎬 START AUTO LIVE STREAMING", type="primary", use_container_width=True, disabled=st.session_state.auto_stream_active)
699
+
700
+ with stop_col:
701
+ stop_btn = st.button("⏹️ STOP", use_container_width=True, disabled=not st.session_state.auto_stream_active)
702
+
703
+ # Handle start
704
+ if start_btn:
705
+ st.session_state.auto_stream_active = True
706
+ st.session_state.session_start_time = int(time.time())
707
+ st.session_state.last_capture = 0
708
+ st.session_state.frame_num = 0
709
+ st.rerun()
710
+
711
+ # Handle stop
712
+ if stop_btn:
713
+ st.session_state.auto_stream_active = False
714
+ st.info("⏹️ Streaming stopped")
715
+ st.rerun()
716
+
717
+ # Main auto-streaming logic
718
+ if st.session_state.auto_stream_active:
719
+ # Calculate elapsed time
720
+ elapsed = int(time.time() - st.session_state.session_start_time)
721
+ current_time = time.time()
722
+
723
+ # Status bar
724
+ status_col = st.columns([3, 1])[0]
725
+ with status_col:
726
+ st.info(f"🔴 LIVE | Running for {elapsed}s | Auto-capturing every 2 seconds")
727
+
728
+ # Check if it's time to capture (every 2 seconds)
729
+ should_capture = (current_time - st.session_state.get('last_capture', 0)) >= 2.0
730
+
731
+ if should_capture:
732
+ # Update last capture time
733
+ st.session_state.last_capture = current_time
734
+ st.session_state.frame_num += 1
735
+
736
+ # Capture container
737
+ capture_container = st.container()
738
+
739
+ with capture_container:
740
+ # Use camera input but hide it visually while keeping functionality
741
+ st.markdown("### 📹 Live Frame Capture")
742
+
743
+ # Create a unique key for each auto-capture
744
+ cam_key = f"auto_capture_{st.session_state.frame_num}"
745
+
746
+ # Hide the ugly "Take a photo" text with custom CSS
747
+ st.markdown("""
748
+ <style>
749
+ div[data-testid="stFileUploader"] {display: none;}
750
+ button[kind="fileInput"] {display: none;}
751
+ </style>
752
+ """, unsafe_allow_html=True)
753
+
754
+ # Create hidden camera input
755
+ cam_placeholder = st.empty()
756
+ with cam_placeholder:
757
+ cam_buffer = st.camera_input(
758
+ label="", # Empty label!
759
+ key=cam_key,
760
+ label_visibility="hidden" # Hide completely!
761
+ )
762
+
763
+ # Auto-trigger camera after 0.5 seconds
764
+ if cam_buffer is None:
765
+ time.sleep(0.5)
766
+ st.rerun()
767
+
768
+ if cam_buffer is not None:
769
+ # Process this frame IMMEDIATELY
770
+ image = Image.open(cam_buffer)
771
+ image_np = np.array(image)
772
+ image_bgr = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
773
+
774
+ # Display frame
775
+ st.image(image_np, caption=f"📹 Auto-Captured Frame #{st.session_state.frame_num} at {time.strftime('%H:%M:%S')}", width=700)
776
+
777
+ # RUN DETECTION INSTANTLY
778
+ if 'detectors' in st.session_state and 'image' in st.session_state.detectors:
779
+ detector = st.session_state.detectors['image']
780
+ result = detector.detect(image_bgr)
781
+
782
+ if result['success']:
783
+ # SHOW RESULTS IMMEDIATELY
784
+ result_cols = st.columns([2, 1])
785
+
786
+ with result_cols[0]:
787
+ if result['is_fake']:
788
+ st.error(f"""
789
+ **⚠️ FAKE DETECTED!**
790
+
791
+ Confidence: **{result['confidence']*100:.1f}%**
792
+ Fake Probability: {result['fake_probability']*100:.1f}%
793
+ """)
794
+ else:
795
+ st.success(f"""
796
+ **✓ REAL VERIFIED!**
797
+
798
+ Confidence: **{result['confidence']*100:.1f}%**
799
+ Real Probability: {result['real_probability']*100:.1f}%
800
+ """)
801
+
802
+ with result_cols[1]:
803
+ st.metric("Confidence", f"{result['confidence']*100:.1f}%")
804
+
805
+ if 'reliability' in result:
806
+ rel_badge = "🔴" if result['reliability'] == 'low' else "🟡" if result['reliability'] == 'medium' else "🟢"
807
+ st.caption(f"{rel_badge} {result['reliability'].upper()}")
808
+
809
+ # Auto-save to history
810
+ try:
811
+ from auth.database import DatabaseManager
812
+ db = DatabaseManager()
813
+ db.add_detection_record(
814
+ user_id=st.session_state.current_user['id'],
815
+ file_name=f"auto_live_{st.session_state.frame_num}_{int(current_time)}.jpg",
816
+ file_type="webcam_auto_stream",
817
+ prediction=result['prediction'],
818
+ confidence=result['confidence'],
819
+ is_fake=result['is_fake']
820
+ )
821
+ except Exception as save_err:
822
+ pass
823
+
824
+ # Countdown to next capture
825
+ st.info(f"⏱️ Next auto-capture in 2 seconds... (Frame #{st.session_state.frame_num})")
826
+
827
+ # Trigger next frame after delay
828
+ time.sleep(2.0)
829
+ st.rerun()
830
+ else:
831
+ st.warning(f"⚠️ Detection failed: {result.get('error', 'Unknown error')}")
832
+ time.sleep(2.0)
833
+ st.rerun()
834
+ else:
835
+ st.error("❌ Detector not initialized - please refresh the page")
836
+ time.sleep(2.0)
837
+ st.rerun()
838
+ else:
839
+ # First time activation - waiting for camera
840
+ st.info("📷 **Camera is activating...** Please allow camera access in your browser, then click the capture button that appears.")
841
+ time.sleep(1.0)
842
+ st.rerun()
843
+ else:
844
+ # Waiting between captures
845
+ countdown = int(2.0 - (current_time - st.session_state.get('last_capture', 0)))
846
+ st.info(f"⏳ Next auto-capture in {countdown} second(s)...")
847
+ time.sleep(0.5)
848
+ st.rerun()
849
+
850
+ else:
851
+ # Not streaming
852
+ st.info("👆 Click '🎬 START AUTO LIVE STREAMING' to begin automatic real-time detection")
853
+
854
+ st.markdown("""
855
+ ---
856
+ #### ✨ What Happens When You Start:
857
+
858
+ 1. **Camera activates automatically** (browser will ask for permission)
859
+ 2. **Auto-captures every 2 seconds** - NO manual clicking needed!
860
+ 3. **Instant AI analysis** on every captured frame
861
+ 4. **Results display immediately** - Fake/Real with confidence %
862
+ 5. **Auto-saves to history** - Every detection logged
863
+ 6. **Continuous operation** until you click Stop
864
+
865
+ **Just position your face and watch it work!**
866
+ """)
867
+
868
+ with st.expander("ℹ️ How to use webcam detection"):
869
+ st.markdown("""
870
+ ### Instructions
871
+
872
+ 1. Click "Allow" when prompted for camera permissions
873
+ 2. Position your face in the frame
874
+ 3. Click "Take a picture"
875
+ 4. Wait for the AI analysis
876
+ 5. View results instantly
877
+
878
+ ### Tips for Best Results
879
+
880
+ - Good lighting (face should be well-lit)
881
+ - Face the camera directly
882
+ - Remove glasses/masks if possible
883
+ - Keep still while capturing
884
+ - High resolution preferred
885
+
886
+ ### Understanding Results
887
+
888
+ - **🟢 High Reliability** (>70% confidence): Trust the prediction
889
+ - **🟡 Medium Reliability** (55-70%): Consider other evidence
890
+ - **🔴 Low Reliability** (<55%): Model is uncertain, manual review recommended
891
+
892
+ **Note**: This uses the same AI model as image detection, trained on available DeepFake datasets.
893
+ """)
894
+
895
+
896
+ def social_media_page():
897
+ """Social media detection page"""
898
+ st.markdown("<h1 class='main-header'>🌐 Social Media Verification</h1>", unsafe_allow_html=True)
899
+
900
+ st.info("🔗 Paste a social media URL to analyze the media content")
901
+
902
+ # Initialize detector if not already done
903
+ if 'social_detector' not in st.session_state:
904
+ try:
905
+ image_detector = st.session_state.detectors.get('image')
906
+ video_detector = st.session_state.detectors.get('video')
907
+ audio_detector = st.session_state.detectors.get('audio')
908
+
909
+ st.session_state.social_detector = SocialMediaDeepFakeDetector(
910
+ image_detector=image_detector,
911
+ video_detector=video_detector,
912
+ audio_detector=audio_detector
913
+ )
914
+ except Exception as e:
915
+ st.error(f"Error initializing social media detector: {e}")
916
+ return
917
+
918
+ url = st.text_input("Social Media URL", placeholder="https://twitter.com/... or https://youtube.com/... or https://facebook.com/...")
919
+
920
+ if url:
921
+ if st.button("🔍 Analyze URL", type="primary"):
922
+ with st.spinner("Downloading and analyzing media from URL..."):
923
+ try:
924
+ # Detect platform
925
+ from urllib.parse import urlparse
926
+ parsed = urlparse(url)
927
+ domain = parsed.netloc.lower()
928
+
929
+ platform_name = "Direct URL"
930
+ platform_emoji = "🔗"
931
+
932
+ if 'youtube.com' in domain or 'youtu.be' in domain:
933
+ platform_name = "YouTube"
934
+ platform_emoji = "📺"
935
+ result = st.session_state.social_detector.verify_youtube_video(url)
936
+ elif 'twitter.com' in domain or 'x.com' in domain:
937
+ platform_name = "Twitter/X"
938
+ platform_emoji = "🐦"
939
+ result = st.session_state.social_detector.verify_twitter_media(url)
940
+ elif 'instagram.com' in domain:
941
+ platform_name = "Instagram"
942
+ platform_emoji = "📸"
943
+ result = st.session_state.social_detector.verify_instagram_media(url)
944
+ elif 'facebook.com' in domain or 'fb.com' in domain or 'fb.watch' in domain:
945
+ platform_name = "Facebook"
946
+ platform_emoji = "📘"
947
+ result = st.session_state.social_detector.verify_facebook_media(url)
948
+ elif 'github.com' in domain:
949
+ platform_name = "GitHub"
950
+ platform_emoji = "🐙"
951
+ result = st.session_state.social_detector.verify_github_content(url)
952
+ elif 'whatsapp.com' in domain:
953
+ platform_name = "WhatsApp"
954
+ platform_emoji = "📱"
955
+ result = st.session_state.social_detector.verify_whatsapp_media(url)
956
+ else:
957
+ result = st.session_state.social_detector.detect_from_url(url)
958
+
959
+ # Display results
960
+ if result.get('success'):
961
+ st.success(f"✅ Analysis Complete - {platform_emoji} {platform_name}")
962
+
963
+ # Show prediction
964
+ is_fake = result.get('is_fake', False)
965
+ confidence = result.get('confidence', 0) * 100
966
+
967
+ if is_fake:
968
+ st.error(f"🚨 **FAKE** Detected (Confidence: {confidence:.1f}%)")
969
+ else:
970
+ st.success(f"✓ **REAL** Content (Confidence: {confidence:.1f}%)")
971
+
972
+ # Show additional info
973
+ col1, col2, col3 = st.columns(3)
974
+ with col1:
975
+ st.metric("Platform", f"{platform_emoji} {platform_name}")
976
+ with col2:
977
+ st.metric("Media Type", result.get('media_type', 'Unknown'))
978
+ with col3:
979
+ reliability = "High" if confidence > 70 else "Medium" if confidence > 55 else "Low"
980
+ st.metric("Reliability", reliability)
981
+
982
+ # Save to history if user is logged in
983
+ if st.session_state.current_user:
984
+ from auth.database import DetectionHistoryManager
985
+ db_manager = DetectionHistoryManager()
986
+ db_manager.add_detection(
987
+ username=st.session_state.current_user,
988
+ file_name=url[:50] + "...",
989
+ file_type=result.get('media_type', 'unknown'),
990
+ prediction="Fake" if is_fake else "Real",
991
+ confidence=confidence / 100,
992
+ source_url=url
993
+ )
994
+ st.success("✓ Result saved to your detection history")
995
+
996
+ else:
997
+ error_msg = result.get('error', 'Unknown error')
998
+ st.error(f"❌ Analysis Failed: {error_msg}")
999
+
1000
+ # Provide specific troubleshooting based on error
1001
+ if 'download' in error_msg.lower() or 'failed to download' in error_msg.lower():
1002
+ st.warning("""
1003
+ **💡 Download Failed - Common Causes:**
1004
+
1005
+ 1. **Private Content** - Account/post is private (not public)
1006
+ 2. **Invalid URL** - URL is broken or doesn't exist
1007
+ 3. **Network Issue** - Check internet connection
1008
+ 4. **Rate Limited** - Too many requests, wait and try again
1009
+ 5. **Platform Blocking** - Site is blocking automated access
1010
+
1011
+ **✅ Quick Fixes:**
1012
+ - ✓ Verify URL opens in browser
1013
+ - ✓ Ensure account is PUBLIC
1014
+ - ✓ Try a different URL
1015
+ - ✓ Check console output for detailed error
1016
+ - ✓ See TROUBLESHOOTING_DOWNLOAD_ERRORS.md for help
1017
+ """)
1018
+ elif 'timeout' in error_msg.lower():
1019
+ st.warning("""
1020
+ **⏱️ Request Timed Out**
1021
+
1022
+ The server took too long to respond. This can happen with:
1023
+ - Slow internet connection
1024
+ - Overloaded servers
1025
+ - Very large files
1026
+
1027
+ **Try:**
1028
+ - Check your internet speed
1029
+ - Wait a moment and try again
1030
+ - Use a different URL
1031
+ """)
1032
+ elif '403' in error_msg or 'forbidden' in error_msg.lower():
1033
+ st.warning("""
1034
+ **🚫 Access Denied (403 Forbidden)**
1035
+
1036
+ The platform is blocking access. This happens with:
1037
+ - Private accounts
1038
+ - Region-locked content
1039
+ - Automated access detection
1040
+
1041
+ **Solutions:**
1042
+ - Use public content only
1043
+ - Configure API keys for better access
1044
+ - Try from different network
1045
+ """)
1046
+ elif '404' in error_msg or 'not found' in error_msg.lower():
1047
+ st.warning("""
1048
+ **❌ Content Not Found (404)**
1049
+
1050
+ The URL doesn't point to valid content:
1051
+ - Post/video may be deleted
1052
+ - URL has typo
1053
+ - Content was never there
1054
+
1055
+ **Check:**
1056
+ - Open URL in browser first
1057
+ - Verify username/post ID
1058
+ - Use "Share" button to copy correct URL
1059
+ """)
1060
+ else:
1061
+ st.warning("""
1062
+ **💡 Troubleshooting Tips:**
1063
+
1064
+ 1. Check that the URL is correct and complete
1065
+ 2. Verify the content is publicly accessible
1066
+ 3. Try opening the URL in your browser first
1067
+ 4. Check the console output for detailed error messages
1068
+ 5. Review TROUBLESHOOTING_DOWNLOAD_ERRORS.md for solutions
1069
+
1070
+ **Test with known working URLs:**
1071
+ - YouTube: https://youtube.com/watch?v=dQw4w9WgXcQ
1072
+ - GitHub: https://github.com/octocat/Spoon-Knife/blob/main/LICENSE
1073
+ """)
1074
+
1075
+ except Exception as e:
1076
+ error_details = str(e)
1077
+ st.error(f"❌ Error during analysis: {error_details}")
1078
+
1079
+ # Show helpful debugging info
1080
+ with st.expander("🔍 View Detailed Error Information"):
1081
+ import traceback
1082
+ st.code(traceback.format_exc())
1083
+
1084
+ st.markdown("""
1085
+ **What to do next:**
1086
+
1087
+ 1. Copy this error message
1088
+ 2. Check console output for more details
1089
+ 3. Verify your URL is correct and public
1090
+ 4. Try a different URL to test
1091
+ 5. See TROUBLESHOOTING_DOWNLOAD_ERRORS.md for solutions
1092
+ """)
1093
+
1094
+ # Information section
1095
+ st.markdown("---")
1096
+ st.subheader("ℹ️ Platform Support")
1097
+
1098
+ col1, col2, col3 = st.columns(3)
1099
+
1100
+ with col1:
1101
+ st.markdown("""
1102
+ ### 🐦 Twitter/X
1103
+ - Tweet images
1104
+ - Tweet videos
1105
+ - GIFs
1106
+
1107
+ **API Status**: Optional
1108
+ """)
1109
+
1110
+ with col2:
1111
+ st.markdown("""
1112
+ ### 📺 YouTube
1113
+ - Regular videos
1114
+ - Shorts
1115
+ - Video links
1116
+
1117
+ **API Status**: Optional (uses yt-dlp)
1118
+ """)
1119
+
1120
+ with col3:
1121
+ st.markdown("""
1122
+ ### 📸 Instagram
1123
+ - Posts
1124
+ - Images
1125
+ - Videos
1126
+ - Reels
1127
+
1128
+ **API Status**: Optional
1129
+ """)
1130
+
1131
+ col4, col5, col6 = st.columns(3)
1132
+
1133
+ with col4:
1134
+ st.markdown("""
1135
+ ### 📘 Facebook
1136
+ - Post images
1137
+ - Videos
1138
+ - Public content
1139
+
1140
+ **API Status**: Optional
1141
+ """)
1142
+
1143
+ with col5:
1144
+ st.markdown("""
1145
+ ### 🐙 GitHub
1146
+ - Repository images
1147
+ - Media files
1148
+ - Release assets
1149
+
1150
+ **API Status**: Optional
1151
+ """)
1152
+
1153
+ with col6:
1154
+ st.markdown("""
1155
+ ### 📱 WhatsApp
1156
+ - Media links
1157
+ - Shared content
1158
+
1159
+ **API Status**: Optional
1160
+ """)
1161
+
1162
+ # API Configuration Guide
1163
+ with st.expander("🔑 Configure API Keys (Optional but Recommended)"):
1164
+ st.markdown("""
1165
+ ### API Configuration Guide
1166
+
1167
+ For best results, configure the following API keys:
1168
+
1169
+ #### 1. Twitter/X API
1170
+ 1. Go to [Twitter Developer Portal](https://developer.twitter.com/)
1171
+ 2. Create a project and app
1172
+ 3. Generate Bearer Token
1173
+ 4. Set environment variable: `TWITTER_API_KEY`
1174
+
1175
+ #### 2. YouTube Data API
1176
+ 1. Go to [Google Cloud Console](https://console.cloud.google.com/)
1177
+ 2. Create a new project
1178
+ 3. Enable YouTube Data API v3
1179
+ 4. Create API Key
1180
+ 5. Set environment variable: `YOUTUBE_API_KEY`
1181
+
1182
+ #### 3. Instagram Basic Display API
1183
+ 1. Go to [Facebook Developers](https://developers.facebook.com/)
1184
+ 2. Create an app
1185
+ 3. Add Instagram Basic Display product
1186
+ 4. Generate Access Token
1187
+ 5. Set environment variable: `INSTAGRAM_TOKEN`
1188
+
1189
+ ---
1190
+
1191
+ ### Using Environment Variables
1192
+
1193
+ **Option 1: Create `.env` file** (Recommended)
1194
+
1195
+ Create a file named `.env` in the project root:
1196
+
1197
+ ```env
1198
+ TWITTER_API_KEY=your_twitter_key_here
1199
+ YOUTUBE_API_KEY=your_youtube_key_here
1200
+ INSTAGRAM_TOKEN=your_instagram_token_here
1201
+ ```
1202
+
1203
+ **Option 2: Set via Command Line**
1204
+
1205
+ Windows PowerShell:
1206
+ ```powershell
1207
+ $env:TWITTER_API_KEY="your_key_here"
1208
+ $env:YOUTUBE_API_KEY="your_key_here"
1209
+ $env:INSTAGRAM_TOKEN="your_token_here"
1210
+ ```
1211
+
1212
+ Linux/Mac:
1213
+ ```bash
1214
+ export TWITTER_API_KEY="your_key_here"
1215
+ export YOUTUBE_API_KEY="your_key_here"
1216
+ export INSTAGRAM_TOKEN="your_token_here"
1217
+ ```
1218
+
1219
+ **Note**: The system can work without API keys using direct download methods,
1220
+ but some platforms may have restrictions. API keys provide more reliable access.
1221
+ """)
1222
+
1223
+ with st.expander("ℹ️ How to use social media detection"):
1224
+ st.markdown("""
1225
+ ### Instructions
1226
+
1227
+ 1. **Copy URL**: Copy the link from Twitter, YouTube, or Instagram
1228
+ 2. **Paste URL**: Paste it in the text field above
1229
+ 3. **Analyze**: Click "Analyze URL" button
1230
+ 4. **Wait**: System will download and analyze the content
1231
+ 5. **Results**: View the AI analysis results
1232
+
1233
+ ### Tips for Best Results
1234
+
1235
+ - Use public posts (not private accounts)
1236
+ - Ensure the URL points directly to a post with media
1237
+ - For Twitter, use tweets that contain images/videos
1238
+ - For YouTube, any public video URL works
1239
+ - For Instagram, use public posts only
1240
+
1241
+ ### Understanding Results
1242
+
1243
+ - **🟢 High Reliability** (>70% confidence): Trust the prediction
1244
+ - **🟡 Medium Reliability** (55-70%): Consider other evidence
1245
+ - **🔴 Low Reliability** (<55%): Model is uncertain, manual review recommended
1246
+
1247
+ ### Supported Formats
1248
+
1249
+ **Images**: JPG, PNG, BMP, GIF
1250
+ **Videos**: MP4, AVI, MOV, MKV, WebM
1251
+ **Audio**: WAV, MP3, FLAC (extracted from videos)
1252
+ """)
1253
+
1254
+
1255
+ def history_page():
1256
+ """Detection history page"""
1257
+ st.markdown("<h1 class='main-header'>📊 Detection History</h1>", unsafe_allow_html=True)
1258
+
1259
+ if not st.session_state.current_user:
1260
+ st.warning("Please login to view your detection history")
1261
+ return
1262
+
1263
+ from auth.database import DatabaseManager
1264
+ db = DatabaseManager()
1265
+
1266
+ # Get user history
1267
+ history = db.get_user_detection_history(st.session_state.current_user['id'], limit=100)
1268
+
1269
+ # Display statistics FIRST (even if no history)
1270
+ stats = db.get_detection_statistics(st.session_state.current_user['id'])
1271
+
1272
+ if stats:
1273
+ st.subheader("📈 Your Analytics Dashboard")
1274
+
1275
+ col1, col2, col3, col4 = st.columns(4)
1276
+
1277
+ with col1:
1278
+ st.metric("Total Detections", stats['total_detections'])
1279
+
1280
+ with col2:
1281
+ st.metric("Fake Detected", stats['fake_count'])
1282
+
1283
+ with col3:
1284
+ st.metric("Real Verified", stats['real_count'])
1285
+
1286
+ with col4:
1287
+ st.metric("Avg Confidence", f"{stats['average_confidence']*100:.1f}%")
1288
+
1289
+ # Show breakdown by file type
1290
+ if stats.get('by_file_type'):
1291
+ st.write("**Detections by Type:**")
1292
+ type_cols = st.columns(len(stats['by_file_type']))
1293
+ for i, (file_type, count) in enumerate(stats['by_file_type'].items()):
1294
+ with type_cols[i]:
1295
+ icon = "🖼️" if file_type == 'image' else "🎥" if file_type == 'video' else "🎤"
1296
+ st.metric(label=icon, value=count, delta=file_type.title())
1297
+
1298
+ st.divider()
1299
+
1300
+ # Search and filter
1301
+ search_term = st.text_input("🔍 Search by filename", "")
1302
+
1303
+ if search_term and history:
1304
+ history = db.search_detections(st.session_state.current_user['id'], search_term)
1305
+
1306
+ # Display as table
1307
+ if history:
1308
+ st.write(f"**{len(history)} detections found**")
1309
+
1310
+ for record in history:
1311
+ with st.expander(f"{record['file_name']} - {record['prediction']} ({record['created_at']})"):
1312
+ col1, col2 = st.columns(2)
1313
+
1314
+ with col1:
1315
+ st.write(f"**File Type:** {record['file_type']}")
1316
+ st.write(f"**Prediction:** {record['prediction']}")
1317
+ st.write(f"**Confidence:** {record['confidence']*100:.1f}%")
1318
+
1319
+ with col2:
1320
+ status = "❌ Fake" if record['is_fake'] else "✅ Real"
1321
+ st.write(f"**Status:** {status}")
1322
+ st.write(f"**Date:** {record['created_at']}")
1323
+
1324
+ # Add download button if file exists
1325
+ if record.get('file_path') and os.path.exists(record['file_path']):
1326
+ with open(record['file_path'], 'rb') as f:
1327
+ st.download_button(
1328
+ label="📥 Download File",
1329
+ data=f.read(),
1330
+ file_name=record['file_name'],
1331
+ mime="application/octet-stream"
1332
+ )
1333
+ else:
1334
+ st.info("📭 No detections found. Start analyzing media to build your history!")
1335
+ st.markdown("""
1336
+ **How to get started:**
1337
+ 1. Go to **Image Detection** and upload an image
1338
+ 2. Or try **Video Detection** with a video file
1339
+ 3. Or analyze **Audio** files
1340
+ 4. Your detection history will appear here automatically
1341
+ """)
1342
+
1343
+
1344
+ def reports_page():
1345
+ """Reports download page"""
1346
+ st.markdown("<h1 class='main-header'>📥 Download Reports</h1>", unsafe_allow_html=True)
1347
+
1348
+ if not st.session_state.current_user:
1349
+ st.warning("Please login to access your reports")
1350
+ return
1351
+
1352
+ from auth.database import DatabaseManager
1353
+ db = DatabaseManager()
1354
+
1355
+ reports = db.get_user_reports(st.session_state.current_user['id'])
1356
+
1357
+ if reports:
1358
+ st.write(f"**{len(reports)} reports available**")
1359
+
1360
+ for report in reports:
1361
+ col1, col2, col3 = st.columns([3, 2, 1])
1362
+
1363
+ with col1:
1364
+ st.write(f"**{report['generated_at']}**")
1365
+
1366
+ with col2:
1367
+ st.write(f"Detection #{report['detection_id']}")
1368
+
1369
+ with col3:
1370
+ if os.path.exists(report['report_path']):
1371
+ with open(report['report_path'], 'rb') as f:
1372
+ st.download_button(
1373
+ label="📥 Download",
1374
+ data=f.read(),
1375
+ file_name=f"report_{report['id']}.pdf",
1376
+ mime="application/pdf"
1377
+ )
1378
+ else:
1379
+ st.write("File not found")
1380
+ else:
1381
+ st.info("No reports generated yet. Generate reports from the detection pages.")
1382
+
1383
+
1384
+ def main():
1385
+ """Main application entry point"""
1386
+
1387
+ if not st.session_state.authenticated:
1388
+ login_page()
1389
+ else:
1390
+ main_app()
1391
+
1392
+
1393
+ if __name__ == "__main__":
1394
+ main()
requirements-minimal.txt ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Memory-Optimized Requirements for Deployment
2
+ # Uses lighter alternatives and defers heavy imports
3
+
4
+ # Core - Lightweight base
5
+ numpy==1.23.5
6
+ pandas==1.5.3
7
+ Pillow==9.5.0
8
+ scipy==1.10.1
9
+
10
+ # OpenCV - Headless version (smaller)
11
+ opencv-python-headless==4.7.0.72
12
+
13
+ # Scikit-learn (needed but smaller than TF)
14
+ scikit-learn==1.2.2
15
+
16
+ # Streamlit
17
+ streamlit==1.28.0
18
+
19
+ # Visualization (lightweight)
20
+ matplotlib==3.7.1
21
+ seaborn==0.12.2
22
+ plotly==5.15.0
23
+
24
+ # Utilities
25
+ bcrypt==4.0.1
26
+ tqdm==4.65.0
27
+ python-dotenv==1.0.0
28
+
29
+ # Image handling
30
+ imageio==2.28.1
31
+
32
+ # Video processing (deferred import)
33
+ ffmpeg-python==0.2.0
34
+
35
+ # PDF generation
36
+ reportlab==4.0.0
37
+
38
+ # Security
39
+ PyJWT==2.6.0
40
+
41
+ # NOTE: TensorFlow/Keras installed separately with memory limits
42
+ # tensorflow==2.12.0 # Install during runtime, not build