Start
This commit is contained in:
commit
301abf1b7e
|
@ -0,0 +1,16 @@
|
||||||
|
jupytext
|
||||||
|
python-lsp-server
|
||||||
|
ocp_vscode
|
||||||
|
pyright
|
||||||
|
vosk
|
||||||
|
sounddevice
|
||||||
|
pyperclip
|
||||||
|
pyautogui
|
||||||
|
black
|
||||||
|
jupyter
|
||||||
|
flake8
|
||||||
|
pyflakes
|
||||||
|
# pylint
|
||||||
|
git+https://github.com/gumyr/bd_warehouse
|
||||||
|
git+https://github.com/gumyr/build123d
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
import zipfile
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
VENV_DIR = "venv"
|
||||||
|
REQUIREMENTS_FILE = "requirements.txt"
|
||||||
|
MODEL_URL = "https://alphacephei.com/vosk/models/vosk-model-small-pl-0.22.zip"
|
||||||
|
MODEL_ZIP = "vosk-model-small-pl-0.22.zip"
|
||||||
|
MODEL_DIR = "vosk-model-small-pl-0.22"
|
||||||
|
|
||||||
|
|
||||||
|
def create_virtualenv():
|
||||||
|
print("[+] Tworzenie środowiska wirtualnego...")
|
||||||
|
subprocess.check_call([sys.executable, "-m", "venv", VENV_DIR])
|
||||||
|
|
||||||
|
|
||||||
|
def install_requirements():
|
||||||
|
print("[+] Instalacja pakietów z requirements.txt...")
|
||||||
|
pip_path = os.path.join(VENV_DIR, "bin", "pip") if os.name != "nt" else os.path.join(VENV_DIR, "Scripts", "pip.exe")
|
||||||
|
subprocess.check_call([pip_path, "install", "-r", REQUIREMENTS_FILE])
|
||||||
|
|
||||||
|
|
||||||
|
def download_model():
|
||||||
|
if os.path.exists(MODEL_DIR):
|
||||||
|
print("[i] Model już istnieje, pomijam pobieranie.")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"[+] Pobieranie modelu z {MODEL_URL}...")
|
||||||
|
urllib.request.urlretrieve(MODEL_URL, MODEL_ZIP)
|
||||||
|
|
||||||
|
print("[+] Rozpakowywanie modelu...")
|
||||||
|
with zipfile.ZipFile(MODEL_ZIP, 'r') as zip_ref:
|
||||||
|
zip_ref.extractall(".")
|
||||||
|
|
||||||
|
print("[+] Usuwanie archiwum ZIP...")
|
||||||
|
os.remove(MODEL_ZIP)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
create_virtualenv()
|
||||||
|
install_requirements()
|
||||||
|
download_model()
|
||||||
|
print("[✓] Gotowe!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -0,0 +1,118 @@
|
||||||
|
from vosk import Model, KaldiRecognizer
|
||||||
|
import sounddevice as sd
|
||||||
|
import json
|
||||||
|
import pyperclip # Biblioteka do obsługi schowka
|
||||||
|
import pyautogui
|
||||||
|
import sys
|
||||||
|
import tkinter as tk
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
# Ścieżka do modelu
|
||||||
|
model_path = "./vosk-model-small-pl-0.22"
|
||||||
|
model = Model(model_path)
|
||||||
|
recognizer = KaldiRecognizer(model, 16000)
|
||||||
|
|
||||||
|
listening = False # Flaga stanu nasłuchiwania
|
||||||
|
emacs_mode = False # Flaga trybu Emacs
|
||||||
|
|
||||||
|
# Funkcja obsługi danych audio
|
||||||
|
def callback(indata, frames, time, status):
|
||||||
|
if status:
|
||||||
|
print(f"Status: {status}", file=sys.stderr)
|
||||||
|
# Konwersja danych na `bytes`
|
||||||
|
data = bytes(indata)
|
||||||
|
if recognizer.AcceptWaveform(data):
|
||||||
|
result = json.loads(recognizer.Result())
|
||||||
|
text = result.get("text", "")
|
||||||
|
if text:
|
||||||
|
print(f"Rozpoznano: {text}")
|
||||||
|
insert_text_with_clipboard(text)
|
||||||
|
|
||||||
|
# Funkcja kopiowania do schowka i wklejania
|
||||||
|
def insert_text_with_clipboard(text):
|
||||||
|
try:
|
||||||
|
pyperclip.copy(text) # Kopiowanie tekstu do schowka
|
||||||
|
if emacs_mode:
|
||||||
|
pyautogui.hotkey('shift', 'insert') # Wklejanie w trybie Emacs
|
||||||
|
else:
|
||||||
|
pyautogui.hotkey('ctrl', 'v') # Standardowe wklejanie
|
||||||
|
pyautogui.press('space') # Dodanie spacji (opcjonalne)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Błąd podczas wklejania tekstu: {e}", file=sys.stderr)
|
||||||
|
|
||||||
|
# Funkcja nasłuchiwania i rozpoznawania mowy
|
||||||
|
def listen_and_type():
|
||||||
|
global listening
|
||||||
|
print("Słucham... (naciśnij Stop, aby zatrzymać)")
|
||||||
|
try:
|
||||||
|
with sd.RawInputStream(samplerate=16000, blocksize=8000, dtype='int16',
|
||||||
|
channels=1, callback=callback):
|
||||||
|
while listening:
|
||||||
|
pass # Nasłuchiwanie trwa w pętli
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Błąd podczas nasłuchiwania: {e}", file=sys.stderr)
|
||||||
|
|
||||||
|
# Funkcje sterujące GUI
|
||||||
|
def toggle_listening():
|
||||||
|
global listening
|
||||||
|
if listening:
|
||||||
|
listening = False
|
||||||
|
update_button_state()
|
||||||
|
print("Nasłuchiwanie zatrzymane.")
|
||||||
|
else:
|
||||||
|
listening = True
|
||||||
|
update_button_state()
|
||||||
|
thread = Thread(target=listen_and_type)
|
||||||
|
thread.daemon = True
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
def toggle_emacs_mode():
|
||||||
|
global emacs_mode
|
||||||
|
emacs_mode = not emacs_mode
|
||||||
|
update_emacs_button_state()
|
||||||
|
mode = "Emacs" if emacs_mode else "Standard"
|
||||||
|
print(f"Tryb wklejania: {mode}")
|
||||||
|
|
||||||
|
# Aktualizacja stanu przycisków
|
||||||
|
def update_button_state():
|
||||||
|
if listening:
|
||||||
|
toggle_button.config(text="Stop", bg="red", fg="white")
|
||||||
|
else:
|
||||||
|
toggle_button.config(text="Start", bg="lightgrey", fg="black")
|
||||||
|
|
||||||
|
def update_emacs_button_state():
|
||||||
|
if emacs_mode:
|
||||||
|
emacs_button.config(text="Tryb: Emacs", bg="blue", fg="white")
|
||||||
|
else:
|
||||||
|
emacs_button.config(text="Tryb: Standard", bg="lightgrey", fg="black")
|
||||||
|
|
||||||
|
# Funkcja obsługi skrótu klawiszowego
|
||||||
|
def handle_shortcut(event):
|
||||||
|
if event.keysym == 'F1': # F1 jako skrót klawiszowy
|
||||||
|
toggle_listening()
|
||||||
|
|
||||||
|
# Tworzenie GUI
|
||||||
|
def create_gui():
|
||||||
|
global toggle_button, emacs_button
|
||||||
|
|
||||||
|
root = tk.Tk()
|
||||||
|
root.title("Vosk Rozpoznawanie Mowy")
|
||||||
|
root.geometry("300x200")
|
||||||
|
|
||||||
|
toggle_button = tk.Button(root, text="Start", command=toggle_listening, width=15, bg="lightgrey", fg="black")
|
||||||
|
toggle_button.pack(pady=10)
|
||||||
|
|
||||||
|
emacs_button = tk.Button(root, text="Tryb: Standard", command=toggle_emacs_mode, width=15, bg="lightgrey", fg="black")
|
||||||
|
emacs_button.pack(pady=10)
|
||||||
|
|
||||||
|
exit_button = tk.Button(root, text="Wyjście", command=root.destroy, width=15)
|
||||||
|
exit_button.pack(pady=10)
|
||||||
|
|
||||||
|
# Dodanie skrótu klawiszowego
|
||||||
|
root.bind("<F1>", handle_shortcut)
|
||||||
|
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
|
# Uruchomienie GUI
|
||||||
|
if __name__ == "__main__":
|
||||||
|
create_gui()
|
Loading…
Reference in New Issue