Last active
July 20, 2021 10:25
-
-
Save PaulleDemon/f6521bbd8de852ac0c8fd4d0da6f0b85 to your computer and use it in GitHub Desktop.
PyQt/PySide with speech_recognition
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# MIT License | |
# | |
# Copyright (c) 2021 Paul | |
# | |
# Permission is hereby granted, free of charge, to any person obtaining a copy | |
# of this software and associated documentation files (the "Software"), to deal | |
# in the Software without restriction, including without limitation the rights | |
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
# copies of the Software, and to permit persons to whom the Software is | |
# furnished to do so, subject to the following conditions: | |
# | |
# The above copyright notice and this permission notice shall be included in all | |
# copies or substantial portions of the Software. | |
# | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
# SOFTWARE. | |
import sys | |
import speech_recognition as sr | |
from PySide2 import QtWidgets, QtCore, QtGui | |
# Note: if you get os error while running speech to text it might be because of you microphone or privacy setting | |
class Assistant(QtWidgets.QWidget): | |
def __init__(self, *args, **kwargs): | |
super(Assistant, self).__init__(*args, **kwargs) | |
self.setLayout(QtWidgets.QVBoxLayout()) | |
self.microphone_id = 0 | |
self.listening = False | |
mic_lst = sr.Microphone.list_microphone_names() | |
self.select_mic = QtWidgets.QComboBox() | |
self.select_mic.addItems(mic_lst) | |
self.select_mic.currentIndexChanged.connect(self.setMicIndex) | |
self.listen_btn = QtWidgets.QPushButton("Listen") | |
self.listen_btn.setCheckable(True) | |
self.listen_btn.clicked.connect(self.toggleListen) | |
self.speech_lbl = QtWidgets.QLabel() | |
self.layout().addWidget(self.select_mic) | |
self.layout().addWidget(self.listen_btn) | |
self.layout().addWidget(self.speech_lbl) | |
def setMicIndex(self, index): # Changes the mic | |
self.microphone_id = index | |
print(self.microphone_id) | |
def toggleListen(self, listen: bool): | |
if listen: | |
self.startListening() | |
else: | |
self.terminateListening() | |
def startListening(self): | |
self.speech_lbl.clear() | |
self.stt = SpeechToText(self.microphone_id) # important to make it an instance/global variable else thread will be destroyed when running | |
self.stt.messageAdded.connect(self.speech_lbl.setText) | |
self.stt.errorMessage.connect(self.speech_lbl.setText) | |
self.stt.started.connect(self.starting) # updates button label when thread starts | |
self.stt.finished.connect(self.stop) # updates button label when thread is finished | |
self.stt.start() | |
def starting(self): | |
self.listen_btn.setChecked(True) | |
self.listen_btn.setText("Listening...") | |
self.listening = True | |
def stop(self): | |
self.listen_btn.setChecked(False) | |
self.listen_btn.setText("Listen") | |
self.listening = False | |
def terminateListening(self): | |
if self.listening: | |
self.stt.terminate() | |
self.stt.wait() | |
self.stop() | |
def closeEvent(self, event: QtGui.QCloseEvent) -> None: | |
self.terminateListening() | |
super(Assistant, self).closeEvent(event) | |
class SpeechToText(QtCore.QThread): | |
messageAdded = QtCore.Signal(str) | |
errorMessage = QtCore.Signal(str) | |
def __init__(self, device_id=0, sample_rate=48000, chunk_size=2048, *args, **kwargs): | |
super(SpeechToText, self).__init__(*args, **kwargs) | |
self.device_id = device_id | |
self.sample_rate = sample_rate | |
self.chunk_size = chunk_size | |
# self.start() | |
def run(self) -> None: | |
# link to speech_to _text source: https://www.geeksforgeeks.org/python-convert-speech-to-text-and-text-to -speech/ | |
r = sr.Recognizer() | |
# while not self.isInterruptionRequested(): | |
with sr.Microphone(device_index=self.device_id, sample_rate=self.sample_rate, | |
chunk_size=self.chunk_size) as source: | |
# wait for a second to let the recognizer adjust the | |
# energy threshold based on the surrounding noise level | |
r.adjust_for_ambient_noise(source) | |
# listens for the user's input | |
audio = r.listen(source) | |
try: | |
text = r.recognize_google(audio) | |
self.messageAdded.emit(text) | |
# error occurs when google could not understand what was said | |
except sr.UnknownValueError: | |
self.errorMessage.emit("Google Speech Recognition could not understand audio") | |
# print("Google Speech Recognition could not understand audio") | |
except sr.RequestError as e: | |
self.errorMessage.emit("Could not request results from Google Speech Recognition service;{0}".format(e)) | |
# print("Could not request results from Google Speech Recognition service;{0}".format(e)) | |
print("Finished") | |
if __name__ == "__main__": | |
app = QtWidgets.QApplication(sys.argv) | |
win = Assistant() | |
win.show() | |
sys.exit(app.exec_()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment