VerbaLive / app.py
koesan's picture
Update app.py
dee222b verified
import os
import sys
import time
import threading
from flask import Flask, render_template, request, jsonify, Response
import numpy as np
import requests
import re
import queue
import april_asr as april
import json
# Google çeviri için farklı yaklaşım
try:
from googletrans import Translator
GOOGLE_TRANSLATE_AVAILABLE = True
except Exception as e:
print(f"Google Translate loading error: {e}")
GOOGLE_TRANSLATE_AVAILABLE = False
try:
import deepl
DEEPL_AVAILABLE = True
except ImportError:
DEEPL_AVAILABLE = False
# Flask uygulamasını başlat
app = Flask(__name__)
# Global değişkenler ve nesneler
live_caption_instance = None
is_running = False
asr_queue = queue.Queue()
translator = None # Translator nesnesini global tanımla
class SimpleGoogleTranslator:
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
})
def translate(self, text, target_lang='tr', source_lang='en'):
try:
url = "https://translate.googleapis.com/translate_a/single"
params = {
'client': 'gtx',
'sl': source_lang,
'tl': target_lang,
'dt': 't',
'q': text
}
response = self.session.get(url, params=params, timeout=10)
if response.status_code == 200:
result = response.json()
if result and len(result) > 0 and len(result[0]) > 0:
translated_text = ''.join([item[0] for item in result[0] if item[0]])
return translated_text
return None
except Exception as e:
print(f"Simple Google Translate error: {e}")
return None
class ImprovedTranslator:
def __init__(self):
self.google_translator = None
self.simple_translator = SimpleGoogleTranslator()
self.deepl_translator = None
def translate(self, text, target_lang, service="Google Translate", deepl_key=""):
if not text or not text.strip():
return ""
try:
cleaned_text = self._clean_text(text)
if service == "Google Translate":
return self._google_translate(cleaned_text, target_lang)
elif service == "DeepL" and DEEPL_AVAILABLE and deepl_key:
return self._deepl_translate(cleaned_text, target_lang, deepl_key)
else:
return f"[{service} not available]"
except Exception as e:
return f"[Translation error: {str(e)[:50]}...]"
def _clean_text(self, text):
text = text.strip()
text = re.sub(r'\s+', ' ', text)
return text
def _google_translate(self, text, target_lang):
try:
result = self.simple_translator.translate(text, target_lang)
if result:
return result
except Exception as e:
print(f"Simple translator failed: {e}")
if GOOGLE_TRANSLATE_AVAILABLE:
try:
if self.google_translator is None:
self.google_translator = Translator()
result = self.google_translator.translate(text, dest=target_lang, src='en')
if result and result.text:
return result.text
except Exception as e:
print(f"Googletrans failed: {e}")
return "[Google translation failed]"
def _deepl_translate(self, text, target_lang, deepl_key):
try:
if self.deepl_translator is None:
self.deepl_translator = deepl.Translator(deepl_key)
deepl_lang_map = {
'tr': 'TR', 'fr': 'FR', 'de': 'DE', 'es': 'ES',
'it': 'IT', 'ru': 'RU', 'ja': 'JA', 'zh-CN': 'ZH',
'pt': 'PT', 'nl': 'NL', 'ko': 'KO'
}
deepl_target = deepl_lang_map.get(target_lang, target_lang.upper())
result = self.deepl_translator.translate_text(text, target_lang=deepl_target)
return result.text if result else "[DeepL no result]"
except Exception as e:
return f"[DeepL error]"
def init_asr():
"""ASR modelini başlatır."""
global live_caption_instance
if live_caption_instance is None:
try:
model_path = "april-english-dev-01110_en.april"
if not os.path.exists(model_path):
print(f"[HATA] Model dosyası bulunamadı: {model_path}")
return
model = april.Model(model_path)
def asr_handler(result_type, tokens):
text = "".join(token.token for token in tokens).strip()
if not text:
return
if result_type == april.Result.PARTIAL_RECOGNITION:
asr_queue.put({"english": text, "type": "partial"})
elif result_type == april.Result.FINAL_RECOGNITION:
asr_queue.put({"english": text, "type": "final"})
live_caption_instance = april.Session(model, asr_handler, asynchronous=True)
print("ASR Model başarıyla başlatıldı.")
except Exception as e:
print(f"[HATA] ASR Model yükleme hatası: {e}")
live_caption_instance = None # Hata durumunda nesneyi None yap
@app.route('/')
def index():
return render_template('index.html')
@app.route('/start', methods=['POST'])
def start_stream():
global is_running, translator
if not is_running:
init_asr()
translator = ImprovedTranslator()
is_running = True
return jsonify({"status": "started"})
@app.route('/stop', methods=['POST'])
def stop_stream():
global is_running, live_caption_instance
if is_running:
is_running = False
if live_caption_instance:
live_caption_instance = None
return jsonify({"status": "stopped"})
@app.route('/upload_audio', methods=['POST'])
def upload_audio():
audio_data = request.data
if live_caption_instance:
try:
live_caption_instance.feed_pcm16(audio_data)
except Exception as e:
print(f"[HATA] ASR feed hatası: {e}")
return jsonify({"status": "error", "message": str(e)}), 500
return '', 204
@app.route('/stream_results')
def stream_results():
target_lang = request.args.get("target_lang", "tr")
service = request.args.get("service", "Google Translate")
deepl_key = request.args.get("deepl_key", "")
def generate():
while is_running:
try:
result = asr_queue.get(timeout=0.1)
english_text = result["english"]
result_type = result["type"]
translated_text = ""
if result_type == "partial":
translated_text = translator.translate(english_text, target_lang, "Google Translate", "")
elif result_type == "final":
translated_text = translator.translate(english_text, target_lang, service, deepl_key)
response_data = {
"english": english_text,
"type": result_type,
"translation": translated_text,
}
yield f"data: {json.dumps(response_data)}\n\n"
except queue.Empty:
continue
except Exception as e:
print(f"SSE hatası: {e}")
break
return Response(generate(), mimetype='text/event-stream')
if __name__ == '__main__':
init_asr()
# Port numarasını ortam değişkeninden al, varsayılan 7860
port = int(os.environ.get('PORT', 7860))
app.run(host='0.0.0.0', port=port, threaded=True)