# app.py - Antigravity Shield v4.2 JURY (Visual Edition Optimized) # -*- coding: utf-8 -*- import numpy as np import librosa import librosa.display import matplotlib.pyplot as plt import noisereduce as nr import soundfile as sf import hashlib import os import gradio as gr # ========================================== # 1. OUTILS DE TRAITEMENT # ========================================== class AudioManipulator: def charger_audio(self, path): return librosa.load(path, sr=44100) def reduire_bruit(self, y, sr): return nr.reduce_noise(y=y, sr=sr, prop_decrease=0.8) # ========================================== # 2. LE BOUCLIER IA v4.2 JURY # ========================================== class AuthenticMusicShield: def __init__(self): print("🚀 Lancement du Bouclier v4.2 (Expert Radio & Jury)...") self.ia = None # Ne pas charger le modèle au démarrage def load_model(self): if self.ia is None: try: from transformers import pipeline self.ia = pipeline("audio-classification", model="MIT/ast-finetuned-audioset-10-10-0.4593") print("✅ Modèle IA chargé.") except Exception as e: print(f"⚠️ Échec du chargement du modèle IA : {e}") self.ia = None def get_sha256(self, path): with open(path, "rb") as f: return hashlib.sha256(f.read()).hexdigest() def generer_spectrogramme(self, y, sr): plt.figure(figsize=(10, 4)) S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128) S_dB = librosa.power_to_db(S, ref=np.max) librosa.display.specshow(S_dB, sr=sr, x_axis='time', y_axis='mel', cmap='magma') plt.colorbar(format='%+2.0f dB') plt.title('Empreinte Spectrale (Texture)') plt.tight_layout() plot_path = "spectrum.png" plt.savefig(plot_path) plt.close() return plot_path def analyser_expert(self, path): if path is None: return None, "En attente...", None try: # Charger le modèle IA seulement si nécessaire self.load_model() file_name = os.path.basename(path) file_hash = self.get_sha256(path) y, sr = librosa.load(path, sr=44100) y_denoised = nr.reduce_noise(y=y, sr=sr) # Analyse Jitter & SID pitches, _ = librosa.piptrack(y=y, sr=sr) jitter = np.std(pitches[pitches > 0]) / 1000 if np.any(pitches > 0) else 0 stft = np.abs(librosa.stft(y_denoised)) score_sid = 95.0 if np.mean(stft[-1]) > 0.0003 else 15.0 # Analyse IA top_label = "Inconnu" score_ia = 0 if self.ia: res_ia = self.ia(path) top_label = res_ia[0]['label'] score_ia = res_ia[0]['score'] * 100 # Détection du type de source is_radio_speech = any(tag in top_label for tag in ["Speech", "Conversation", "Hum", "Radio"]) # ========================================== # LOGIQUE DE DÉCISION v4.2 JURY # ========================================== if score_sid > 80: verdict = "✅ AUTHENTIQUE CERTIFIÉ (SID)" note = "Badge SID détecté. Intégrité et provenance garanties." elif is_radio_speech: if 0.01 < jitter < 1.5: verdict = "✅ AUTHENTIQUE (Humain/Radio)" note = f"Source réelle confirmée par IA ({top_label})." else: verdict = "🔴 DEEPFAKE DÉTECTÉ" note = "Anomalie physique extrême sur voix humaine." elif "Music" in top_label or "Singing" in top_label or "Inconnu" in top_label: if 0.12 < jitter < 0.85: verdict = "✅ AUTHENTIQUE (Artiste)" note = "Vibration humaine naturelle validée." else: verdict = "🔴 AI COVER / DEEPFAKE DÉTECTÉ" note = f"Instabilité ou perfection artificielle. Jitter: {jitter:.4f}" else: verdict = "⚠️ ANALYSE INCONCLUSIVE" note = "Signal non identifié par le bouclier." # Génération du spectrogramme spec_img = self.generer_spectrogramme(y, sr) # Rapport Formaté pour le JURY report = f"\n{'='*45}\n🛡️ RAPPORT D'EXPERTISE v4.2 JURY\n{'='*45}\n" report += f" 📂 NOM FICHIER : {file_name}\n" report += f" 🔑 ID SHA-256 : {file_hash[:16]}...\n" report += f" 🎙️ SOURCE IA : {top_label} ({score_ia:.1f}%)\n" report += f" 🧬 INDICE VIE : {jitter:.4f}\n" report += f"{'-'*45}\n" report += f" >>> VERDICT : {verdict}\n" report += f" >>> NOTE : {note}\n{'='*45}\n" return spec_img, report, {"Verdict": verdict, "Jitter": round(jitter, 4), "SID": score_sid} except Exception as e: return None, f"Erreur : {str(e)}", None # --- Interface Gradio --- shield = AuthenticMusicShield() with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown("# 🛡️ Antigravity Shield v4.2 PRO (Jury Edition Optimized)") with gr.Row(): with gr.Column(): audio_input = gr.Audio(type="filepath", label="Audio Input") run_btn = gr.Button("🔍 ANALYSER L'AUTHENTICITÉ", variant="primary") with gr.Column(): image_output = gr.Image(label="Spectrogramme (Preuve Visuelle)") report_output = gr.Textbox(label="Rapport Officiel", lines=10) metrics_output = gr.Json(label="Métriques Techniques") run_btn.click( fn=shield.analyser_expert, inputs=audio_input, outputs=[image_output, report_output, metrics_output] ) # SSR désactivé pour réduire la RAM et éviter crash 137 demo.launch(ssr_mode=False)