Clipboard to TTS
A very rough bit of code for Windows to generate TTS from any text sent to the WINDOWS clipboard with Ctrl+C
This commit is contained in:
1 parent
0f26ca4bbf
commit
d542e6ba14
3 files changed
+178
No files matched your search
@@ -0,0 +1,167 @@
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
import pyperclip
|
||||
import requests
|
||||
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMenu, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton
|
||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
|
||||
from PyQt5.QtGui import QIcon
|
||||
|
||||
class ClipboardMonitor(QThread):
|
||||
text_changed = pyqtSignal(str)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.last_text = pyperclip.paste()
|
||||
self.running = True
|
||||
|
||||
def run(self):
|
||||
while self.running:
|
||||
current_text = pyperclip.paste()
|
||||
if current_text != self.last_text:
|
||||
self.text_changed.emit(current_text)
|
||||
self.last_text = current_text
|
||||
time.sleep(0.5)
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
class TTSWorker(QThread):
|
||||
def __init__(self, api_url, params):
|
||||
super().__init__()
|
||||
self.api_url = api_url
|
||||
self.params = params
|
||||
self.text_queue = []
|
||||
|
||||
def add_text(self, text):
|
||||
self.text_queue.append(text)
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
if self.text_queue:
|
||||
text = self.text_queue.pop(0)
|
||||
self.send_to_tts(text)
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
|
||||
def send_to_tts(self, text):
|
||||
params = self.params.copy()
|
||||
params["text_input"] = text
|
||||
try:
|
||||
response = requests.post(self.api_url, data=params)
|
||||
if response.status_code != 200:
|
||||
print(f"TTS generation failed with status code: {response.status_code}")
|
||||
except requests.RequestException as e:
|
||||
print(f"Error sending request to TTS API: {e}")
|
||||
|
||||
class SettingsWindow(QWidget):
|
||||
def __init__(self, tts_worker):
|
||||
super().__init__()
|
||||
self.tts_worker = tts_worker
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
layout = QVBoxLayout()
|
||||
self.setLayout(layout)
|
||||
|
||||
layout.addWidget(QLabel("TTS API URL:"))
|
||||
self.api_url_input = QLineEdit(self.tts_worker.api_url)
|
||||
layout.addWidget(self.api_url_input)
|
||||
|
||||
layout.addWidget(QLabel("Voice:"))
|
||||
self.voice_input = QLineEdit(self.tts_worker.params["character_voice_gen"])
|
||||
layout.addWidget(self.voice_input)
|
||||
|
||||
save_button = QPushButton("Save")
|
||||
save_button.clicked.connect(self.save_settings)
|
||||
layout.addWidget(save_button)
|
||||
|
||||
self.setWindowTitle("TTS Settings")
|
||||
self.setGeometry(300, 300, 300, 150)
|
||||
|
||||
def save_settings(self):
|
||||
self.tts_worker.api_url = self.api_url_input.text()
|
||||
self.tts_worker.params["character_voice_gen"] = self.voice_input.text()
|
||||
self.close()
|
||||
|
||||
class TTSApp(QSystemTrayIcon):
|
||||
def __init__(self, app):
|
||||
super().__init__(parent=app)
|
||||
self.app = app
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
self.tts_worker = TTSWorker(
|
||||
api_url="http://127.0.0.1:7851/api/tts-generate",
|
||||
params={
|
||||
"text_filtering": "standard",
|
||||
"character_voice_gen": "female_01.wav",
|
||||
"language": "en",
|
||||
"output_file_name": "clipboard_tts",
|
||||
"output_file_timestamp": "true",
|
||||
"autoplay": "true",
|
||||
"autoplay_volume": "0.8"
|
||||
}
|
||||
)
|
||||
self.tts_worker.start()
|
||||
|
||||
self.clipboard_monitor = ClipboardMonitor()
|
||||
self.clipboard_monitor.text_changed.connect(self.on_text_changed)
|
||||
|
||||
self.setIcon(QIcon("icon.png"))
|
||||
self.setVisible(True)
|
||||
|
||||
menu = QMenu()
|
||||
start_action = menu.addAction("Start Monitoring")
|
||||
start_action.triggered.connect(self.start_monitoring)
|
||||
stop_action = menu.addAction("Stop Monitoring")
|
||||
stop_action.triggered.connect(self.stop_monitoring)
|
||||
settings_action = menu.addAction("Settings")
|
||||
settings_action.triggered.connect(self.show_settings)
|
||||
exit_action = menu.addAction("Exit")
|
||||
exit_action.triggered.connect(self.exit_app)
|
||||
self.setContextMenu(menu)
|
||||
|
||||
self.settings_window = SettingsWindow(self.tts_worker)
|
||||
|
||||
def on_text_changed(self, text):
|
||||
self.tts_worker.add_text(text)
|
||||
|
||||
def start_monitoring(self):
|
||||
self.clipboard_monitor.start()
|
||||
self.showMessage("TTS App", "Clipboard monitoring started")
|
||||
|
||||
def stop_monitoring(self):
|
||||
self.clipboard_monitor.stop()
|
||||
self.showMessage("TTS App", "Clipboard monitoring stopped")
|
||||
|
||||
def show_settings(self):
|
||||
self.settings_window.show()
|
||||
|
||||
def exit_app(self):
|
||||
self.clipboard_monitor.stop()
|
||||
self.tts_worker.quit()
|
||||
QApplication.instance().quit()
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
QApplication.instance().quit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("[AllTalk TTS] AllTalk Clipboard to TTS is starting...")
|
||||
print("[AllTalk TTS] Press Ctrl+C to exit")
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
if not QSystemTrayIcon.isSystemTrayAvailable():
|
||||
print("System tray is not available on this system.")
|
||||
sys.exit(1)
|
||||
|
||||
tts_app = TTSApp(app)
|
||||
|
||||
# This allows for Ctrl+C to work
|
||||
timer = QTimer()
|
||||
timer.start(500)
|
||||
timer.timeout.connect(lambda: None)
|
||||
|
||||
sys.exit(app.exec_())
|
||||
Reference in new issue
Block a user