AbdulWahab14 commited on
Commit
6e72c7b
Β·
verified Β·
1 Parent(s): d3bd666

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -21
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # app.py β€” DeepFake AI Forensics (Light Royal Blue Theme)
2
  import os
3
  import subprocess
4
  import tempfile
@@ -30,24 +30,55 @@ model.to(device)
30
  print(f"[+] Model loaded on {device}")
31
 
32
  # ==========================================
33
- # 2. AUDIO / VIDEO PREPROCESSING
34
  # ==========================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  def convert_to_audio(file_path):
36
  ext = os.path.splitext(file_path)[1].lower().lstrip('.')
37
- if ext in ["wav", "mp3", "flac", "m4a", "ogg", "aac", "wma"]:
38
- return file_path
39
- if ext in ["mp4", "mkv", "avi", "mov", "webm", "flv"]:
40
- print("[+] Video detected β†’ extracting audio via ffmpeg...")
41
- out = tempfile.mktemp(suffix=".wav")
42
- cmd = [
43
- "ffmpeg", "-i", file_path,
44
- "-vn", "-acodec", "pcm_s16le",
45
- "-ar", "16000", "-ac", "1",
46
- out, "-y"
47
- ]
48
- subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
49
- return out
50
- raise ValueError(f"Unsupported file format: {ext}")
 
 
 
 
 
 
51
 
52
  def load_audio(path):
53
  audio, _ = librosa.load(path, sr=16000)
@@ -82,19 +113,19 @@ def analyze(file_path):
82
  if ai_score < 0.35:
83
  verdict = "HUMAN VOICE"
84
  level = "LOW RISK"
85
- color = "#059669" # emerald-600
86
  icon = "πŸ§‘"
87
  glow = "rgba(5,150,105,0.18)"
88
  elif ai_score < 0.65:
89
  verdict = "UNCERTAIN / MIXED"
90
  level = "MEDIUM RISK"
91
- color = "#d97706" # amber-600
92
  icon = "⚠️"
93
  glow = "rgba(217,119,6,0.18)"
94
  else:
95
  verdict = "AI / SYNTHETIC VOICE"
96
  level = "HIGH RISK"
97
- color = "#dc2626" # red-600
98
  icon = "πŸ€–"
99
  glow = "rgba(220,38,38,0.18)"
100
 
@@ -262,7 +293,12 @@ def detect_audio(audio_file):
262
  return plot_path, result_html, f"{percentage:.1f}%", color, ""
263
 
264
  except Exception as e:
265
- return None, f"<div style='color:#dc2626;padding:30px;'>❌ Analysis Error: {str(e)}</div>", "Error", "#dc2626", ""
 
 
 
 
 
266
 
267
 
268
  def detect_video(video_file):
@@ -347,7 +383,12 @@ def detect_video(video_file):
347
  return plot_path, result_html, f"{percentage:.1f}%", color, ""
348
 
349
  except Exception as e:
350
- return None, f"<div style='color:#dc2626;padding:30px;'>❌ Analysis Error: {str(e)}</div>", "Error", "#dc2626", ""
 
 
 
 
 
351
 
352
 
353
  # ==========================================
@@ -497,11 +538,15 @@ def build_ui():
497
  <span class="format-badge">M4A</span>
498
  <span class="format-badge">FLAC</span>
499
  <span class="format-badge">OGG</span>
 
500
  </div>
501
  <div style="font-size: 0.8em; color: #475569; margin-bottom: 16px; display: flex; align-items: center; gap: 6px;">
502
  <span style="font-size: 1.2em;">πŸ“Ž</span>
503
  <span>Maximum file size: <strong style="color: #1e40af;">50 MB</strong></span>
504
  </div>
 
 
 
505
  """)
506
 
507
  audio_input = gr.Audio(
 
1
+ # app.py β€” DeepFake AI Forensics (WhatsApp Voice Note Fix)
2
  import os
3
  import subprocess
4
  import tempfile
 
30
  print(f"[+] Model loaded on {device}")
31
 
32
  # ==========================================
33
+ # 2. AUDIO / VIDEO PREPROCESSING (ROBUST)
34
  # ==========================================
35
+ def normalize_audio(file_path):
36
+ """
37
+ Converts ANY audio/video to standard 16kHz mono WAV via FFmpeg.
38
+ This fixes WhatsApp voice notes (Opus/OGG disguised as MP3),
39
+ corrupt headers, and exotic codecs.
40
+ """
41
+ out = tempfile.mktemp(suffix=".wav")
42
+ cmd = [
43
+ "ffmpeg", "-y",
44
+ "-i", file_path,
45
+ "-vn", # no video
46
+ "-acodec", "pcm_s16le", # 16-bit PCM
47
+ "-ar", "16000", # 16 kHz
48
+ "-ac", "1", # mono
49
+ "-af", "loudnorm=I=-16:TP=-1.5:LRA=11", # normalize levels
50
+ out
51
+ ]
52
+ result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
53
+
54
+ if result.returncode != 0:
55
+ err = result.stderr.decode('utf-8', errors='ignore')[:200]
56
+ raise RuntimeError(f"FFmpeg could not decode this file. It may be corrupted or use an unsupported codec.\nDetails: {err}")
57
+
58
+ return out
59
+
60
  def convert_to_audio(file_path):
61
  ext = os.path.splitext(file_path)[1].lower().lstrip('.')
62
+
63
+ # Supported audio formats (including WhatsApp Opus)
64
+ audio_exts = ["wav", "mp3", "flac", "m4a", "ogg", "opus", "aac", "wma", "oga"]
65
+ # Supported video formats
66
+ video_exts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "3gp"]
67
+
68
+ if ext in audio_exts:
69
+ print(f"[+] Audio detected ({ext}) β†’ normalizing via ffmpeg...")
70
+ return normalize_audio(file_path)
71
+
72
+ if ext in video_exts:
73
+ print("[+] Video detected β†’ extracting & normalizing audio via ffmpeg...")
74
+ return normalize_audio(file_path)
75
+
76
+ # Unknown extension? Try ffmpeg anyway as last resort
77
+ print(f"[+] Unknown format ({ext}) β†’ attempting ffmpeg decode...")
78
+ try:
79
+ return normalize_audio(file_path)
80
+ except Exception:
81
+ raise ValueError(f"Unsupported file format: {ext}. Please upload MP3, WAV, M4A, OGG, OPUS, or MP4.")
82
 
83
  def load_audio(path):
84
  audio, _ = librosa.load(path, sr=16000)
 
113
  if ai_score < 0.35:
114
  verdict = "HUMAN VOICE"
115
  level = "LOW RISK"
116
+ color = "#059669"
117
  icon = "πŸ§‘"
118
  glow = "rgba(5,150,105,0.18)"
119
  elif ai_score < 0.65:
120
  verdict = "UNCERTAIN / MIXED"
121
  level = "MEDIUM RISK"
122
+ color = "#d97706"
123
  icon = "⚠️"
124
  glow = "rgba(217,119,6,0.18)"
125
  else:
126
  verdict = "AI / SYNTHETIC VOICE"
127
  level = "HIGH RISK"
128
+ color = "#dc2626"
129
  icon = "πŸ€–"
130
  glow = "rgba(220,38,38,0.18)"
131
 
 
293
  return plot_path, result_html, f"{percentage:.1f}%", color, ""
294
 
295
  except Exception as e:
296
+ err_msg = str(e)
297
+ if "FFmpeg" in err_msg:
298
+ err_html = f"<div style='color:#dc2626;padding:30px;'><strong>❌ File Decode Error</strong><br><br>{err_msg}<br><br><span style='color:#475569;font-size:0.9em;'>WhatsApp voice notes are often .opus or .ogg files disguised as .mp3. Try renaming the file to .ogg or exporting it differently.</span></div>"
299
+ else:
300
+ err_html = f"<div style='color:#dc2626;padding:30px;'>❌ Analysis Error: {err_msg}</div>"
301
+ return None, err_html, "Error", "#dc2626", ""
302
 
303
 
304
  def detect_video(video_file):
 
383
  return plot_path, result_html, f"{percentage:.1f}%", color, ""
384
 
385
  except Exception as e:
386
+ err_msg = str(e)
387
+ if "FFmpeg" in err_msg:
388
+ err_html = f"<div style='color:#dc2626;padding:30px;'><strong>❌ File Decode Error</strong><br><br>{err_msg}</div>"
389
+ else:
390
+ err_html = f"<div style='color:#dc2626;padding:30px;'>❌ Analysis Error: {err_msg}</div>"
391
+ return None, err_html, "Error", "#dc2626", ""
392
 
393
 
394
  # ==========================================
 
538
  <span class="format-badge">M4A</span>
539
  <span class="format-badge">FLAC</span>
540
  <span class="format-badge">OGG</span>
541
+ <span class="format-badge">OPUS</span>
542
  </div>
543
  <div style="font-size: 0.8em; color: #475569; margin-bottom: 16px; display: flex; align-items: center; gap: 6px;">
544
  <span style="font-size: 1.2em;">πŸ“Ž</span>
545
  <span>Maximum file size: <strong style="color: #1e40af;">50 MB</strong></span>
546
  </div>
547
+ <div style="font-size: 0.75em; color: #94a3b8; background: #eff6ff; border-radius: 8px; padding: 10px 12px; margin-bottom: 12px; line-height: 1.5;">
548
+ πŸ’‘ <strong>WhatsApp voice notes:</strong> If your file fails to upload, try renaming it from <code>.mp3</code> to <code>.ogg</code> or <code>.opus</code> before uploading.
549
+ </div>
550
  """)
551
 
552
  audio_input = gr.Audio(