Ani-Voice-API / voice_pipeline.py
ssasio's picture
Duplicate from beleata74/Ani-Voice-API
7eecd1a
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()