| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- """
- Konan Voice Client — PC Windows
- Push-to-talk : maintiens ESPACE pour parler, relâche pour envoyer.
- Ctrl+C pour quitter.
- Installation :
- pip install sounddevice scipy openai-whisper requests keyboard pyttsx3
- """
- import sounddevice as sd
- import scipy.io.wavfile as wav
- import whisper
- import requests
- import pyttsx3
- import keyboard
- import numpy as np
- import tempfile
- import os
- import sys
- KONAN_API = "http://192.168.1.21:8765/api/chat"
- SAMPLE_RATE = 16000
- USER_ID = "pc_user"
- print("Chargement de Whisper tiny...")
- model = whisper.load_model("tiny")
- print("Whisper prêt.")
- engine = pyttsx3.init()
- engine.setProperty("rate", 165)
- # Voix française si disponible
- voices = engine.getProperty("voices")
- for v in voices:
- if "fr" in v.id.lower() or "french" in v.name.lower():
- engine.setProperty("voice", v.id)
- break
- def speak(text):
- print(f"Konan : {text}")
- engine.say(text)
- engine.runAndWait()
- def record_until_release():
- print("🎙️ Enregistrement... (relâche Espace pour envoyer)")
- chunks = []
- stream = sd.InputStream(samplerate=SAMPLE_RATE, channels=1, dtype="int16")
- stream.start()
- while keyboard.is_pressed("space"):
- chunk, _ = stream.read(1024)
- chunks.append(chunk)
- stream.stop()
- stream.close()
- if not chunks:
- return None
- audio = np.concatenate(chunks, axis=0).flatten()
- return audio
- def transcribe(audio):
- with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
- tmp_path = f.name
- wav.write(tmp_path, SAMPLE_RATE, audio)
- result = model.transcribe(tmp_path, language="fr")
- try:
- os.unlink(tmp_path)
- except Exception:
- pass
- return result["text"].strip()
- def ask_konan(text):
- try:
- r = requests.post(KONAN_API, json={"text": text, "user_id": USER_ID}, timeout=120)
- data = r.json()
- return data.get("response", "Pas de réponse.")
- except Exception as e:
- return f"Erreur connexion : {e}"
- speak("Konan est prêt. Maintiens Espace pour parler.")
- print("\n▶ Maintiens ESPACE pour parler. Ctrl+C pour quitter.\n")
- try:
- while True:
- keyboard.wait("space")
- audio = record_until_release()
- if audio is None or len(audio) < SAMPLE_RATE * 0.3:
- print("(trop court, ignoré)")
- continue
- print("Transcription...")
- text = transcribe(audio)
- if not text:
- print("(rien détecté)")
- continue
- print(f"Toi : {text}")
- print("Konan réfléchit...")
- response = ask_konan(text)
- speak(response)
- except KeyboardInterrupt:
- print("\nAu revoir.")
|