(二十)AI同声传译、AI语音识别、AI文本翻译、AI实时翻译、AI文本转语音、AI声纹识别、AI男女声识别

(二十)AI同声传译、AI语音识别、AI文本翻译、AI实时翻译、AI文本转语音、AI声纹识别、AI男女声识别

本文应用的AI技术较多,包括AI语音识别、AI文本翻译、AI文本转语音、AI声纹识别、男女声识别等。
AI语音识别:将英文或中文语音收录,然后发送到AI识别线程,转成文本;
AI文本翻译:将上述翻译的文本发给AI文本翻译线程,得到翻译后的文本;
AI文本转语音:将上诉翻译后的文本发给AI文本转语音线程,得到语音数据,然后将语音数据发送到扬声器发音;
AI声纹识别:由于原语音有男女声音,特别加入了AI声纹男女声识别线程,自动识别后,选择相应的男女声腔发音。

由于原本的依赖库模块都是把声音文件存盘再除处理,为了防止磁盘频繁访问、加快处理效率,本文修改了一些依赖库的文件。对此文感兴趣的可以加微深入探讨:herbert156

可运行的软件打包上传了网盘,下载说明如下:
1、先下载AI_Translate.exe可执行文件,执行安装。注意:安装的目录不能包含中文;
2、以上安装的软件只包含tiny、base、small三个小的模型,还有2个大的模型:Medium、Large;
3、如果想使用较大的模型(Medium、Large)请下载百度网盘里【model_faster_whisper】目录里的文件,拷贝在【AI_Translate\model_faster_whisper】下即可。
4、百度网盘链接: https://pan.baidu.com/s/1z3IH7eL4Fl8XpGQoOCM7Sw
提取码: 4ek5

软件界面:
在这里插入图片描述

话不多说上代码:
一、运行代码:

#AI同声传译具V1.0
import asyncio
import audioop, cv2
import io, time, traceback, wave

import edge_tts
import numpy as np
import os, sys, threading
from datetime import datetime, timedelta
import http.client, win32api, win32con
import configparser as configparser
from queue import Queue

import whisper
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QWidget, QMessageBox, QApplication, QColorDialog, QFontDialog, QLabel, QDesktopWidget, \
    QSlider
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QFont, QColor, QIcon, QFontMetrics
from AI_Translate_UI import Ui_trans
from PIL import Image,ImageDraw,ImageFont
from pydub import AudioSegment

from xgboost import XGBClassifier
import gender_predict.config as cfg
import pickle
from gender_predict.utils import extract_features

pil_img = Image.open("start_img.jpg")
ImageDraw.Draw(pil_img).text((410,200), 'AI同声传译 v1.0', (255,255,255),font=ImageFont.truetype("msyh.ttc", 18))
ImageDraw.Draw(pil_img).text((410,330), "正在加载AI模型,请稍后 ......", (255,255,255),font=ImageFont.truetype("msyh.ttc", 16))
img_s = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
all_thread_exit = False
run_flag = 0
delay_2 = 0.0
delay_3 = 0.0
delay_4 = 0.0

def showpic():  # 以下代码显示软件初始界面
    global ret, frame
    while run_flag == 0:
        cv2.imshow("AI Translate System(Based on OpenAI)", img_s)
        cv2.waitKey(100)
    cv2.destroyAllWindows()
t = threading.Thread(target=showpic)
t.start()

is_faster = True
is_Argos = True

import pyaudio, torch, yaml, zhconv
from faster_whisper import WhisperModel
if not is_Argos: from transformers import MarianMTModel, MarianTokenizer
from argostranslate import package
import argostranslate.translate

def is_contains_chinese():  #运行目录不能包含中文
    strs = os.getcwd()
    for _char in strs:
        if '\u4e00' <= _char <= '\u9fa5':
            win32api.MessageBox(0, f"软件安装目录【{strs}】不能包含中文,\n请移动到其他目录再运行......", '运行错误提示', win32con.MB_OK)
            sys.exit()

def get_web_time(host): #获取网络时间,并设置系统时间
    try:
        conn=http.client.HTTPConnection(host,timeout=20)
        conn.request("GET", "/")
        r=conn.getresponse()
    except:
        win32api.MessageBox(0, f"网络连接超时,您必须链接网络才能使用本软件...", '运行错误提示', win32con.MB_OK); sys.exit()
    ts=  r.getheader('date') #获取http头date部分
    ltime= time.strptime(ts[5:25], "%d %b %Y %H:%M:%S")   #将GMT时间转换成北京时间
    ttime=time.localtime(time.mktime(ltime)+8*60*60)
    date = "%u%02u%02u" % (ttime.tm_year, ttime.tm_mon, ttime.tm_mday)
    return date

is_contains_chinese()

stop_flag = False
run_flag = 0

settings_file = "settings.yaml"   #读取配置文件icanx_settings.yaml
settings = {
    
    }
if os.path.exists(settings_file):
    with open(settings_file, 'r') as f:
        settings = yaml.safe_load(f)
if settings == None:    # Happens if the file is empty.
    settings = {
    
    }
default_font_family = settings.get('default_font_family', '微软雅黑')
default_font_size = settings.get('default_font_size', 12)
default_model = settings.get('default_model', 3)
default_bk_Color = settings.get('default_bk_Color', '#000000')
default_fr_Color = settings.get('default_fr_Color', '#ffffff')
show_bottom = settings.get('show_bottom', True)
show_win_w = settings.get('show_win_w', 1280)
show_win_h = settings.get('show_win_h', 50)
show_win_x = settings.get('show_win_x', 0)
show_win_y = settings.get('show_win_y', 50)
main_win_x = settings.get('main_win_x', 100)
main_win_y = settings.get('main_win_y', 200)
play_switch_flag = settings.get('play_switch_flag', True)
gender_predict_flag = 0

language = 'en'; en_zh = True
rates = '+0%'; vol = '+0%'
model_list = ['tiny', 'base', 'small', 'medium', 'large']
if model_list[default_model] == 'large': model_dir = ".\model_faster_whisper\whisper-" + model_list[default_model]
else: model_dir = ".\model_faster_whisper\whisper-" + model_list[default_model] + '-en'
if not os.path.exists(model_dir):
    model_dir = ".\model_faster_whisper\whisper-base-en"
    default_model = 1; print("默认的模型不存在,改为:whisper-base-en模型...")

os.environ['ARGOS_DEVICE_TYPE'] = 'auto'    #自动使用GPU进行文字翻译

if torch.has_cuda: gpu_ok = True; device = "cuda"   #检查是否有可用的GPU
else: gpu_ok = False; device = "cpu"

data_queue = Queue()    #音频采集队列
text_queue = Queue()    #字符输出队列
speak_queue = Queue()   #音频播放队列
gender_queue = Queue()   #性别识别队列

#遍历可用得音频输入设备
pa = pyaudio.PyAudio()
microphones = []; mic_list = []; VB_Audio = False
for i in range(pa.get_device_count()):
    device_info = pa.get_device_info_by_index(i)
    if device_info['maxInputChannels'] > 0 and device_info['hostApi'] == 0 and 'Microsoft' not in device_info['name']:
        microphones.append((device_info['index'],device_info['name']))
        mic_list.append(device_info['name'])
print('可用的音频输入设备:', microphones)
if microphones: device_index = microphones[0][0]
else:
    win32api.MessageBox(0, f"信息提示:没有发现可用的音频输入设备,软件无法采集声音;\n"
                           f"解决办法:请在目录[混音器安装]中点击[VoicemeeterSetup.exe]安装混音器。", '运行提示', win32con.MB_OK)
    run_flag = 1; sys.exit()

if not microphones: device_index = microphones[0][0]
for i in range(len(mic_list)):
    if 'VB-Audio' in mic_list[i]: VB_Audio = True; device_index = microphones[i][0];break
if not VB_Audio:
    win32api.MessageBox(0, f"信息提示:没有在音频输入设备列表中发现混音器,软件无法采集系统声音;\n"
                           f"解决办法:请在目录[混音器安装]中点击[VoicemeeterSetup.exe]安装混音器。", '运行提示', win32con.MB_OK)
#遍历可用得音频播放设备
speaks = []; speak_list = []
# default_speak = pa.get_default_output_device_info()
# if default_speak:
#     speaks = [(default_speak['index'],'系统默认')]
#     speak_list = ['系统默认']
for i in range(pa.get_device_count()):
    device_info = pa.get_device_info_by_index(i)
    if device_info['maxOutputChannels'] > 0 and device_info['hostApi'] == 0 and 'Microsoft' not in device_info['name']:
        speaks.append((device_info['index'],device_info['name']))
        speak_list.append(device_info['name'])
print('可用的音频播放设备:', speaks)
if speaks: speak_device_index = speaks[0][0]
else:
    win32api.MessageBox(0, f"信息提示:没有发现可用的音频播放设备,软件无法播放声音;\n"
                           f"解决办法:请插入耳机或者外接扬声器。", '运行提示', win32con.MB_OK)
    run_flag = 1; sys.exit()
pa.terminate()

max_energy = 5000
sample_rate = 16000
chunk_size = 1024
max_int16 = 2 ** 15
out_voice_model = "zh-CN-YunjianNeural"

my_title = "iCANX同声传译"

# faster_model: WhisperModel = None   #模型全局变量

class GenderPredict(QThread):
    # sinout = pyqtSignal(str)
    def __init__(self, winshot):
        super(GenderPredict, self).__init__()
        self.main_win = winshot

        self.MODEL = XGBClassifier()
        self.MODEL.load_model(cfg.MODEL_PATH)

    def run(self):
        global stop_flag, out_voice_model, delay_4
        last_res = 0.8
        while not stop_flag:
            if not gender_queue.empty() and gender_predict_flag == 0:
                # print('性别队列长度:', gender_queue.qsize())
                t0 = time.time()
                wav_data = gender_queue.get(block=False)
                wav_data.seek(0)
                audio_file = io.BytesIO(wav_data.read())
                audio_file.seek(0)
                result = self.audio_prediction(audio_file)

                mean_result = (last_res + result)/2
                last_res = result
                delay_4 = time.time() - t0

                if mean_result > 0.5: is_man_voice = True; self.main_win.man_wuman_show.setText('->男音')
                else: is_man_voice = False; self.main_win.man_wuman_show.setText('->女音')
                # print(result)

                if is_man_voice:
                    if self.main_win.language.currentIndex() == 0: out_voice_model = "zh-CN-YunjianNeural"
                    else: out_voice_model = "en-US-ChristopherNeural"
                else:
                    if self.main_win.language.currentIndex() == 0: out_voice_model = "zh-CN-XiaoxiaoNeural"
                    else: out_voice_model = "en-US-MichelleNeural"

            time.sleep(0.1)

        self.MODEL = None
        while not gender_queue.empty(): data = gender_queue.get()
        print('退出线程:GenderPredict...')

    def audio_prediction(self, audio_file):
        feats = extract_features(audio_file, mel=True, mfcc=True, chroma=True, contrast=True)
        scaler = pickle.load(open(cfg.SCALAR_PATH, 'rb'))
        X = scaler.transform(feats.reshape(1, -1))
        pred = self.MODEL.predict_proba(X)
        return pred[0][1]

class EdgeTTSTrans(QThread):
    # sinout = pyqtSignal(str)
    def __init__(self, winshot):
        super(EdgeTTSTrans, self).__init__()
        self.main_win = winshot
        self.rates = rates

    def run(self):
        global stop_flag, text_queue, speak_queue, delay_3

        while not stop_flag:
            # print('字符队列长度:', text_queue.qsize())
            if not text_queue.empty() and play_switch_flag:
                q_size = speak_queue.qsize()
                # print(q_size)
                if q_size == 2:
                    self.rates = '+20%'; self.main_win.Text_10.setText('语速(+20%)'); self.main_win.rates_slider.setValue(20)
                elif q_size == 3:
                    self.rates = '+30%'; self.main_win.Text_10.setText('语速(+30%)'); self.main_win.rates_slider.setValue(30)
                elif q_size == 4:
                    self.rates = '+40%'; self.main_win.Text_10.setText('语速(+40%)'); self.main_win.rates_slider.setValue(40)
                elif q_size >= 5:
                    self.rates = '+60%'; self.main_win.Text_10.setText('语速(+60%)'); self.main_win.rates_slider.setValue(60)
                else:
                    self.rates = '+0%'; self.main_win.Text_10.setText(f'语速(0%)')
                    self.main_win.rates_slider.setValue(0)

                t0 = time.time()
                text = text_queue.get(block=False)
                # print('翻译:', text)
                asyncio.run(self.edge_tts_trans(text))
                delay_3 = time.time() - t0

            time.sleep(0.1)

        while not text_queue.empty(): data = text_queue.get()
        print('退出线程:EdgeTTSTrans...')

    async def edge_tts_trans(self, text):
        communicate = edge_tts.Communicate(text=text, rate=self.rates, volume=vol, voice=out_voice_model)
        try:
            mp3_audio = await communicate.save()
            mp3_audio.seek(0)
            song = AudioSegment.from_file(mp3_audio, format='mp3')
            wav_file = io.BytesIO()
            song.export(wav_file, format="wav")
            speak_queue.put(wav_file)
        except: traceback.print_exc()

class PlayAudioWav(QThread):
    # sinout = pyqtSignal(str)
    def __init__(self, winshot):
        super(PlayAudioWav, self).__init__()
        self.main_win = winshot
        self.play_out = pyaudio.PyAudio()

    def run(self):
        global stop_flag, speak_device_index, speak_queue
        while not stop_flag:
            if not speak_queue.empty() and play_switch_flag:
                # print('播放队列长度:', speak_queue.qsize())
                wave_file = speak_queue.get(block=False)
                wf = wave.open(wave_file, 'rb')

                def callback(in_data, frame_count, time_info, status):
                    data = wf.readframes(frame_count)
                    return (data, pyaudio.paContinue)
                stream = self.play_out.open(format=8, channels=1, rate=24000, output=True,
                                            output_device_index=speak_device_index, stream_callback=callback)
                stream.start_stream()
                while stream.is_active() and not stop_flag: time.sleep(0.1)
            time.sleep(0.1)

        if not stop_flag:
            stream.stop_stream()
            stream.close()

        self.play_out.terminate()
        while not speak_queue.empty(): data = speak_queue.get()
        print('退出线程:PlayAudioWav...')

class TransateThread(QThread):
    # sinout = pyqtSignal(str)
    def __init__(self, winshot):
        super(TransateThread, self).__init__()
        self.main_win = winshot

    def run(self):
        global stop_flag, data_queue, all_thread_exit
        next_transcribe_time = None
        transcribe_rate_seconds = 0.5
        transcribe_rate = timedelta(seconds=transcribe_rate_seconds)
        max_record_time = 15
        silence_time = 0.5
        last_sample = bytes()
        samples_with_silence = 0
        silence_energy = 500
        task = 'transcribe'
        silence_flag = True
        complete_text = ''
        out_str = ''
        last_play_txt = ''
        text = ''

        if is_faster:
            self.faster_model = WhisperModel(model_dir,
                                        device=device, compute_type="int8",
                                        num_workers=1, local_files_only=True)
            if not self.faster_model: print('模型载入失败...')
            else: print('模型载入成功(faster_model)...')
        else:
            audio_model = whisper.load_model('base.en', device, download_root='./model_whisper')
            if not audio_model: print('模型载入失败...')
            else: print('模型载入成功(whisper_model) ...')

        self.main_win.my_long_win.up_show.setText(' Waiting the voice...')
        self.main_win.my_long_win.down_show.setText(' 正在等待声音传入...')

        while not stop_flag:    # Main loop. Wait for data from the recording thread at transcribe it.
            if not data_queue.empty():
                now = datetime.utcnow()
                if not next_transcribe_time:    # Set next_transcribe_time for the first time.
                    next_transcribe_time = now + transcribe_rate
                # Only run transcription occasionally. This reduces stress on the GPU and makes transcriptions
                # more accurate because they have more audio context, but makes the transcription less real time.
                if now > next_transcribe_time:
                    next_transcribe_time = now + transcribe_rate

                    phrase_complete = False
                    while not data_queue.empty():
                        data = data_queue.get()
                        energy = audioop.rms(data, self.main_win.pa.get_sample_size(pyaudio.paInt16))
                        if energy < silence_energy: samples_with_silence += 1
                        else: samples_with_silence = 0

                        # If we have encounter enough silence, restart the buffer and add a new line.
                        if samples_with_silence > sample_rate / chunk_size * silence_time:
                            phrase_complete = True
                            silence_flag = True
                            last_sample = bytes()
                            # print('静音片段...')
                        else: silence_flag = False
                        last_sample += data

                    # Write out raw frames as a wave file.
                    wav_file = io.BytesIO()
                    wav_writer: wave.Wave_write = wave.open(wav_file, "wb")
                    wav_writer.setframerate(sample_rate)
                    wav_writer.setsampwidth(self.main_win.pa.get_sample_size(pyaudio.paInt16))
                    wav_writer.setnchannels(1)
                    wav_writer.writeframes(last_sample)
                    wav_writer.close()

                    # Read the audio data, now with wave headers.
                    wav_file.seek(0)
                    wav_reader: wave.Wave_read = wave.open(wav_file)
                    samples = wav_reader.getnframes()
                    audio = wav_reader.readframes(samples)
                    wav_reader.close()

                    # Convert the wave data straight to a numpy array for the model.
                    # https://stackoverflow.com/a/62298670
                    audio_as_np_int16 = np.frombuffer(audio, dtype=np.int16)
                    audio_as_np_float32 = audio_as_np_int16.astype(np.float32)
                    audio_normalised = audio_as_np_float32 / max_int16

                    if not phrase_complete:
                        if is_faster:
                            t0 = time.time()
                            self.segments, info = self.faster_model.transcribe(audio_normalised, language=language, task=task,
                                                                    condition_on_previous_text=True,
                                                                    without_timestamps=True)
                            for segment in self.segments:
                                text = segment.text
                            delay_1 = time.time() - t0
                        else:
                            result = audio_model.transcribe(audio_normalised, language=language, task=task)
                            text = result['text'].strip()

                        # 文字长度超出显示显示边界后,断句、从新开始
                        # If we've reached our max recording time, it's time to break up the buffer, add an empty line after we edited the last line.
                        audio_length_in_seconds = samples / float(sample_rate)
                        if (self.main_win.metrics.width(text) > show_win_w - 100) or (audio_length_in_seconds > max_record_time):
                            phrase_complete = True
                            last_sample = bytes()
                            complete_text = complete_text + text
                            # print(complete_text)

                        len_text=len(text)
                        if len_text > 10: # 小于10个字符的英文不翻译
                            t0 = time.time()
                            if self.main_win.language.currentIndex() == 1:
                                text = zhconv.convert(text, 'zh-cn')
                                out_str = self.main_win.trans_text.translate([text])[0]      # 翻译句子
                            else: out_str = ' '+self.main_win.trans_text.translate([text])[0]
                            delay_2 = time.time() - t0

                            if en_zh and len(out_str) > len_text*3:      # 大于2倍字符的结果判定为错误
                                print('短句翻译错误:', text, '\n', out_str)
                                out_str = ''

                        self.main_win.my_long_win.up_show.setText(text)
                        # self.main_win.my_long_win.down_show.setText(out_str)
                        run_stat_text = (f"统计:语音转文字({delay_1:.2f}秒)|文字翻译({delay_2:.2f}秒)|"
                                         f"翻译转语音({delay_3:.2f}秒)|声纹识别({delay_4:.2f}秒)")
                        self.main_win.run_state.setText(run_stat_text)

                    audio_length_in_seconds = samples / float(sample_rate)
                    if audio_length_in_seconds > 5 and not silence_flag and gender_predict_flag == 0:
                        gender_queue.put(wav_file)      # 发性别识别对列

                    if phrase_complete and out_str != '' and last_play_txt != out_str:     # 播放语音
                        # self.main_win.my_long_win.up_show.setText(text)
                        self.main_win.my_long_win.down_show.setText(out_str)
                        last_play_txt = out_str
                        # print('原句:', text)
                        if play_switch_flag: text_queue.put(out_str)

            time.sleep(0.1)

        run_stat_text = (f"统计:语音转文字时延(0.00)秒)|文字翻译时延(0.00)|"
                         f"翻译转语音时延(0.00)秒)|声纹识别((0.00)")
        self.main_win.run_state.setText(run_stat_text)

        while not data_queue.empty(): data = data_queue.get()   # 清空队列里的数据
        self.main_win.stream.stop_stream()  # Stop Audio Recording
        self.main_win.stream.close()  # Close Audio Recording
        self.main_win.pa.terminate()  # Audio System Close

        # print("线程数(1):",threading.active_count())
        self.main_win.record_thread.wait()  # 等待录音线程结束
        self.main_win.tts_thread.wait()     # 等待TTS线程结束
        self.main_win.play_thread.wait()     # 等待Play线程结束
        # print("线程数(2):",threading.active_count())
        # try: torch.cuda.empty_cache()   #清空模型占用的GPU显存
        # except: traceback.print_exc()
        # faster_model = None
        print("退出线程:TransateThread(Main Loop)...")
        torch.cuda.empty_cache()
        Tensor = None
        self.main_win.set_True_Btn()
        all_thread_exit = True

class Translator:      #Marian翻译的类
    def __init__(self, source_lang: str, dest_lang: str) -> None:
        self.model_name = f'Helsinki-NLP/opus-mt-{source_lang}-{dest_lang}'
        if not is_Argos:
            self.model = MarianMTModel.from_pretrained(self.model_name)
            self.tokenizer = MarianTokenizer.from_pretrained(self.model_name)

    def translate(self, texts):
        tokens = self.tokenizer(list(texts), return_tensors="pt", padding=True)
        translate_tokens = self.model.generate(**tokens)
        return [self.tokenizer.decode(t, skip_special_tokens=True) for t in translate_tokens]

class TranslatorArgos:      #Argos翻译的类
    def __init__(self, source_lang: str, dest_lang: str) -> None:
        self.source_lang = source_lang
        self.dest_lang = dest_lang
        self.model_name = f'.\\Argos_model\\translate-{source_lang}_{dest_lang}-1_7.argosmodel'
        package.install_from_path(self.model_name)
    def translate(self, texts):
        self.translatedText = argostranslate.translate.translate(texts[0], self.source_lang, self.dest_lang)
        return [self.translatedText]

class long_win(QWidget):    #底条窗口的类
    def __init__(self, win_shot):
        super(long_win, self).__init__()
        self.main_win = win_shot
        global show_win_x, show_win_y, show_win_w, show_win_h

        screen = QDesktopWidget().screenGeometry()  # 获取屏幕大小
        if screen.width() <= show_win_w :
            show_win_w = screen.width() - 10

        desktop_count = QApplication.desktop().screenCount()
        if (desktop_count == 1 and
                (show_win_x < 0 or show_win_y < 0 or
                 show_win_x > screen.width() or show_win_y > screen.height())):
            show_win_x = 20; show_win_y = 20

        self.setWindowIcon(QIcon("ican48.ico"))
        self.setWindowFlags(Qt.CustomizeWindowHint|Qt.WindowCloseButtonHint|Qt.FramelessWindowHint)
        self.setStyleSheet("QWidget {background-color:%s}" % default_bk_Color)
        self.setWindowTitle("AI同声传译:翻译条")

        self.setGeometry(show_win_x, show_win_y, show_win_w, show_win_h)

        self.up_show = QLabel(' 源语言:', self)
        self.down_show = QLabel(' 翻译后:', self)
        self.up_show.setStyleSheet(f"color:{default_fr_Color}")
        self.down_show.setStyleSheet(f"color:{default_fr_Color}")
        self.up_show.setFont(QFont(default_font_family, default_font_size))
        self.down_show.setFont(QFont(default_font_family, default_font_size))

        self.up_show.move(5, 5)
        self.up_show.setFixedSize(show_win_w, int(show_win_h/2)-5)
        self.down_show.move(5, int(show_win_h/2))
        self.down_show.setFixedSize(show_win_w, int(show_win_h/2)-5)

        if self.main_win.show_bottom.isChecked(): self.show()

    def resizeEvent(self, event):
        global show_win_w, show_win_h
        show_win_w, show_win_h = event.size().width(), event.size().height()
        if show_win_h > 200: show_win_h = 200
        self.up_show.move(5, 5)
        self.up_show.setFixedSize(show_win_w, int(show_win_h/2)-5)
        self.down_show.move(5, int(show_win_h/2))
        self.down_show.setFixedSize(show_win_w, int(show_win_h/2)-5)
        self.update()

class recording_thread(QThread):
    sinout = pyqtSignal(str)
    def __init__(self, winshot, stream:pyaudio.Stream):
        super(recording_thread, self).__init__()
        self.main_win = winshot
        self.stream = stream
    def run(self):
        global max_energy, stop_flag, data_queue
        while not stop_flag:
            data = self.stream.read(chunk_size)     # We record as fast as possible so that we can update the volume bar at a fast rate.
            energy = audioop.rms(data, self.main_win.pa.get_sample_size(pyaudio.paInt16))
            if energy > max_energy:
                max_energy = energy
            cur_volume = min(energy / max_energy, 1.0)
            data_queue.put(data)
            self.sinout.emit(str(int(cur_volume*100)))
            time.sleep(0.05)
        while not data_queue.empty(): data = data_queue.get()
        print('退出线程:recording_thread...')

class Winshot(QWidget, Ui_trans):
    def __init__(self):
        super(Winshot, self).__init__()
        self.setupUi(self)
        global hwnd, run_flag, main_win_x, main_win_y

        palette1 = QtGui.QPalette()
        palette1.setColor(palette1.Background, QtGui.QColor(200, 200, 200))
        self.setWindowIcon(QIcon("ican48.ico"))

        screen = QDesktopWidget().screenGeometry()  # 获取屏幕大小
        desktop_count = QApplication.desktop().screenCount()
        if (desktop_count == 1 and
                (main_win_x < 0 or main_win_y < 0 or
                 main_win_x > screen.width() or main_win_y > screen.height())):
            main_win_x = 100; main_win_y = 200
        self.move(main_win_x, main_win_y)

        self.my_long_win = long_win(self)

        self.setFixedSize(self.size())

        self.createLayout()
        self.setPalette(palette1)
        self.setWindowTitle(my_title)
        self.setWindowFlags(Qt.WindowMinimizeButtonHint)

        self.show()
        run_flag = 1

    def recording_signal(self, str):
        self.volume_bar.setValue(int(str))

    def show_error(self,str):
        r_button = QMessageBox.question(self, my_title,'\n\n'+str+'\n\n', QMessageBox.Ok)
    def set_False_Btn(self):
        self.audio_mic.setEnabled(False)
        self.language.setEnabled(False)
        self.ai_model.setEnabled(False)
        self.cpu_gpu.setEnabled(False)
        self.startButton.setEnabled(False)
        self.quitButton.setEnabled(False)
        self.stopButton.setEnabled(True)
    def set_True_Btn(self):
        self.audio_mic.setEnabled(True)
        self.language.setEnabled(True)
        self.ai_model.setEnabled(True)
        self.cpu_gpu.setEnabled(True)
        self.startButton.setEnabled(True)
        self.quitButton.setEnabled(True)
        self.stopButton.setEnabled(False)

    def save_yaml(self):
        global stop_flag, stop_flag, show_win_x, show_win_y, show_win_w, show_win_h, main_win_x, main_win_y
        rect = self.my_long_win.geometry()
        show_win_x, show_win_y, show_win_w, show_win_h = rect.x(), rect.y(), rect.width(), rect.height()
        rect = self.geometry()
        main_win_x, main_win_y = rect.x(), rect.y()
        settings = {
    
    
            'default_font_family': default_font_family,
            'default_font_size': default_font_size,
            'default_model': default_model,
            'default_bk_Color': default_bk_Color,
            'default_fr_Color': default_fr_Color,
            'show_bottom': show_bottom,
            'show_win_w': show_win_w,
            'show_win_h': show_win_h,
            'show_win_x': show_win_x,
            'show_win_y': show_win_y,
            'main_win_x': main_win_x,
            'main_win_y': main_win_y,
            'play_switch_flag': play_switch_flag,
            }
        with open(settings_file, 'w+') as f:
            yaml.dump(settings, f)

    def start_run(self):
        global stop_flag, stop_flag, show_win_x, show_win_y, show_win_w, show_win_h, main_win_x, main_win_y
        stop_flag = False
        self.set_False_Btn()
        # 获取字体的metrics
        self.metrics = QFontMetrics(QFont(default_font_family, default_font_size))

        self.save_yaml()        #配置存盘yaml文件

        self.my_long_win.up_show.setText(' Initializing AI Environment...')
        self.my_long_win.down_show.setText(' 正在初始化AI环境,请稍后...')

        if is_Argos:
            if self.language.currentIndex() == 0: self.trans_text = TranslatorArgos('en', 'zh')
            else: self.trans_text = TranslatorArgos('zh', 'en')
        else:
            if self.language.currentIndex() == 0: self.trans_text = Translator('en', 'zh')
            else: self.trans_text = Translator('zh', 'en')

        self.pa = pyaudio.PyAudio()
        self.stream = self.pa.open(format=pyaudio.paInt16,
                         channels=1,
                         rate=sample_rate,
                         input=True,
                         frames_per_buffer=chunk_size,
                         input_device_index=device_index)

        self.record_thread = recording_thread(self, self.stream)   #启动读取音频线程
        self.record_thread.sinout.connect(self.recording_signal)
        self.record_thread.start()

        self.transate_thread = TransateThread(self)   #启动翻译线程
        self.transate_thread.start()

        self.tts_thread = EdgeTTSTrans(self)   #启动TTS线程
        self.tts_thread.start()

        self.play_thread = PlayAudioWav(self)   #启动Play线程
        self.play_thread.start()

        self.gender_thread = GenderPredict(self)   #启动性别识别线程
        self.gender_thread.start()

    def stoprun(self):
        global stop_flag
        r_button = QMessageBox.question(self, my_title,"\n\n确定要停止运行吗?   \n\n", QMessageBox.Yes | QMessageBox.No)
        if r_button == QMessageBox.Yes:
            stop_flag = True
            self.save_yaml()  # 配置存盘yaml文件
            while not all_thread_exit:
                time.sleep(0.1)
            sys.exit()

    def quitWin(self):
        global stop_flag
        r_button = QMessageBox.question(self, "my_title",
                                        "\n\n退出将终止本程序......\n\n确认退出吗?\n\n", QMessageBox.Yes | QMessageBox.No)
        if r_button == QMessageBox.Yes:
            stop_flag = True
            self.save_yaml()  # 配置存盘yaml文件
            # pa.terminate()
            sys.exit()

    def click_audio_mic(self):
        global device_index
        device_index = microphones[self.audio_mic.currentIndex()][0]
    def click_audio_speak(self, str):
        global speak_device_index
        _speaks = []
        pa = pyaudio.PyAudio()
        # default_speak = pa.get_default_output_device_info()
        # if default_speak: _speaks = [(default_speak['index'], '系统默认')]
        for i in range(pa.get_device_count()):
            device_info = pa.get_device_info_by_index(i)
            if device_info['maxOutputChannels'] > 0 and device_info['hostApi'] == 0 and 'Microsoft' not in device_info[
                'name']:
                _speaks.append((device_info['index'], device_info['name']))
        # print('扬声器列表:', _speaks)
        for _speaks_ in _speaks:
            if speak_list[self.audio_speak.currentIndex()] == _speaks_[1]: speak_device_index = _speaks_[0]
        # print('当前: ', speak_device_index)
        pa.terminate()

    def click_ai_model(self, str):
        global model_dir, default_model
        if self.language.currentIndex() == 1 or str == 'large': model_dir = ".\model_faster_whisper\whisper-"+ str
        else: model_dir = ".\model_faster_whisper\whisper-"+ str + '-en'
        if not os.path.exists(model_dir):
            model_dir = ".\model_faster_whisper\whisper-base-en"
            default_model = 1
            self.ai_model.setCurrentIndex(default_model)
            print("您选择的模型不存在,改为:whisper-base-en模型...")
            self.show_error('\n您选择的模型文件不在模型目录,请下载您需要的模型文件...   \n')
        else:
            default_model = self.ai_model.currentIndex()

    def click_cpu_gpu(self, str):
        global device
        if self.cpu_gpu.currentIndex() == 0: device = 'cpu'
        elif gpu_ok: device = 'cuda'
        else: self.show_error('\n您的GPU不可用于AI处理,不能选择GPU...   \n'); self.cpu_gpu.setCurrentIndex(0)
    def click_language(self):
        global language, model_dir, out_voice_model, en_zh
        if self.language.currentIndex() == 0: language = 'en'; en_zh = True
        else: language = 'zh'; en_zh = False

        str1 = self.ai_model.currentText()
        if self.language.currentIndex() == 1 or str1 == 'large':
            model_dir = ".\model_faster_whisper\whisper-"+ str1
        else:
            model_dir = ".\model_faster_whisper\whisper-"+ str1 + '-en'

        if self.man_woman.currentIndex() == 1:
            if self.language.currentIndex() == 0: out_voice_model = "zh-CN-YunjianNeural"
            else: out_voice_model = "en-US-ChristopherNeural"
        elif self.man_woman.currentIndex() == 2:
            if self.language.currentIndex() == 0: out_voice_model = "zh-CN-XiaoxiaoNeural"
            else: out_voice_model = "en-US-MichelleNeural"

    def color_bk_fuc(self):
        global default_bk_Color
        color = QColorDialog.getColor(title='背景颜色选择' )
        if color.isValid():
            default_bk_Color = color.name()
            # self.src_out_text.setStyleSheet("QTextBrowser {background-color:%s}" % color.name())
            # self.dst_out_text.setStyleSheet("QTextBrowser {background-color:%s}" % color.name())
            self.color_bk.setStyleSheet("QPushButton {background-color:%s}" % color.name())
            self.font_select.setStyleSheet("color: %s; background-color:%s" % (default_fr_Color, default_bk_Color))
            self.my_long_win.setStyleSheet("QWidget {background-color:%s}" % color.name())
    def color_fr_fuc(self):
        global default_fr_Color
        color = QColorDialog.getColor(title='前景颜色选择' )
        if color.isValid():
            default_fr_Color = color.name()
            # self.src_out_text.setTextColor(color)
            # self.dst_out_text.setTextColor(color)
            self.color_fr.setStyleSheet("QPushButton {background-color:%s}" % color.name())
            self.font_select.setStyleSheet("color: %s; background-color:%s" % (default_fr_Color, default_bk_Color))

            self.my_long_win.up_show.setStyleSheet(f"color:{color.name()}")
            self.my_long_win.down_show.setStyleSheet(f"color:{color.name()}")

    def click_show_bottom(self):
        global show_bottom
        if self.show_bottom.isChecked(): self.my_long_win.show()
        else: self.my_long_win.hide()
        show_bottom = self.show_bottom.isChecked()

    def click_font_select(self,font):
        global default_font_family, default_font_size
        font, ok = QFontDialog.getFont(QFont(default_font_family, default_font_size),
                                       parent=self,caption = '字体选择')
        if ok:
            default_font_family = font.family()
            default_font_size = font.pointSize()
            self.font_select.setText(str(default_font_size))
            # self.src_out_text.setFont(font)
            # self.dst_out_text.setFont(font)
            self.my_long_win.up_show.setFont(font)
            self.my_long_win.down_show.setFont(font)

    def rates_slider_fuc(self):
        global rates
        self.Text_10.setText(f'语速({self.rates_slider.value()}%)')
        _rates = self.rates_slider.value()
        if _rates >= 0: rates = f'+{_rates}%'
        else: rates = f'{_rates}%'
    def vol_slider_fuc(self):
        global vol
        self.Text_12.setText(f'增益({self.vol_slider.value()}%)')
        _vol = self.vol_slider.value()
        if _vol >= 0: vol = f'+{_vol}%'
        else: vol = f'{_vol}%'
    def man_woman_fuc(self):
        """
        Name: zh - CN - XiaoxiaoNeural / Gender: Female
        Name: zh - CN - XiaoyiNeural / Gender: Female        ok
        Name: zh - CN - liaoning - XiaobeiNeural / Gender: Female        nook
        Name: zh - CN - shaanxi - XiaoniNeural / Gender: Female        nook
        Name: zh - CN - YunxiaNeural / Gender: Female        nook
        Name: zh - CN - YunjianNeural / Gender: Male        ok
        Name: zh - CN - YunxiNeural / Gender: Male        ok
        Name: zh - CN - YunyangNeural / Gender: Male        ok
        Name: en - US - AnaNeural / Gender: Female
        Name: en - US - AriaNeural / Gender: Female
        Name: en - US - ChristopherNeural / Gender: Male
        Name: en - US - EricNeural / Gender: Male
        Name: en - US - GuyNeural / Gender: Male
        Name: en - US - JennyNeural / Gender: Female
        Name: en - US - MichelleNeural / Gender: Female
        Name: en - US - RogerNeural / Gender: Male
        Name: en - US - SteffanNeural / Gender: Male
        """
        global out_voice_model, gender_predict_flag
        gender_predict_flag = self.man_woman.currentIndex()

        if self.man_woman.currentIndex() == 1:
            self.man_wuman_show.setText('')
            if self.language.currentIndex() == 0: out_voice_model = "zh-CN-YunjianNeural"
            else: out_voice_model = "en-US-ChristopherNeural"
        elif self.man_woman.currentIndex() == 2:
            self.man_wuman_show.setText('')
            if self.language.currentIndex() == 0: out_voice_model = "zh-CN-XiaoxiaoNeural"
            else: out_voice_model = "en-US-MichelleNeural"

    def play_switch_fun(self):
        global play_switch_flag
        play_switch_flag = self.play_switch.isChecked()

    def createLayout(self):
        self.audio_mic.addItems(mic_list)
        for i in range(len(mic_list)):
            if 'VB-Audio' in mic_list[i]: self.audio_mic.setCurrentIndex(i); break
        self.audio_mic.activated[str].connect(self.click_audio_mic)

        self.audio_speak.addItems(speak_list)
        self.audio_speak.activated[str].connect(self.click_audio_speak)

        self.ai_model.addItems(model_list)
        self.ai_model.setCurrentIndex(default_model)
        self.ai_model.activated[str].connect(self.click_ai_model)

        self.cpu_gpu.addItems(['CPU', 'GPU'])
        if gpu_ok: self.cpu_gpu.setCurrentIndex(1)
        self.cpu_gpu.activated[str].connect(self.click_cpu_gpu)

        self.language.addItems(['英->汉', '汉->英'])
        self.language.activated[str].connect(self.click_language)

        self.show_bottom.stateChanged.connect(self.click_show_bottom)
        self.show_bottom.setChecked(show_bottom)

        self.volume_bar.setStyleSheet("QProgressBar::chunk {background-color: #2a9f18}")

        # self.src_out_text.setStyleSheet("QTextBrowser {background-color:%s}" % default_bk_Color)
        # self.dst_out_text.setStyleSheet("QTextBrowser {background-color:%s}" % default_bk_Color)
        self.color_bk.setStyleSheet("QPushButton {background-color:%s}" % default_bk_Color)

        # self.src_out_text.setTextColor(QColor(default_fr_Color))
        # self.dst_out_text.setTextColor(QColor(default_fr_Color))
        self.font_select.setStyleSheet("QPushButton {color:%s}" % default_fr_Color)
        self.color_fr.setStyleSheet("QPushButton {background-color:%s}" % default_fr_Color)

        self.font_select.setStyleSheet("color: %s; background-color:%s" % (default_fr_Color, default_bk_Color))

        # self.src_out_text.setFont(QFont(default_font_family, default_font_size))
        # self.dst_out_text.setFont(QFont(default_font_family, default_font_size))

        self.font_select.setText(str(default_font_size))

        self.startButton.clicked.connect(self.start_run)
        self.stopButton.clicked.connect(self.stoprun)
        self.quitButton.clicked.connect(self.quitWin)
        self.color_bk.clicked.connect(self.color_bk_fuc)
        self.color_fr.clicked.connect(self.color_fr_fuc)
        self.font_select.clicked.connect(self.click_font_select)
        self.stopButton.setEnabled(False)

        self.man_woman.setCurrentIndex(0)
        self.man_woman.addItems(['自动', '男声', '女声'])
        self.man_woman.activated[str].connect(self.man_woman_fuc)
        self.vol_slider.setTickPosition(QSlider.TicksAbove)
        self.rates_slider.setTickPosition(QSlider.TicksAbove)
        self.vol_slider.valueChanged.connect(self.vol_slider_fuc)
        self.rates_slider.valueChanged.connect(self.rates_slider_fuc)
        self.play_switch.stateChanged.connect(self.play_switch_fun)
        self.play_switch.setChecked(play_switch_flag)

#if __name__ == '__main__':
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QtWidgets.QApplication(sys.argv)
winshot = Winshot()
sys.exit(app.exec_())

界面部分:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'AI_Translate_UI.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_trans(object):
    def setupUi(self, trans):
        trans.setObjectName("trans")
        trans.resize(621, 368)
        font = QtGui.QFont()
        font.setFamily("宋体")
        trans.setFont(font)
        self.startButton = QtWidgets.QPushButton(trans)
        self.startButton.setGeometry(QtCore.QRect(260, 302, 71, 23))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.startButton.setFont(font)
        self.startButton.setObjectName("startButton")
        self.stopButton = QtWidgets.QPushButton(trans)
        self.stopButton.setGeometry(QtCore.QRect(400, 302, 71, 23))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.stopButton.setFont(font)
        self.stopButton.setObjectName("stopButton")
        self.quitButton = QtWidgets.QPushButton(trans)
        self.quitButton.setGeometry(QtCore.QRect(530, 302, 71, 23))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.quitButton.setFont(font)
        self.quitButton.setObjectName("quitButton")
        self.audio_mic = QtWidgets.QComboBox(trans)
        self.audio_mic.setGeometry(QtCore.QRect(69, 20, 211, 21))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(9)
        self.audio_mic.setFont(font)
        self.audio_mic.setMaxVisibleItems(15)
        self.audio_mic.setObjectName("audio_mic")
        self.Text_1 = QtWidgets.QLabel(trans)
        self.Text_1.setGeometry(QtCore.QRect(30, 23, 51, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_1.setFont(font)
        self.Text_1.setObjectName("Text_1")
        self.volume_bar = QtWidgets.QProgressBar(trans)
        self.volume_bar.setGeometry(QtCore.QRect(328, 26, 271, 10))
        self.volume_bar.setProperty("value", 1)
        self.volume_bar.setTextVisible(False)
        self.volume_bar.setObjectName("volume_bar")
        self.groupBox = QtWidgets.QGroupBox(trans)
        self.groupBox.setGeometry(QtCore.QRect(20, 130, 581, 51))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.groupBox.setFont(font)
        self.groupBox.setObjectName("groupBox")
        self.Text_5 = QtWidgets.QLabel(self.groupBox)
        self.Text_5.setGeometry(QtCore.QRect(170, 22, 61, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_5.setFont(font)
        self.Text_5.setObjectName("Text_5")
        self.color_bk = QtWidgets.QPushButton(self.groupBox)
        self.color_bk.setGeometry(QtCore.QRect(234, 20, 21, 20))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.color_bk.setFont(font)
        self.color_bk.setText("")
        self.color_bk.setObjectName("color_bk")
        self.color_fr = QtWidgets.QPushButton(self.groupBox)
        self.color_fr.setGeometry(QtCore.QRect(393, 20, 21, 20))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.color_fr.setFont(font)
        self.color_fr.setText("")
        self.color_fr.setObjectName("color_fr")
        self.Text_7 = QtWidgets.QLabel(self.groupBox)
        self.Text_7.setGeometry(QtCore.QRect(330, 22, 61, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_7.setFont(font)
        self.Text_7.setObjectName("Text_7")
        self.font_select = QtWidgets.QPushButton(self.groupBox)
        self.font_select.setGeometry(QtCore.QRect(531, 20, 21, 20))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.font_select.setFont(font)
        self.font_select.setObjectName("font_select")
        self.show_bottom = QtWidgets.QCheckBox(self.groupBox)
        self.show_bottom.setGeometry(QtCore.QRect(14, 20, 131, 20))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.show_bottom.setFont(font)
        self.show_bottom.setObjectName("show_bottom")
        self.Text_8 = QtWidgets.QLabel(self.groupBox)
        self.Text_8.setGeometry(QtCore.QRect(470, 22, 61, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_8.setFont(font)
        self.Text_8.setObjectName("Text_8")
        self.groupBox_2 = QtWidgets.QGroupBox(trans)
        self.groupBox_2.setGeometry(QtCore.QRect(20, 60, 581, 51))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.groupBox_2.setFont(font)
        self.groupBox_2.setObjectName("groupBox_2")
        self.Text_4 = QtWidgets.QLabel(self.groupBox_2)
        self.Text_4.setGeometry(QtCore.QRect(12, 22, 51, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_4.setFont(font)
        self.Text_4.setObjectName("Text_4")
        self.language = QtWidgets.QComboBox(self.groupBox_2)
        self.language.setGeometry(QtCore.QRect(53, 20, 74, 22))
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(9)
        self.language.setFont(font)
        self.language.setObjectName("language")
        self.Text_2 = QtWidgets.QLabel(self.groupBox_2)
        self.Text_2.setGeometry(QtCore.QRect(395, 22, 81, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_2.setFont(font)
        self.Text_2.setObjectName("Text_2")
        self.cpu_gpu = QtWidgets.QComboBox(self.groupBox_2)
        self.cpu_gpu.setGeometry(QtCore.QRect(480, 20, 61, 22))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(9)
        self.cpu_gpu.setFont(font)
        self.cpu_gpu.setObjectName("cpu_gpu")
        self.Text_3 = QtWidgets.QLabel(self.groupBox_2)
        self.Text_3.setGeometry(QtCore.QRect(176, 22, 81, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_3.setFont(font)
        self.Text_3.setObjectName("Text_3")
        self.ai_model = QtWidgets.QComboBox(self.groupBox_2)
        self.ai_model.setGeometry(QtCore.QRect(260, 19, 81, 22))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(9)
        self.ai_model.setFont(font)
        self.ai_model.setObjectName("ai_model")
        self.Text_9 = QtWidgets.QLabel(trans)
        self.Text_9.setGeometry(QtCore.QRect(290, 23, 51, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_9.setFont(font)
        self.Text_9.setObjectName("Text_9")
        self.groupBox_3 = QtWidgets.QGroupBox(trans)
        self.groupBox_3.setGeometry(QtCore.QRect(20, 200, 581, 81))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.groupBox_3.setFont(font)
        self.groupBox_3.setObjectName("groupBox_3")
        self.play_switch = QtWidgets.QCheckBox(self.groupBox_3)
        self.play_switch.setGeometry(QtCore.QRect(15, 20, 91, 20))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.play_switch.setFont(font)
        self.play_switch.setObjectName("play_switch")
        self.audio_speak = QtWidgets.QComboBox(self.groupBox_3)
        self.audio_speak.setGeometry(QtCore.QRect(85, 47, 231, 21))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(9)
        self.audio_speak.setFont(font)
        self.audio_speak.setMaxVisibleItems(15)
        self.audio_speak.setObjectName("audio_speak")
        self.Text_6 = QtWidgets.QLabel(self.groupBox_3)
        self.Text_6.setGeometry(QtCore.QRect(30, 50, 51, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_6.setFont(font)
        self.Text_6.setObjectName("Text_6")
        self.Text_10 = QtWidgets.QLabel(self.groupBox_3)
        self.Text_10.setGeometry(QtCore.QRect(120, 20, 61, 20))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_10.setFont(font)
        self.Text_10.setObjectName("Text_10")
        self.Text_11 = QtWidgets.QLabel(self.groupBox_3)
        self.Text_11.setGeometry(QtCore.QRect(370, 50, 61, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_11.setFont(font)
        self.Text_11.setObjectName("Text_11")
        self.man_woman = QtWidgets.QComboBox(self.groupBox_3)
        self.man_woman.setGeometry(QtCore.QRect(437, 47, 61, 22))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(9)
        self.man_woman.setFont(font)
        self.man_woman.setObjectName("man_woman")
        self.rates_slider = QtWidgets.QSlider(self.groupBox_3)
        self.rates_slider.setGeometry(QtCore.QRect(180, 21, 131, 16))
        self.rates_slider.setMinimum(-99)
        self.rates_slider.setTracking(True)
        self.rates_slider.setOrientation(QtCore.Qt.Horizontal)
        self.rates_slider.setInvertedAppearance(False)
        self.rates_slider.setInvertedControls(False)
        self.rates_slider.setObjectName("rates_slider")
        self.Text_12 = QtWidgets.QLabel(self.groupBox_3)
        self.Text_12.setGeometry(QtCore.QRect(370, 20, 61, 20))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.Text_12.setFont(font)
        self.Text_12.setObjectName("Text_12")
        self.vol_slider = QtWidgets.QSlider(self.groupBox_3)
        self.vol_slider.setGeometry(QtCore.QRect(430, 21, 131, 16))
        self.vol_slider.setMinimum(-99)
        self.vol_slider.setTracking(False)
        self.vol_slider.setOrientation(QtCore.Qt.Horizontal)
        self.vol_slider.setObjectName("vol_slider")
        self.man_wuman_show = QtWidgets.QLabel(self.groupBox_3)
        self.man_wuman_show.setGeometry(QtCore.QRect(505, 50, 45, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.man_wuman_show.setFont(font)
        self.man_wuman_show.setText("")
        self.man_wuman_show.setObjectName("man_wuman_show")
        self.line = QtWidgets.QFrame(trans)
        self.line.setGeometry(QtCore.QRect(0, 340, 631, 16))
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.run_state = QtWidgets.QLabel(trans)
        self.run_state.setGeometry(QtCore.QRect(4, 350, 511, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.run_state.setFont(font)
        self.run_state.setObjectName("run_state")
        self.run_state_2 = QtWidgets.QLabel(trans)
        self.run_state_2.setGeometry(QtCore.QRect(510, 350, 101, 16))
        font = QtGui.QFont()
        font.setFamily("宋体")
        font.setPointSize(9)
        self.run_state_2.setFont(font)
        self.run_state_2.setObjectName("run_state_2")

        self.retranslateUi(trans)
        QtCore.QMetaObject.connectSlotsByName(trans)

    def retranslateUi(self, trans):
        _translate = QtCore.QCoreApplication.translate
        trans.setWindowTitle(_translate("trans", "AI同声传译"))
        self.startButton.setText(_translate("trans", "开始"))
        self.stopButton.setText(_translate("trans", "停止"))
        self.quitButton.setText(_translate("trans", "退出"))
        self.Text_1.setText(_translate("trans", "音源:"))
        self.groupBox.setTitle(_translate("trans", "显示设置"))
        self.Text_5.setText(_translate("trans", "背景颜色:"))
        self.Text_7.setText(_translate("trans", "前景颜色:"))
        self.font_select.setText(_translate("trans", "12"))
        self.show_bottom.setText(_translate("trans", "显示翻译条窗口"))
        self.Text_8.setText(_translate("trans", "字体大小:"))
        self.groupBox_2.setTitle(_translate("trans", "功能设置"))
        self.Text_4.setText(_translate("trans", "语言:"))
        self.Text_2.setText(_translate("trans", "处理器选择:"))
        self.Text_3.setText(_translate("trans", "AI模型选择:"))
        self.Text_9.setText(_translate("trans", "音量:"))
        self.groupBox_3.setTitle(_translate("trans", "语音播放"))
        self.play_switch.setText(_translate("trans", "播放开关"))
        self.Text_6.setText(_translate("trans", "扬声器:"))
        self.Text_10.setText(_translate("trans", "语速(0%)"))
        self.Text_11.setText(_translate("trans", "语音选择:"))
        self.Text_12.setText(_translate("trans", "增益(0%)"))
        self.run_state.setText(_translate("trans", "统计:"))
        self.run_state_2.setText(_translate("trans", "【版权所有】"))

猜你喜欢

转载自blog.csdn.net/weixin_42398606/article/details/133132872