fix windows hotkey performance
This commit is contained in:
12
Readme.md
12
Readme.md
@@ -65,7 +65,8 @@ To get this script working you will need to install the following on the relevan
|
|||||||
* pip install pydub
|
* pip install pydub
|
||||||
* pip install keyboard
|
* pip install keyboard
|
||||||
* pip install pystray
|
* pip install pystray
|
||||||
* pip install playsound
|
* pip install pygame
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Mac
|
### Mac
|
||||||
@@ -88,10 +89,19 @@ To get this script working you will need to install the following on the relevan
|
|||||||
pip install --upgrade pip # Ensure pip is updated
|
pip install --upgrade pip # Ensure pip is updated
|
||||||
pip install pyinstaller # Install PyInstaller
|
pip install pyinstaller # Install PyInstaller
|
||||||
|
|
||||||
|
OLD:
|
||||||
python -m PyInstaller --onefile --windowed text-to-mic.py
|
python -m PyInstaller --onefile --windowed text-to-mic.py
|
||||||
|
|
||||||
|
New
|
||||||
|
python -m PyInstaller --onefile --add-data "assets;assets" text-to-mic.py
|
||||||
|
|
||||||
## Mac
|
## Mac
|
||||||
|
|
||||||
brew install python
|
brew install python
|
||||||
pip3 install pyinstaller
|
pip3 install pyinstaller
|
||||||
|
|
||||||
|
OLD
|
||||||
pyinstaller --onefile --windowed text-to-mic.py
|
pyinstaller --onefile --windowed text-to-mic.py
|
||||||
|
|
||||||
|
New
|
||||||
|
pyinstaller --onefile --add-data "assets:assets" text-to-mic.py
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import wave
|
|||||||
import webbrowser
|
import webbrowser
|
||||||
import json
|
import json
|
||||||
import keyboard
|
import keyboard
|
||||||
import pygame
|
import sys
|
||||||
|
|
||||||
from pystray import Icon as icon, MenuItem as item, Menu as menu
|
from pystray import Icon as icon, MenuItem as item, Menu as menu
|
||||||
from PIL import Image, ImageDraw
|
from PIL import Image, ImageDraw
|
||||||
@@ -16,6 +16,7 @@ from openai import OpenAI
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pydub import AudioSegment
|
from pydub import AudioSegment
|
||||||
|
from audioplayer import AudioPlayer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -107,9 +108,9 @@ class Application(tk.Tk):
|
|||||||
|
|
||||||
def setup_hotkeys(self):
|
def setup_hotkeys(self):
|
||||||
# Register global hotkeys
|
# Register global hotkeys
|
||||||
keyboard.add_hotkey('ctrl+shift+r', lambda: self.hotkey_record_trigger())
|
keyboard.add_hotkey('ctrl+shift+0', lambda: self.hotkey_record_trigger())
|
||||||
keyboard.add_hotkey('ctrl+shift+s', lambda: self.hotkey_stop_trigger() )
|
keyboard.add_hotkey('ctrl+shift+9', lambda: self.hotkey_stop_trigger() )
|
||||||
keyboard.add_hotkey('ctrl+shift+l', lambda: self.hotkey_play_last_audio_trigger() )
|
keyboard.add_hotkey('ctrl+shift+8', lambda: self.hotkey_play_last_audio_trigger() )
|
||||||
|
|
||||||
def hotkey_play_last_audio_trigger(self):
|
def hotkey_play_last_audio_trigger(self):
|
||||||
if hasattr(self, 'last_audio_file'):
|
if hasattr(self, 'last_audio_file'):
|
||||||
@@ -122,30 +123,42 @@ class Application(tk.Tk):
|
|||||||
self.play_sound('assets/wrong-short.wav')
|
self.play_sound('assets/wrong-short.wav')
|
||||||
if self.recording:
|
if self.recording:
|
||||||
self.stop_recording(auto_play=False)
|
self.stop_recording(auto_play=False)
|
||||||
|
self.recording=False
|
||||||
|
|
||||||
# Sounds from https://mixkit.co/free-sound-effects/notification/
|
# Sounds from https://mixkit.co/free-sound-effects/notification/
|
||||||
def hotkey_record_trigger(self):
|
def hotkey_record_trigger(self):
|
||||||
|
|
||||||
if self.recording:
|
if self.recording:
|
||||||
self.play_sound('assets/mixkit-message-pop-alert-2354.mp3')
|
self.play_sound('assets/pop.wav')
|
||||||
self.submit_text()
|
self.submit_text()
|
||||||
else:
|
else:
|
||||||
|
|
||||||
input_device_index = self.input_device_index.get() # Assuming input_device_index is a StringVar
|
if not self.recording:
|
||||||
input_device_id = self.available_input_devices.get(input_device_index)
|
self.start_recording(play_confirm_sound=True)
|
||||||
if input_device_id is None:
|
else:
|
||||||
self.play_sound('assets/please-select-input.wav')
|
self.stop_recording(auto_play=True)
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.play_sound('assets/mixkit-message-pop-alert-2354.mp3')
|
|
||||||
self.toggle_recording()
|
|
||||||
|
|
||||||
|
|
||||||
def play_sound(self, sound_file):
|
def play_sound(self, sound_file):
|
||||||
pygame.init()
|
player = AudioPlayer(self.resource_path(sound_file))
|
||||||
pygame.mixer.init()
|
player.play(block=True)
|
||||||
sound = pygame.mixer.Sound(sound_file)
|
|
||||||
sound.play()
|
def resource_path(self, relative_path):
|
||||||
|
"""Get the absolute path to the resource, works for development and PyInstaller."""
|
||||||
|
try:
|
||||||
|
# When running in a PyInstaller bundle, use the '_MEIPASS' directory
|
||||||
|
base_path = sys._MEIPASS
|
||||||
|
except AttributeError:
|
||||||
|
# When running live, use the directory where this file is located
|
||||||
|
base_path = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
return os.path.join(base_path, relative_path)
|
||||||
|
|
||||||
|
return os.path.join(base_path, relative_path)
|
||||||
|
|
||||||
def initialize_gui(self):
|
def initialize_gui(self):
|
||||||
|
|
||||||
@@ -233,13 +246,13 @@ class Application(tk.Tk):
|
|||||||
instruction_window.geometry("400x300") # Width x Height
|
instruction_window.geometry("400x300") # Width x Height
|
||||||
|
|
||||||
instructions = """How to use Hotkeys
|
instructions = """How to use Hotkeys
|
||||||
ctrl+shift+r
|
ctrl+shift+0
|
||||||
This starts a recording, then converts to text and plays when you press this hotkey again.
|
This starts a recording, then converts to text and plays when you press this hotkey again.
|
||||||
|
|
||||||
ctrl+shift+s
|
ctrl+shift+9
|
||||||
If you are recording, you can press this hotkey to stop recording without playing
|
If you are recording, you can press this hotkey to stop recording without playing
|
||||||
|
|
||||||
ctrl+shift+l
|
ctrl+shift+8
|
||||||
This replays the last audio clip played
|
This replays the last audio clip played
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -618,16 +631,19 @@ https://www.scorchsoft.com/blog/text-to-mic-for-meetings/
|
|||||||
def stop_recording_btn_change(self, btn_text):
|
def stop_recording_btn_change(self, btn_text):
|
||||||
self.record_button.config(text=btn_text)
|
self.record_button.config(text=btn_text)
|
||||||
|
|
||||||
def start_recording(self):
|
|
||||||
|
def start_recording(self, play_confirm_sound=False):
|
||||||
|
|
||||||
input_device_index = self.input_device_index.get() # Assuming input_device_index is a StringVar
|
input_device_index = self.input_device_index.get() # Assuming input_device_index is a StringVar
|
||||||
input_device_id = self.available_input_devices.get(input_device_index)
|
input_device_id = self.available_input_devices.get(input_device_index)
|
||||||
|
|
||||||
if input_device_id is None:
|
if input_device_id is None:
|
||||||
messagebox.showerror("Error", "Selected audio device is not available.")
|
if play_confirm_sound:
|
||||||
|
self.play_sound('assets/please-select-input.wav')
|
||||||
|
else:
|
||||||
|
messagebox.showerror("Error", "Selected audio device is not available.")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
device_info = self.get_device_info(input_device_id)
|
device_info = self.get_device_info(input_device_id)
|
||||||
sample_rate = int(device_info['defaultSampleRate'])
|
sample_rate = int(device_info['defaultSampleRate'])
|
||||||
|
|
||||||
@@ -653,6 +669,8 @@ https://www.scorchsoft.com/blog/text-to-mic-for-meetings/
|
|||||||
self.p = pyaudio.PyAudio()
|
self.p = pyaudio.PyAudio()
|
||||||
self.stream = self.p.open(format=pyaudio.paInt16, channels=1, rate=sample_rate, input=True, frames_per_buffer=1024, input_device_index=input_device_id)
|
self.stream = self.p.open(format=pyaudio.paInt16, channels=1, rate=sample_rate, input=True, frames_per_buffer=1024, input_device_index=input_device_id)
|
||||||
|
|
||||||
|
if play_confirm_sound:
|
||||||
|
self.play_sound('assets/pop.wav')
|
||||||
|
|
||||||
def record():
|
def record():
|
||||||
while self.recording:
|
while self.recording:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ a = Analysis(
|
|||||||
['text-to-mic.py'],
|
['text-to-mic.py'],
|
||||||
pathex=[],
|
pathex=[],
|
||||||
binaries=[],
|
binaries=[],
|
||||||
datas=[],
|
datas=[('assets', 'assets')],
|
||||||
hiddenimports=[],
|
hiddenimports=[],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
hooksconfig={},
|
hooksconfig={},
|
||||||
@@ -29,7 +29,7 @@ exe = EXE(
|
|||||||
upx=True,
|
upx=True,
|
||||||
upx_exclude=[],
|
upx_exclude=[],
|
||||||
runtime_tmpdir=None,
|
runtime_tmpdir=None,
|
||||||
console=False,
|
console=True,
|
||||||
disable_windowed_traceback=False,
|
disable_windowed_traceback=False,
|
||||||
argv_emulation=False,
|
argv_emulation=False,
|
||||||
target_arch=None,
|
target_arch=None,
|
||||||
|
|||||||
Reference in New Issue
Block a user