Guest User

Untitled

a guest
Nov 19th, 2025
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.48 KB | None | 0 0
  1. import whisper
  2. import pyttsx3
  3. import requests
  4. import json
  5. import threading
  6. import pyaudio
  7. import wave
  8. import keyboard
  9. import subprocess
  10. import os
  11. import time
  12.  
  13. class VoiceAssistant:
  14. def __init__(self):
  15. # Инициализация компонентов
  16. print("Загрузка Whisper...")
  17. self.whisper_model = whisper.load_model("base") # или "small" для скорости
  18.  
  19. print("Инициализация TTS...")
  20. self.tts = pyttsx3.init()
  21. self.tts.setProperty('rate', 180) # скорость речи
  22.  
  23. # Настройки аудио
  24. self.audio_format = pyaudio.paInt16
  25. self.channels = 1
  26. self.rate = 16000
  27. self.chunk = 1024
  28.  
  29. # URL Ollama API
  30. self.ollama_url = "http://localhost:11434/api/generate"
  31.  
  32. print("Голосовой помощник готов!")
  33.  
  34. def speak(self, text):
  35. """Озвучивание текста"""
  36. print(f"🔊 {text}")
  37. self.tts.say(text)
  38. self.tts.runAndWait()
  39.  
  40. def record_audio(self, duration=5):
  41. """Запись аудио с микрофона"""
  42. audio = pyaudio.PyAudio()
  43.  
  44. stream = audio.open(
  45. format=self.audio_format,
  46. channels=self.channels,
  47. rate=self.rate,
  48. input=True,
  49. frames_per_buffer=self.chunk
  50. )
  51.  
  52. print("🎤 Слушаю...")
  53. frames = []
  54.  
  55. for _ in range(0, int(self.rate / self.chunk * duration)):
  56. data = stream.read(self.chunk)
  57. frames.append(data)
  58.  
  59. stream.stop_stream()
  60. stream.close()
  61. audio.terminate()
  62.  
  63. # Сохранение во временный файл
  64. with wave.open("temp_audio.wav", 'wb') as wf:
  65. wf.setnchannels(self.channels)
  66. wf.setsampwidth(audio.get_sample_size(self.audio_format))
  67. wf.setframerate(self.rate)
  68. wf.writeframes(b''.join(frames))
  69.  
  70. return "temp_audio.wav"
  71.  
  72. def speech_to_text(self, audio_file):
  73. """Преобразование речи в текст через Whisper"""
  74. try:
  75. result = self.whisper_model.transcribe(audio_file)
  76. return result["text"].strip()
  77. except Exception as e:
  78. print(f"Ошибка распознавания: {e}")
  79. return ""
  80.  
  81. def query_ollama(self, prompt):
  82. """Запрос к локальной модели через Ollama"""
  83. try:
  84. data = {
  85. "model": "owl/t-lite:latest", # замените на вашу модель
  86. "prompt": prompt,
  87. "stream": False
  88. }
  89.  
  90. response = requests.post(self.ollama_url, json=data, timeout=60)
  91. if response.status_code == 200:
  92. return response.json()["response"]
  93. else:
  94. return "Ошибка связи с Ollama"
  95.  
  96. except Exception as e:
  97. return f"Ошибка: {e}"
  98.  
  99. def execute_system_command(self, command):
  100. """Выполнение системных команд"""
  101. try:
  102. if "открой" in command.lower():
  103. if "блокнот" in command.lower():
  104. subprocess.run(["notepad.exe"])
  105. return "Блокнот открыт"
  106. elif "калькулятор" in command.lower():
  107. subprocess.run(["calc.exe"])
  108. return "Калькулятор открыт"
  109. elif "проводник" in command.lower():
  110. subprocess.run(["explorer.exe"])
  111. return "Проводник открыт"
  112.  
  113. elif "закрой" in command.lower():
  114. if "блокнот" in command.lower():
  115. subprocess.run(["taskkill", "/f", "/im", "notepad.exe"])
  116. return "Блокнот закрыт"
  117.  
  118. return None # команда не распознана
  119.  
  120. except Exception as e:
  121. return f"Ошибка выполнения: {e}"
  122.  
  123. def process_command(self, text):
  124. """Обработка команды пользователя"""
  125. if not text:
  126. return "Не расслышал"
  127.  
  128. print(f"👤 Услышал: {text}")
  129.  
  130. # Сначала проверяем простые системные команды
  131. system_result = self.execute_system_command(text)
  132. if system_result:
  133. return system_result
  134.  
  135. # Если не системная команда, отправляем в Ollama
  136. prompt = f"""Ты голосовой помощник. Пользователь сказал: "{text}"
  137.  
  138. Если это простая команда или вопрос - отвечай кратко и по делу.
  139. Если это сложная задача, которая требует продвинутых знаний - скажи "НУЖНА_ПОМОЩЬ_CLAUDE:" и сформулируй детальный промпт для отправки в Claude API.
  140.  
  141. Ответ:"""
  142.  
  143. response = self.query_ollama(prompt)
  144.  
  145. # Проверяем, нужна ли помощь Claude
  146. if "НУЖНА_ПОМОЩЬ_CLAUDE:" in response:
  147. claude_prompt = response.split("НУЖНА_ПОМОЩЬ_CLAUDE:")[1].strip()
  148. # Здесь можно добавить реальный запрос к Claude API
  149. return f"Обратился бы к Claude с вопросом: {claude_prompt}"
  150.  
  151. return response
  152.  
  153. def run(self):
  154. """Основной цикл работы"""
  155. self.speak("Голосовой помощник запущен. Нажимайте пробел для записи.")
  156.  
  157. while True:
  158. try:
  159. print("\n⏳ Жду команды... (Пробел - записать, Esc - выход)")
  160.  
  161. # Ждём нажатия пробела
  162. keyboard.wait('space')
  163.  
  164. # Записываем аудио
  165. audio_file = self.record_audio(duration=5)
  166.  
  167. # Преобразуем в текст
  168. text = self.speech_to_text(audio_file)
  169.  
  170. # Обрабатываем команду
  171. response = self.process_command(text)
  172.  
  173. # Озвучиваем ответ
  174. self.speak(response)
  175.  
  176. # Проверяем на выход
  177. if keyboard.is_pressed('esc'):
  178. break
  179.  
  180. except KeyboardInterrupt:
  181. break
  182. except Exception as e:
  183. print(f"Ошибка: {e}")
  184. self.speak("Произошла ошибка")
  185.  
  186. self.speak("До свидания!")
  187.  
  188. # Удаляем временный файл
  189. if os.path.exists("temp_audio.wav"):
  190. os.remove("temp_audio.wav")
  191.  
  192. if __name__ == "__main__":
  193. assistant = VoiceAssistant()
  194. assistant.run()
Advertisement
Add Comment
Please, Sign In to add comment