""" Ses Deşifre Pro - Türkçe Ses-Metin Dönüştürme Hugging Face Spaces için profesyonel arayüz. Gradio 6.x uyumlu + Gemini AI Özet Desteği. """ import gradio as gr from faster_whisper import WhisperModel import tempfile import time import requests # ==================== CONFIGURATION ==================== MODEL_SIZE = "medium" # Options: tiny, base, small, medium, large-v3 # ======================================================= # Load model once at startup print("🔄 Model yükleniyor... (Bu işlem birkaç dakika sürebilir)") model = WhisperModel( MODEL_SIZE, device="cpu", compute_type="int8" ) print("✅ Model yüklendi!") def summarize_with_gemini(text: str, api_key: str, custom_prompt: str = "") -> str: """ Summarize text using Google Gemini API. API key is not stored - used only for this single request. """ if not api_key or not api_key.strip(): return "⚠️ Gemini API anahtarı girilmedi." if not text or text.strip() == "" or text.startswith("⚠️") or text.startswith("❌"): return "⚠️ Önce bir transkripsiyon oluşturun." # Extract only the transcription text (remove stats section) clean_text = text.split("───────────────────────────────────")[0].strip() if not clean_text: return "⚠️ Özetlenecek metin bulunamadı." # Build the prompt base_instruction = "Aşağıdaki Türkçe metni analiz et ve özetle." if custom_prompt and custom_prompt.strip(): full_prompt = f"{custom_prompt.strip()}\n\nMetin:\n{clean_text}" else: full_prompt = f"{base_instruction}\n\nMetin:\n{clean_text}" # Gemini API endpoint url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={api_key}" headers = {"Content-Type": "application/json"} payload = { "contents": [{"parts": [{"text": full_prompt}]}], "generationConfig": { "temperature": 0.7, "maxOutputTokens": 2048 } } try: response = requests.post(url, headers=headers, json=payload, timeout=60) if response.status_code == 200: result = response.json() if "candidates" in result and len(result["candidates"]) > 0: candidate = result["candidates"][0] if "content" in candidate and "parts" in candidate["content"]: parts = candidate["content"]["parts"] if len(parts) > 0 and "text" in parts[0]: return parts[0]["text"] return "❌ Gemini yanıtı beklenmedik formatta." elif response.status_code == 400: return "❌ Geçersiz istek. API anahtarını kontrol edin." elif response.status_code in [401, 403]: return "❌ API anahtarı geçersiz veya yetkisiz." elif response.status_code == 429: return "❌ API kullanım limiti aşıldı. Lütfen bekleyin." else: return f"❌ Gemini API hatası: {response.status_code}" except requests.exceptions.Timeout: return "❌ Gemini API zaman aşımı. Tekrar deneyin." except requests.exceptions.RequestException as e: return f"❌ Bağlantı hatası: {str(e)}" except Exception as e: return f"❌ Beklenmeyen hata: {str(e)}" def transcribe(audio_path: str): """ Transcribe audio file to Turkish text. Returns: (transcription_text, download_file_path) """ if audio_path is None: return "⚠️ Lütfen bir ses dosyası yükleyin veya mikrofonla kayıt yapın.", None try: start_time = time.time() # Transcribe with Turkish language segments, info = model.transcribe( audio_path, language="tr", beam_size=5 ) # Collect all segments full_text = [] for segment in segments: full_text.append(segment.text) result = " ".join(full_text).strip() elapsed = time.time() - start_time if not result: return "⚠️ Ses dosyasında konuşma algılanamadı. Lütfen daha net bir kayıt deneyin.", None # Create downloadable TXT file txt_file = tempfile.NamedTemporaryFile( mode='w', suffix='.txt', delete=False, encoding='utf-8' ) txt_file.write(result) txt_file.close() # Format display text with stats display_text = f"""{result} ─────────────────────────────────── 📊 İstatistikler • Algılanan dil: Türkçe • Ses süresi: {info.duration:.1f} saniye • İşlem süresi: {elapsed:.1f} saniye • Hız: {info.duration/elapsed:.1f}x gerçek zamanlı ───────────────────────────────────""" return display_text, txt_file.name except Exception as e: error_msg = str(e) if "ffmpeg" in error_msg.lower(): return "❌ Ses dosyası işlenemedi. Desteklenen formatlar: MP3, WAV, M4A, OGG, FLAC", None return f"❌ Bir hata oluştu: {error_msg}", None # Build Interface (Gradio 6.x compatible) with gr.Blocks(title="Ses Deşifre Pro") as demo: # Header via HTML gr.HTML("""

🎙️ Ses Deşifre Pro

Yapay zeka ile Türkçe ses kayıtlarını metne dönüştürün

""") # Main content with gr.Row(): with gr.Column(): gr.HTML('
📤 Ses Kaynağı
') audio_input = gr.Audio( label="Ses Dosyası veya Mikrofon", type="filepath", sources=["upload", "microphone"] ) submit_btn = gr.Button( "✨ Transkripsiyon Başlat", variant="primary", size="lg" ) # Tips gr.HTML("""

💡 İpucu: En iyi sonuç için net, gürültüsüz ses kayıtları kullanın. Desteklenen formatlar: MP3, WAV, M4A, OGG, FLAC

""") # Results section with gr.Row(): with gr.Column(): gr.HTML('
📝 Transkripsiyon Sonucu
') output_text = gr.Textbox( label="", placeholder="Sonuç burada görünecek...", lines=12, interactive=False ) download_file = gr.File( label="📥 Sonucu İndir (.txt)" ) # ==================== GEMINI AI SECTION ==================== gr.HTML("""

Gemini AI ile Özet

Opsiyonel • API anahtarınız saklanmaz

""") with gr.Row(): with gr.Column(scale=1): gemini_api_key = gr.Textbox( label="🔑 Gemini API Anahtarı", placeholder="AIza... şeklinde API anahtarınızı girin", type="password", info="Güvenli: Anahtarınız sunucuda saklanmaz, yalnızca bu istek için kullanılır." ) gemini_prompt = gr.Textbox( label="📝 Gemini'ye Not (Opsiyonel)", placeholder="Örn: Sınavım için özet yap, En önemli 5 maddeyi listele, Bu metnin raporunu çıkar...", lines=2, info="Boş bırakırsanız genel bir özet oluşturulur." ) gemini_btn = gr.Button( "🤖 Gemini ile Özetle", variant="secondary", size="lg" ) with gr.Column(scale=1): gemini_output = gr.Textbox( label="Gemini Özet Sonucu", placeholder="Özet burada görünecek...", lines=10, show_copy_button=True ) gr.HTML("""

🔒 Gizlilik: API anahtarınız sunucuda saklanmaz. "Gemini ile Özetle" butonuna basmadığınız sürece hiçbir veri dışarıya gönderilmez. Ücretsiz API anahtarı alın →

""") # Features gr.HTML("""
🚀
Hızlı İşlem
🎯
Yüksek Doğruluk
🔒
Gizlilik Odaklı
AI Özet
""") # Footer gr.HTML("""

Powered by Faster-Whisper & Gemini AI • CPU Optimized • Made with ❤️

""") # Event handling submit_btn.click( fn=transcribe, inputs=[audio_input], outputs=[output_text, download_file] ) gemini_btn.click( fn=summarize_with_gemini, inputs=[output_text, gemini_api_key, gemini_prompt], outputs=gemini_output ) # Launch if __name__ == "__main__": demo.launch(share=False, show_error=True)