Ani-Voice-API / voice_pipeline.py
ssasio's picture
Upload 12 files
caf9e2a verified
Raw
History Blame Contribute Delete
3.83 kB
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()