Deepfake Authenticator commited on
Commit
7f580a0
Β·
1 Parent(s): 03f204c

fix: AV_MISMATCH shows as DEEPFAKE (red) not yellow warning

Browse files

- Frontend: AV_MISMATCH uses same red color + gpp_bad icon as AI_VOICE
- Verdict label shows 'DEEPFAKE (AV MISMATCH)'
- Backend: AV_MISMATCH overrides visual REAL verdict to FAKE
- Both AI_VOICE and AV_MISMATCH count as audio_fake in final decision

backend/detector.py CHANGED
@@ -446,22 +446,25 @@ class ReportGeneratorAgent:
446
  audio_prob = 0.0
447
  if audio and audio.get("available"):
448
  audio_prob = audio.get("fake_probability", 0.0)
449
- audio_fake = audio.get("result") == "AI_VOICE"
 
450
 
451
  # Final verdict: visual is primary, audio can upgrade OR downgrade
452
  if audio and audio.get("available"):
453
- # Both agree β†’ high confidence
454
  if visual_fake and audio_fake:
455
  is_fake = True
456
  elif not visual_fake and not audio_fake:
457
  is_fake = False
458
- # Disagreement β†’ visual wins but audio nudges the score
459
  elif visual_fake and not audio_fake:
460
  # Audio says real β€” only keep FAKE if visual is strong
461
  is_fake = prob >= (threshold + 0.05)
462
  else:
463
- # Visual says real but audio says AI β€” flag as suspicious
464
- is_fake = audio_prob >= 0.75 # only override if audio is very confident
 
 
 
 
465
  else:
466
  is_fake = visual_fake
467
 
 
446
  audio_prob = 0.0
447
  if audio and audio.get("available"):
448
  audio_prob = audio.get("fake_probability", 0.0)
449
+ # AV_MISMATCH counts as fake β€” face-swap with dubbed audio
450
+ audio_fake = audio.get("result") in ("AI_VOICE", "AV_MISMATCH")
451
 
452
  # Final verdict: visual is primary, audio can upgrade OR downgrade
453
  if audio and audio.get("available"):
 
454
  if visual_fake and audio_fake:
455
  is_fake = True
456
  elif not visual_fake and not audio_fake:
457
  is_fake = False
 
458
  elif visual_fake and not audio_fake:
459
  # Audio says real β€” only keep FAKE if visual is strong
460
  is_fake = prob >= (threshold + 0.05)
461
  else:
462
+ # Visual says real but audio says AI/mismatch
463
+ # AV_MISMATCH is a very strong signal β€” override visual
464
+ if audio.get("result") == "AV_MISMATCH":
465
+ is_fake = True # face-swap confirmed by mismatch
466
+ else:
467
+ is_fake = audio_prob >= 0.75
468
  else:
469
  is_fake = visual_fake
470
 
frontend-vanilla/index.html CHANGED
@@ -1219,14 +1219,15 @@ function renderTimeline(frames) {
1219
  function renderAudio(audio) {
1220
  const isAI = audio.result === 'AI_VOICE';
1221
  const isMismatch = audio.result === 'AV_MISMATCH';
1222
- const color = isMismatch ? '#ffdd65' : (isAI ? '#ffb4ab' : '#00ff9c');
 
1223
 
1224
  const icon = document.getElementById('audioIcon');
1225
- icon.textContent = isMismatch ? 'warning' : (isAI ? 'smart_toy' : 'record_voice_over');
1226
  icon.style.color = color;
1227
 
1228
  const verdict = document.getElementById('audioVerdict');
1229
- verdict.textContent = isMismatch ? '⚠ AV MISMATCH' : (audio.result || '--');
1230
  verdict.style.color = color;
1231
 
1232
  document.getElementById('audioConfidence').textContent =
@@ -1247,9 +1248,9 @@ function renderAudio(audio) {
1247
  if (audio.details && audio.details.length) {
1248
  detailsEl.innerHTML = audio.details.map(d => `
1249
  <div class="flex items-start gap-3 p-3 bg-surface-container-low/50 border border-outline-variant/30 rounded-DEFAULT"
1250
- style="${isMismatch ? 'border-color:rgba(255,221,101,0.3);background:rgba(255,221,101,0.05);' : ''}">
1251
- <span class="material-symbols-outlined text-[16px] mt-0.5" style="color:${color};">${isMismatch ? 'warning' : 'chevron_right'}</span>
1252
- <span class="font-data-mono text-data-mono text-sm" style="color:${isMismatch ? '#ffdd65cc' : '#b9cbbc'};">${escHtml(d)}</span>
1253
  </div>`).join('');
1254
  } else {
1255
  detailsEl.innerHTML = '';
 
1219
  function renderAudio(audio) {
1220
  const isAI = audio.result === 'AI_VOICE';
1221
  const isMismatch = audio.result === 'AV_MISMATCH';
1222
+ const isFakeAudio = isAI || isMismatch; // both mean FAKE
1223
+ const color = isFakeAudio ? '#ffb4ab' : '#00ff9c';
1224
 
1225
  const icon = document.getElementById('audioIcon');
1226
+ icon.textContent = isFakeAudio ? 'gpp_bad' : 'record_voice_over';
1227
  icon.style.color = color;
1228
 
1229
  const verdict = document.getElementById('audioVerdict');
1230
+ verdict.textContent = isMismatch ? 'DEEPFAKE (AV MISMATCH)' : (isAI ? 'AI_VOICE' : 'HUMAN_VOICE');
1231
  verdict.style.color = color;
1232
 
1233
  document.getElementById('audioConfidence').textContent =
 
1248
  if (audio.details && audio.details.length) {
1249
  detailsEl.innerHTML = audio.details.map(d => `
1250
  <div class="flex items-start gap-3 p-3 bg-surface-container-low/50 border border-outline-variant/30 rounded-DEFAULT"
1251
+ style="${isFakeAudio ? 'border-color:rgba(255,180,171,0.3);background:rgba(255,180,171,0.04);' : ''}">
1252
+ <span class="material-symbols-outlined text-[16px] mt-0.5" style="color:${color};">chevron_right</span>
1253
+ <span class="font-data-mono text-data-mono text-sm" style="color:#b9cbbc;">${escHtml(d)}</span>
1254
  </div>`).join('');
1255
  } else {
1256
  detailsEl.innerHTML = '';