import gradio as gr import torch import torchaudio import numpy as np from transformers import AutoProcessor, SeamlessM4Tv2Model from datetime import datetime import time import threading import queue import sounddevice as sd class ARISTranslator: def __init__(self, model_name: str = "facebook/seamless-m4t-v2-large"): self.processor = AutoProcessor.from_pretrained(model_name) self.model = SeamlessM4Tv2Model.from_pretrained(model_name) self.sample_rate = self.model.config.sampling_rate self.audio_queue = queue.Queue() self.is_recording = False self.language_codes = { "English (US)": "eng", "Spanish (ES)": "spa", "French (FR)": "fra", "German (DE)": "deu", "Italian (IT)": "ita", "Portuguese (BR)": "por", "Russian (RU)": "rus", "Chinese (CN)": "cmn", "Japanese (JP)": "jpn", "Korean (KR)": "kor", "Hindi (IN)": "hin", "Arabic (AR)": "ara" } def start_recording(self): self.is_recording = True threading.Thread(target=self._record_audio).start() def stop_recording(self): self.is_recording = False def _record_audio(self): with sd.InputStream(channels=1, samplerate=16000, callback=self._audio_callback): while self.is_recording: time.sleep(0.1) def _audio_callback(self, indata, frames, time, status): self.audio_queue.put(indata.copy()) def translate_realtime(self, audio_chunk, src_lang: str, tgt_lang: str) -> tuple[int, np.ndarray]: try: inputs = self.processor(audios=audio_chunk, return_tensors="pt") audio_array = self.model.generate(**inputs, tgt_lang=self.language_codes[tgt_lang])[0].cpu().numpy().squeeze() return self.sample_rate, audio_array except Exception as e: raise gr.Error(f"Translation failed: {str(e)}") def translate_text(self, text: str, src_lang: str, tgt_lang: str) -> tuple[int, np.ndarray]: try: inputs = self.processor(text=text, src_lang=self.language_codes[src_lang], return_tensors="pt") audio_array = self.model.generate(**inputs, tgt_lang=self.language_codes[tgt_lang])[0].cpu().numpy().squeeze() return self.sample_rate, audio_array except Exception as e: raise gr.Error(f"Translation failed: {str(e)}") css = """ /* Cores e temas da interface */ :root { --primary: #00ffff; --secondary: #0066cc; --accent: #ff3366; --background: #000000; --text: #ffffff; } #aris-interface { background-color: var(--background); background-image: radial-gradient(circle at 20% 20%, rgba(0, 102, 204, 0.1) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(0, 255, 255, 0.1) 0%, transparent 50%); min-height: 100vh; font-family: 'Courier New', monospace; padding: 20px; } .title-container { text-align: center; color: var(--primary); margin-bottom: 30px; position: relative; } .title-container h1 { font-size: 3em; letter-spacing: 10px; margin: 0; text-shadow: 0 0 10px var(--primary); } .title-container h3 { font-size: 1.2em; letter-spacing: 3px; opacity: 0.8; margin: 5px 0; } /* Sistema de anéis central */ #status-ring { width: 400px; height: 400px; border: 4px solid var(--primary); border-radius: 50%; margin: 20px auto; position: relative; animation: pulse 2s infinite; display: flex; align-items: center; justify-content: center; background: radial-gradient(circle at center, rgba(0, 255, 255, 0.1) 0%, transparent 70%), conic-gradient(from 0deg, transparent 0%, rgba(0, 255, 255, 0.1) 50%, transparent 100%); } #outer-ring-decoration { position: absolute; width: 420px; height: 420px; border-radius: 50%; border: 1px solid rgba(0, 255, 255, 0.3); animation: rotate 20s linear infinite; } #inner-ring { width: 300px; height: 300px; border: 2px solid var(--primary); border-radius: 50%; display: flex; align-items: center; justify-content: center; position: relative; } #core { width: 200px; height: 200px; border: 3px solid var(--primary); border-radius: 50%; background-color: rgba(0, 0, 0, 0.8); display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--primary); text-align: center; padding: 15px; position: relative; box-shadow: 0 0 20px rgba(0, 255, 255, 0.2); } /* Animações */ @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(0, 255, 255, 0.4); } 70% { box-shadow: 0 0 0 20px rgba(0, 255, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(0, 255, 255, 0); } } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Elementos da interface */ .aris-controls { background: rgba(0, 0, 0, 0.7); border: 2px solid var(--primary); border-radius: 10px; padding: 20px; margin: 20px 0; box-shadow: 0 0 15px rgba(0, 255, 255, 0.1); } .aris-textbox { background-color: rgba(0, 0, 0, 0.8) !important; border: 2px solid var(--primary) !important; color: var(--primary) !important; font-family: 'Courier New', monospace !important; border-radius: 5px !important; padding: 10px !important; } .aris-button { background-color: transparent !important; border: 2px solid var(--primary) !important; color: var(--primary) !important; font-family: 'Courier New', monospace !important; text-transform: uppercase !important; letter-spacing: 2px !important; padding: 12px 24px !important; border-radius: 5px !important; transition: all 0.3s ease !important; } .aris-button:hover { background-color: rgba(0, 255, 255, 0.1) !important; box-shadow: 0 0 15px rgba(0, 255, 255, 0.3) !important; transform: translateY(-2px) !important; } .status-box { background-color: rgba(0, 0, 0, 0.8) !important; border: 2px solid var(--primary) !important; color: var(--primary) !important; padding: 15px !important; border-radius: 5px !important; margin: 5px !important; text-align: center !important; text-transform: uppercase !important; letter-spacing: 1px !important; transition: all 0.3s ease !important; position: relative; overflow: hidden; } .status-box::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 2px; background: linear-gradient(90deg, transparent, var(--primary)); animation: scan-line 2s linear infinite; } @keyframes scan-line { 0% { left: -100%; } 100% { left: 100%; } } .mode-indicator { position: absolute; top: 10px; right: 10px; padding: 5px 10px; background-color: var(--accent); color: var(--text); border-radius: 3px; font-size: 0.8em; letter-spacing: 1px; } .stats-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 20px; } .stat-item { background: rgba(0, 0, 0, 0.7); border: 1px solid var(--primary); padding: 10px; border-radius: 5px; text-align: center; color: var(--primary); } .language-pair-display { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 10px 0; color: var(--primary); font-size: 1.2em; } .language-pair-display::before, .language-pair-display::after { content: '⟨'; color: var(--secondary); } """ def create_interface(): translator = ARISTranslator() def update_status(): return ( f"A.R.I.S. CORE v2.0.0\n" f"Time: {datetime.now().strftime('%H:%M:%S')}\n" f"Neural Engine: ACTIVE\n" f"Translation Matrix: OPERATIONAL" ) def start_realtime_translation(src_lang, tgt_lang): translator.start_recording() return "Real-time translation active..." def stop_realtime_translation(): translator.stop_recording() return "Translation stopped." with gr.Blocks(css=css, title="A.R.I.S. - Advanced Real-time Interpretation System") as demo: gr.HTML('''