From 80e0197743b8c66d9128be271e2d39ac056e1217 Mon Sep 17 00:00:00 2001 From: Abdelkouddous LHACHIMI Date: Thu, 11 Dec 2025 23:31:20 +0100 Subject: [PATCH] Vesion Fonctionnelle --- check_video_authenticity.bat | 4 + check_video_authenticity.py | 167 +++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 check_video_authenticity.bat create mode 100644 check_video_authenticity.py diff --git a/check_video_authenticity.bat b/check_video_authenticity.bat new file mode 100644 index 0000000..bbe4c3b --- /dev/null +++ b/check_video_authenticity.bat @@ -0,0 +1,4 @@ +@echo off +call .venv\Scripts\activate.bat +python "%~n0.py" %* + diff --git a/check_video_authenticity.py b/check_video_authenticity.py new file mode 100644 index 0000000..1c1f1e0 --- /dev/null +++ b/check_video_authenticity.py @@ -0,0 +1,167 @@ +import os +import sys +import requests +import json +import tkinter as tk +from tkinter import filedialog +from rich.console import Console +from rich.progress import Progress, SpinnerColumn, TextColumn +from rich.panel import Panel +from rich.table import Table +from rich import print + +# --- CONFIGURATION --- +# TODO: Replace with your actual Sightengine API credentials +API_USER = "1020608869" +API_SECRET = "M7WF4mAXwSs2gs869LC9PecvYCBQyBSz" + +API_ENDPOINT = "https://api.sightengine.com/1.0/video/check-sync.json" + +console = Console() + +def select_video_file(): + """Opens a file dialog to select a video file using Tkinter.""" + root = tk.Tk() + root.withdraw() # Hide the main window + + file_path = filedialog.askopenfilename( + title="Select a video file to analyze", + filetypes=[ + ("Video Files", "*.mp4 *.mov *.avi *.mkv *.webm *.flv *.wmv"), + ("All Files", "*.*") + ] + ) + return file_path + +def check_video(file_path): + """Checks the video using Sightengine API.""" + if not os.path.exists(file_path): + console.print(f"[bold red]Error:[/bold red] File not found: {file_path}") + return + + params = { + 'models': 'genai', + 'api_user': API_USER, + 'api_secret': API_SECRET + } + + files = { + 'media': open(file_path, 'rb') + } + + try: + with Progress( + SpinnerColumn(), + TextColumn("[progress.description]{task.description}"), + transient=True + ) as progress: + progress.add_task(description="Uploading and analyzing video...", total=None) + response = requests.post(API_ENDPOINT, files=files, data=params) + + response_data = json.loads(response.text) + + if response_data['status'] == 'success': + display_results(file_path, response_data) + else: + error_msg = response_data.get('error', {}).get('message', 'Unknown error') + console.print(f"[bold red]API Error:[/bold red] {error_msg}") + + except Exception as e: + console.print(f"[bold red]System Error:[/bold red] {e}") + finally: + files['media'].close() + +def display_results(file_path, data): + """Displays the analysis results using Rich.""" + + # Calculate aggregate score (average of all frames for simplicity in this demo) + frames = data.get('data', {}).get('frames', []) + if not frames: + console.print("[yellow]No frames analyzed.[/yellow]") + return + + total_ai_score = 0 + count = 0 + + # Create detailed table for frames (showing first few or high scores) + table = Table(title="Frame Analysis (Sample)") + table.add_column("Time (s)", justify="right", style="cyan", no_wrap=True) + table.add_column("AI Probability", justify="right", style="magenta") + table.add_column("Verdict", justify="center") + + max_ai_score = 0 + + for frame in frames: + ai_score = frame.get('type', {}).get('ai_generated', 0) + total_ai_score += ai_score + count += 1 + if ai_score > max_ai_score: + max_ai_score = ai_score + + # Add to table if it's a significant score or just to show some data + # Showing only frames with > 0.1 score or every 10th frame to keep it clean if many frames + if ai_score > 0.5 or count % 10 == 1: + verdict = "[red]FAKE[/red]" if ai_score > 0.8 else ("[yellow]SUSPICIOUS[/yellow]" if ai_score > 0.4 else "[green]REAL[/green]") + # Assuming 1 frame per second roughly? API documentation says 'position' is likely offset + position = frame.get('info', {}).get('position', 0) + # Provide string formatting for score + table.add_row(str(position), f"{ai_score:.2%}", verdict) + + avg_ai_score = total_ai_score / count if count else 0 + + # Final Verdict Panel + final_verdict = "UNCERTAIN" + color = "yellow" + if max_ai_score > 0.85: + final_verdict = "AI GENERATED" + color = "red" + elif max_ai_score < 0.2: + final_verdict = "AUTHENTIC" + color = "green" + + request_info = data.get('request', {}) + req_id = request_info.get('id', 'N/A') + ops = request_info.get('operations', 0) + + panel_content = f""" + [bold]File:[/bold] {os.path.basename(file_path)} + [bold]Request ID:[/bold] {req_id} + [bold]Operations Cost:[/bold] {ops} + + [bold]Max AI Score:[/bold] {max_ai_score:.2%} + [bold]Average AI Score:[/bold] {avg_ai_score:.2%} + + [bold size=20 style={color}]VERDICT: {final_verdict}[/bold size=20 style={color}] + """ + + console.print(Panel(panel_content, title="Analysis Result", expand=False)) + console.print(table) + +def main(): + if API_USER == "CHANGE_ME" or API_SECRET == "CHANGE_ME": + console.print("[bold red]Configuration Error:[/bold red] Please set API_USER and API_SECRET in the script.") + return + + if len(sys.argv) > 1: + video_path = sys.argv[1] + else: + console.print(Panel( + "[bold green]AI Video Authenticity Check[/bold green]\n\n" + "This script analyzes a video to detect AI-generated content using Sightengine.\n" + "Please select a video file in the window that opens...", + title="Welcome", + border_style="green" + )) + video_path = select_video_file() + if not video_path: + console.print("[yellow]No file selected. Exiting.[/yellow]") + return + + console.print(f"[blue]Analyzing:[/blue] {video_path}") + check_video(video_path) + +if __name__ == "__main__": + try: + main() + finally: + input("Press Enter to continue...")