Spaces:
Paused
Paused
| import os | |
| import time | |
| import json | |
| import base64 | |
| import requests | |
| import tempfile | |
| import threading | |
| import queue | |
| import winsound | |
| TRANSCRIPT_PATH = r"C:\Users\nasko\.gemini\antigravity\brain\695897cf-1c58-4886-a686-e9d8c406ebef\.system_generated\logs\transcript.jsonl" | |
| API_URL = "http://localhost:8000/api/v1/synthesize/stream" | |
| audio_queue = queue.Queue() | |
| def player_worker(): | |
| """ | |
| Взима готови WAV файлове от опашката и ги пуска. | |
| """ | |
| while True: | |
| file_path = audio_queue.get() | |
| if file_path is None: break | |
| print(f"🔊 Възпроизвеждам от API...") | |
| winsound.PlaySound(file_path, winsound.SND_FILENAME) | |
| try: | |
| os.remove(file_path) | |
| except OSError: | |
| pass | |
| audio_queue.task_done() | |
| def process_text(text: str): | |
| """ | |
| Изпраща текста към API-то и чака за стрийминг на аудио парчета. | |
| """ | |
| print(f"📡 Изпращане към API: {text[:50]}...") | |
| try: | |
| response = requests.post(API_URL, json={ | |
| "text": text, | |
| "voice_style": "F5", | |
| "speed": 1.6 | |
| }, stream=True) | |
| if response.status_code != 200: | |
| print(f"Грешка от API: {response.status_code} - {response.text}") | |
| return | |
| for line in response.iter_lines(): | |
| if line: | |
| data = json.loads(line) | |
| if "error" in data: | |
| print(f"API Грешка: {data['error']}") | |
| continue | |
| chunk_index = data.get("chunk_index") | |
| audio_base64 = data.get("audio_base64") | |
| if audio_base64: | |
| audio_bytes = base64.b64decode(audio_base64) | |
| # Записваме временно файла и го пускаме в опашката | |
| fd, file_path = tempfile.mkstemp(suffix=f"_chunk_{chunk_index}.wav") | |
| os.close(fd) | |
| with open(file_path, "wb") as f: | |
| f.write(audio_bytes) | |
| audio_queue.put(file_path) | |
| except requests.exceptions.ConnectionError: | |
| print("Не мога да се свържа с API-то! Увери се, че `api.py` работи на порт 8000.") | |
| except Exception as e: | |
| print(f"Грешка при комуникация с API: {e}") | |
| def tail_file(): | |
| """ | |
| Следи чата (transcript.jsonl) за нови съобщения от модела. | |
| """ | |
| if not os.path.exists(TRANSCRIPT_PATH): | |
| print(f"Файлът не съществува: {TRANSCRIPT_PATH}") | |
| return | |
| with open(TRANSCRIPT_PATH, "r", encoding="utf-8") as f: | |
| f.seek(0, 2) | |
| while True: | |
| line = f.readline() | |
| if not line: | |
| time.sleep(0.5) | |
| continue | |
| try: | |
| data = json.loads(line) | |
| if data.get("source") == "MODEL" and data.get("type") in ["PLANNER_RESPONSE", "GENERIC"]: | |
| full_text = data.get("content", "") | |
| if full_text and not full_text.startswith("Created At:"): | |
| print("\n📝 Получен нов текст от чата.") | |
| process_text(full_text) | |
| except Exception as e: | |
| pass | |
| if __name__ == "__main__": | |
| t_play = threading.Thread(target=player_worker, daemon=True) | |
| t_play.start() | |
| print("Ani Voice Client слуша за съобщения и чака API-то...") | |
| tail_file() | |