import os import time import requests import gradio as gr HTML_HEADER = """

Demo of Audio Deepfake Detection

To learn more, visit our website: https://dataspike.io/

Visitor Count
""" def get_verdict_html(score, verdict): """Generate HTML verdict block based on score and verdict.""" # Determine color and label based on verdict if verdict == "deepfake_likely": color = "#E74C3C" label = "Deepfake" description = "This audio shows strong signs of manipulation (likely a deepfake)." elif verdict == "deepfake_unlikely": color = "#2ECC71" label = "Not Deepfake" description = "This audio appears to be genuine." else: color = "#F39C12" label = "Uncertain" description = "The analysis is inconclusive. Further verification may be needed." # Convert score to percentage percentage = int(score * 100) html = f"""

{label}

{description}

Deepfake Probability

{percentage}%

""" return html def api_status(job_id, poll_interval=1.0, max_attempts=120): """Poll API for job status until completion.""" url = f"https://api.dataspike.io/api/v4/deepfake/job/{job_id}" headers = {"ds-api-token": os.getenv("API_KEY")} for attempt in range(max_attempts): try: resp = requests.get(url, headers=headers, timeout=10) result = resp.json() status = result.get("status", "") if status in ("completed", "done", "error", "failed"): return result time.sleep(poll_interval) except Exception as e: # If polling fails, return error return { "status": "error", "errors": [f"Polling failed: {str(e)}"] } # If max attempts reached return { "status": "error", "errors": ["Timeout: processing took too long"] } def check_audio_deepfake(file_path): """Check if audio is a deepfake using the API.""" if not file_path: return """

No Audio File

Please submit an audio file first and then click the button 'Check Audio!'

""" url = "https://api.dataspike.io/api/v4/deepfake/audio/analyze" headers = {"ds-api-token": os.getenv("API_KEY")} try: # Step 1: Submit audio file and get job_id with open(file_path, "rb") as f: files = {"file": f} response = requests.post(url, headers=headers, files=files) job_response = response.json() # Check if we got a job_id if "id" not in job_response: return """

Upload Failed

Failed to upload audio file. Please try again.

""" job_id = job_response["id"] # Step 2: Poll for results deepfake_result = api_status(job_id) # Check verdict and show appropriate message if deepfake_result.get("status") in ("completed", "done"): score = deepfake_result.get("score", 0) verdict = deepfake_result.get("verdict", "unknown") return get_verdict_html(score, verdict) elif deepfake_result.get("status") in ("error", "failed"): return """

Detection Failed

The audio quality is not acceptable or the file is corrupted. Please try with a different audio file.

""" else: return "" except Exception as e: return f"""

Error

API request failed: {str(e)}

""" tabs_css = """ /* Style all Gradio tab buttons */ button[role="tab"] { font-size: 14px !important; font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; padding: 12px 24px !important; margin: 0 6px !important; background-color: #0B0F19 !important; color: #F3F4F6 !important; border-radius: 8px !important; border: 1px solid #1a1a1a !important; box-shadow: none !important; transition: all 0.2s ease !important; } /* Style selected tab button */ button[role="tab"].selected { background-color: #635bff !important; color: white !important; box-shadow: 0 0 6px rgba(99, 91, 255, 0.5) !important; } /* Inactive tab style */ button[role="tab"]:not(.selected) { font-size: 14px !important; font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; padding: 12px 24px !important; margin: 0 6px !important; background-color: #9D2C53 !important; color: #F3F4F6 !important; border-radius: 8px !important; border: 1px solid #1a1a1a !important; box-shadow: none !important; transition: all 0.2s ease !important; } /* Optional: hover effect */ button[role="tab"]:hover { background-color: #1a1a2b !important; color: white !important; } """ with gr.Blocks(theme=gr.themes.Soft(), css=tabs_css) as Demo: header_box = gr.HTML(HTML_HEADER) with gr.Row(equal_height=True): with gr.Column(scale=1): input_audio_path = gr.Audio( label="Input Audio", type="filepath", sources=["upload", "microphone"] ) check_button = gr.Button("Check Audio!", variant="primary") with gr.Column(scale=1): verdict_box = gr.HTML("") check_button.click( check_audio_deepfake, inputs=input_audio_path, outputs=verdict_box, ) if __name__ == "__main__": Demo.launch()