LISHUZUOXUN_yangjiang/Speaker/_speak_base_win32.py

156 lines
4.3 KiB
Python
Raw Normal View History

2024-09-23 14:54:15 +08:00
import threading
import time
import winsound
import pyttsx3
try:
pyttsx3.speak("..")
except:
pass
def beep(duration=700, freq=640):
winsound.Beep(freq, duration)
class SpeakServer:
thread = None # background thread that reads frames from camera
engine = None
__flag = threading.Event() # 用于暂停线程的标识
__flag.clear() # 设置为True
__running = threading.Event() # 用于停止线程的标识
__running.set() # 将running设置为True
__had_data = threading.Event()
__had_data.clear()
speak_list = []
is_pause = True
BASE_SPEED = 200
MAX_SPEED = 320
speed_set = BASE_SPEED
speed_now = BASE_SPEED
def __new__(cls):
if not cls.thread:
# start background frame thread
cls.thread = threading.Thread(target=cls._thread, daemon=True)
cls.thread.start()
return super().__new__(cls)
def start(self):
pass
@staticmethod
def add_speak(data):
SpeakServer.speak_list.append(data)
SpeakServer.__had_data.set()
@classmethod
def check_list(cls):
if not cls.speak_list:
return True
else:
return False
@classmethod
def wait_4_speak(cls):
while not cls.check_list():
time.sleep(0.1)
@staticmethod
def speed_control(rate):
while not SpeakServer.engine:
time.sleep(0.5)
try:
SpeakServer.engine.setProperty('rate', rate)
SpeakServer.speed_set = rate
SpeakServer.speed_now = rate
except:
return
@staticmethod
def set_temp_speed(rate):
while not SpeakServer.engine:
time.sleep(0.5)
try:
SpeakServer.engine.setProperty('rate', rate)
SpeakServer.speed_now = rate
except:
return
@staticmethod
def volume_control(volume):
while not SpeakServer.engine:
time.sleep(0.5)
try:
SpeakServer.engine.setProperty('volume', volume)
except:
return
@staticmethod
def save_to_file(text, output_path):
while True:
try:
SpeakServer.engine = pyttsx3.init()
break
except:
time.sleep(1)
SpeakServer.engine.save_to_file(text, output_path)
SpeakServer.engine.runAndWait()
@classmethod
def _thread(cls):
while True:
try:
cls.engine = pyttsx3.init()
break
except:
time.sleep(1)
while SpeakServer.__running.is_set():
SpeakServer.__had_data.wait()
while cls.speak_list:
try:
temp_speak = cls.speak_list[0]
# 语速控制
if len(cls.speak_list) >= 2:
speak_len = len("".join([str(s) for s in cls.speak_list]))
if speak_len > 10:
speak_speed = cls.BASE_SPEED + min(speak_len, 30) / 30 * (cls.MAX_SPEED - cls.BASE_SPEED)
cls.set_temp_speed(speak_speed)
else:
if cls.speed_now != cls.speed_set:
cls.speed_control(cls.speed_set)
else:
cls.speed_control(cls.speed_set)
cls.engine.say("{}".format(temp_speak))
cls.engine.runAndWait()
cls.speak_list.pop(0)
except Exception as e:
print('speak machine error:', e)
time.sleep(0.1)
SpeakServer.__had_data.clear()
SpeakServer.thread = None
@classmethod
def wait(cls):
cls.__flag.wait()
@classmethod
def pause(cls):
if not cls.is_pause:
cls.__flag.clear() # 设置为False, 让线程阻塞
cls.is_pause = True
@classmethod
def resume(cls):
if cls.is_pause:
cls.__flag.set() # 设置为True, 让线程停止阻塞
cls.is_pause = False
@classmethod
def stop(cls):
return
# cls.__flag.set() # 将线程从暂停状态恢复, 如何已经暂停的话
# cls.__running.clear() # 设置为False