Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import whisper
- import pyttsx3
- import requests
- import json
- import threading
- import pyaudio
- import wave
- import keyboard
- import subprocess
- import os
- import time
- class VoiceAssistant:
- def __init__(self):
- # Инициализация компонентов
- print("Загрузка Whisper...")
- self.whisper_model = whisper.load_model("base") # или "small" для скорости
- print("Инициализация TTS...")
- self.tts = pyttsx3.init()
- self.tts.setProperty('rate', 180) # скорость речи
- # Настройки аудио
- self.audio_format = pyaudio.paInt16
- self.channels = 1
- self.rate = 16000
- self.chunk = 1024
- # URL Ollama API
- self.ollama_url = "http://localhost:11434/api/generate"
- print("Голосовой помощник готов!")
- def speak(self, text):
- """Озвучивание текста"""
- print(f"🔊 {text}")
- self.tts.say(text)
- self.tts.runAndWait()
- def record_audio(self, duration=5):
- """Запись аудио с микрофона"""
- audio = pyaudio.PyAudio()
- stream = audio.open(
- format=self.audio_format,
- channels=self.channels,
- rate=self.rate,
- input=True,
- frames_per_buffer=self.chunk
- )
- print("🎤 Слушаю...")
- frames = []
- for _ in range(0, int(self.rate / self.chunk * duration)):
- data = stream.read(self.chunk)
- frames.append(data)
- stream.stop_stream()
- stream.close()
- audio.terminate()
- # Сохранение во временный файл
- with wave.open("temp_audio.wav", 'wb') as wf:
- wf.setnchannels(self.channels)
- wf.setsampwidth(audio.get_sample_size(self.audio_format))
- wf.setframerate(self.rate)
- wf.writeframes(b''.join(frames))
- return "temp_audio.wav"
- def speech_to_text(self, audio_file):
- """Преобразование речи в текст через Whisper"""
- try:
- result = self.whisper_model.transcribe(audio_file)
- return result["text"].strip()
- except Exception as e:
- print(f"Ошибка распознавания: {e}")
- return ""
- def query_ollama(self, prompt):
- """Запрос к локальной модели через Ollama"""
- try:
- data = {
- "model": "owl/t-lite:latest", # замените на вашу модель
- "prompt": prompt,
- "stream": False
- }
- response = requests.post(self.ollama_url, json=data, timeout=60)
- if response.status_code == 200:
- return response.json()["response"]
- else:
- return "Ошибка связи с Ollama"
- except Exception as e:
- return f"Ошибка: {e}"
- def execute_system_command(self, command):
- """Выполнение системных команд"""
- try:
- if "открой" in command.lower():
- if "блокнот" in command.lower():
- subprocess.run(["notepad.exe"])
- return "Блокнот открыт"
- elif "калькулятор" in command.lower():
- subprocess.run(["calc.exe"])
- return "Калькулятор открыт"
- elif "проводник" in command.lower():
- subprocess.run(["explorer.exe"])
- return "Проводник открыт"
- elif "закрой" in command.lower():
- if "блокнот" in command.lower():
- subprocess.run(["taskkill", "/f", "/im", "notepad.exe"])
- return "Блокнот закрыт"
- return None # команда не распознана
- except Exception as e:
- return f"Ошибка выполнения: {e}"
- def process_command(self, text):
- """Обработка команды пользователя"""
- if not text:
- return "Не расслышал"
- print(f"👤 Услышал: {text}")
- # Сначала проверяем простые системные команды
- system_result = self.execute_system_command(text)
- if system_result:
- return system_result
- # Если не системная команда, отправляем в Ollama
- prompt = f"""Ты голосовой помощник. Пользователь сказал: "{text}"
- Если это простая команда или вопрос - отвечай кратко и по делу.
- Если это сложная задача, которая требует продвинутых знаний - скажи "НУЖНА_ПОМОЩЬ_CLAUDE:" и сформулируй детальный промпт для отправки в Claude API.
- Ответ:"""
- response = self.query_ollama(prompt)
- # Проверяем, нужна ли помощь Claude
- if "НУЖНА_ПОМОЩЬ_CLAUDE:" in response:
- claude_prompt = response.split("НУЖНА_ПОМОЩЬ_CLAUDE:")[1].strip()
- # Здесь можно добавить реальный запрос к Claude API
- return f"Обратился бы к Claude с вопросом: {claude_prompt}"
- return response
- def run(self):
- """Основной цикл работы"""
- self.speak("Голосовой помощник запущен. Нажимайте пробел для записи.")
- while True:
- try:
- print("\n⏳ Жду команды... (Пробел - записать, Esc - выход)")
- # Ждём нажатия пробела
- keyboard.wait('space')
- # Записываем аудио
- audio_file = self.record_audio(duration=5)
- # Преобразуем в текст
- text = self.speech_to_text(audio_file)
- # Обрабатываем команду
- response = self.process_command(text)
- # Озвучиваем ответ
- self.speak(response)
- # Проверяем на выход
- if keyboard.is_pressed('esc'):
- break
- except KeyboardInterrupt:
- break
- except Exception as e:
- print(f"Ошибка: {e}")
- self.speak("Произошла ошибка")
- self.speak("До свидания!")
- # Удаляем временный файл
- if os.path.exists("temp_audio.wav"):
- os.remove("temp_audio.wav")
- if __name__ == "__main__":
- assistant = VoiceAssistant()
- assistant.run()
Advertisement
Add Comment
Please, Sign In to add comment