This commit is contained in:
恍兮惚兮 2024-08-06 12:52:01 +08:00
parent acce466c1b
commit f1445937fc
7 changed files with 106 additions and 101 deletions

View File

@ -67,7 +67,6 @@ class MAINUI:
self.lasttranslatorindex = 0 self.lasttranslatorindex = 0
self.translators = {} self.translators = {}
self.cishus = {} self.cishus = {}
self.reader = None
self.specialreaders = {} self.specialreaders = {}
self.textsource_p = None self.textsource_p = None
self.currentmd5 = "0" self.currentmd5 = "0"
@ -90,6 +89,24 @@ class MAINUI:
self.sqlsavegameinfo = None self.sqlsavegameinfo = None
self.notifyonce = set() self.notifyonce = set()
self.audioplayer = series_audioplayer() self.audioplayer = series_audioplayer()
self._internal_reader = None
self.reader_uid = None
@property
def reader(self):
return self._internal_reader
@reader.setter
def reader(self, _):
if _ is None:
self._internal_reader = None
self.reader_uid = None
self.settin_ui.voicelistsignal.emit(None)
else:
if self.reader_uid != _.uid:
return
self._internal_reader = _
self.settin_ui.voicelistsignal.emit(_)
@property @property
def textsource(self): def textsource(self):
@ -584,31 +601,42 @@ class MAINUI:
else: else:
self.__readcurrent(self.currentread, None, force) self.__readcurrent(self.currentread, None, force)
def loadreader(self, use, voicelistsignal=None, privateconfig=None, init=True): def loadreader(self, use, privateconfig=None, init=True, uid=None):
if voicelistsignal is None:
voicelistsignal = self.settin_ui.voicelistsignal
aclass = importlib.import_module("tts." + use).TTS aclass = importlib.import_module("tts." + use).TTS
obj = aclass(use, voicelistsignal, self.audioplayer.play, privateconfig, init) if uid is None:
uid = uuid.uuid4()
obj = aclass(use, self.audioplayer.play, privateconfig, init, uid)
return obj return obj
@threader def __reader_usewhich(self):
def startreader(self, use=None, checked=True):
self.reader = None
self.settin_ui.voicelistsignal.emit(None)
if not checked:
return
if use is None:
for key in globalconfig["reader"]: for key in globalconfig["reader"]:
if globalconfig["reader"][key]["use"] and os.path.exists( if globalconfig["reader"][key]["use"] and os.path.exists(
("./LunaTranslator/tts/" + key + ".py") ("./LunaTranslator/tts/" + key + ".py")
): ):
use = key return key
break return None
if not use:
@threader
def startreader(self, use=None, checked=True, setting=False):
if setting:
if use != self.__reader_usewhich():
return return
self.reader = self.loadreader(use) self.reader = None
self.reader_usevoice = use self.reader_uid = uuid.uuid4()
self.reader = self.loadreader(use, uid=self.reader_uid)
return
if not checked:
self.reader = None
return
if use is None:
use = self.__reader_usewhich()
if not use:
self.reader = None
return
self.reader = None
self.reader_uid = uuid.uuid4()
self.reader = self.loadreader(use, uid=self.reader_uid)
def selectprocess(self, selectedp, title): def selectprocess(self, selectedp, title):
self.textsource = None self.textsource = None

View File

@ -5,7 +5,6 @@ import qtawesome, os, gobject
from myutils.config import globalconfig, _TR from myutils.config import globalconfig, _TR
from myutils.utils import makehtml from myutils.utils import makehtml
from myutils.wrapper import Singleton_close from myutils.wrapper import Singleton_close
from tts.basettsclass import getvisidx
from gui.usefulwidget import ( from gui.usefulwidget import (
MySwitch, MySwitch,
selectcolor, selectcolor,
@ -212,7 +211,7 @@ class voiceselect(LDialog):
self.engine_internal.append(name) self.engine_internal.append(name)
self.datas = { self.datas = {
"engine": self.engine_internal[0], "engine": self.engine_internal[0],
"voice": "", "voice": None,
"vis": "", "vis": "",
"visx": "", "visx": "",
} }
@ -232,12 +231,10 @@ class voiceselect(LDialog):
self.lastwidget = None self.lastwidget = None
def loadedvoice(self, obj): def loadedvoice(self, obj):
vl, idx = getvisidx(obj) vl = obj.voiceshowlist
self.datas["voice"] = obj.voice
if self._layout.rowCount() == 3: if self._layout.rowCount() == 3:
self._layout.removeRow(1) self._layout.removeRow(1)
if len(vl) == 0: self.datas["voice"] = obj.voice
return
voices = getsimplecombobox( voices = getsimplecombobox(
vl, vl,
self.datas, self.datas,
@ -255,8 +252,10 @@ class voiceselect(LDialog):
def __engine_cb(self, internal): def __engine_cb(self, internal):
self.datas["visx"] = self.engine_vis[self.engine_internal.index(internal)] self.datas["visx"] = self.engine_vis[self.engine_internal.index(internal)]
self.datas["vis"] = self.datas["visx"] self.datas["vis"] = self.datas["visx"]
self.datas["voice"] = None
try: try:
self.object = gobject.baseobject.loadreader(internal, self.voicelistsignal, init=False) self.object = gobject.baseobject.loadreader(internal, init=False)
self.voicelistsignal.emit(self.object)
except: except:
if self._layout.rowCount() == 3: if self._layout.rowCount() == 3:
@ -357,6 +356,9 @@ class yuyinzhidingsetting(LDialog):
elif idx == 2: elif idx == 2:
voice = voiceselect(self) voice = voiceselect(self)
if voice.exec(): if voice.exec():
if voice.datas["voice"] is None:
com.setCurrentIndex(1)
return
config["target"] = ( config["target"] = (
voice.datas["engine"], voice.datas["engine"],
voice.datas["voice"], voice.datas["voice"],

View File

@ -1,7 +1,6 @@
from qtsymbols import * from qtsymbols import *
import os, functools import os, functools
import gobject import gobject
from tts.basettsclass import getvisidx
from myutils.config import globalconfig, static_data from myutils.config import globalconfig, static_data
from gui.inputdialog import ( from gui.inputdialog import (
autoinitdialog_items, autoinitdialog_items,
@ -21,23 +20,30 @@ from gui.usefulwidget import (
def showvoicelist(self, obj): def showvoicelist(self, obj):
vl, idx = getvisidx(obj)
if obj is None:
try: try:
self.voicecombo.blockSignals(True) self.voicecombo.clear()
except:
pass
return
vl = obj.voiceshowlist
idx = obj.voicelist.index(obj.voice)
try:
self.voicecombo.clear() self.voicecombo.clear()
self.voicecombo.addItems(vl) self.voicecombo.addItems(vl)
if idx >= 0:
self.voicecombo.setCurrentIndex(idx) self.voicecombo.setCurrentIndex(idx)
self.voicecombo.blockSignals(False)
except: except:
self.voicecombo_cache = vl, idx self.voicecombo_cache = vl, idx
def changevoice(self, text): def changevoice(self, text):
if gobject.baseobject.reader is None:
globalconfig["reader"][gobject.baseobject.reader_usevoice]["voice"] = ( return
gobject.baseobject.reader.voicelist[self.voicecombo.currentIndex()] gobject.baseobject.reader.voice = gobject.baseobject.reader.voicelist[
) self.voicecombo.currentIndex()
]
def createvoicecombo(self): def createvoicecombo(self):
@ -71,7 +77,9 @@ def getttsgrid(self):
continue continue
if "args" in globalconfig["reader"][name]: if "args" in globalconfig["reader"][name]:
items = autoinitdialog_items(globalconfig["reader"][name]) items = autoinitdialog_items(globalconfig["reader"][name])
items[-1]["callback"] = gobject.baseobject.startreader items[-1]["callback"] = functools.partial(
gobject.baseobject.startreader, name, True, True
)
_3 = D_getIconButton( _3 = D_getIconButton(
callback=functools.partial( callback=functools.partial(
autoinitdialog, autoinitdialog,

View File

@ -37,32 +37,31 @@ class TTSbase:
@property @property
def voice(self): def voice(self):
_v = self.privateconfig["voice"] _v = self.privateconfig["voice"]
if len(self.voicelist) == 0:
return None
if _v not in self.voicelist: if _v not in self.voicelist:
_v = self.voicelist[0] _v = self.voicelist[0]
return _v return _v
@voice.setter
def voice(self, v):
self.privateconfig["voice"] = v
######################## ########################
def __init__( def __init__(
self, self, typename, playaudiofunction, privateconfig=None, init=True, uid=None
typename,
voicelistsignal,
playaudiofunction,
privateconfig=None,
init=True,
) -> None: ) -> None:
self.typename = typename self.typename = typename
self.voicelistsignal = voicelistsignal
self.playaudiofunction = playaudiofunction self.playaudiofunction = playaudiofunction
self.uid = uid
if privateconfig is None: if privateconfig is None:
self.privateconfig = globalconfig["reader"][self.typename] self.privateconfig = globalconfig["reader"][self.typename]
else: else:
self.privateconfig = privateconfig self.privateconfig = privateconfig
self.voicelist, self.voiceshowlist = self.getvoicelist() self.voicelist, self.voiceshowlist = self.getvoicelist()
voicelistsignal.emit(self) if len(self.voicelist) != len(self.voiceshowlist):
raise
if len(self.voicelist) == 0:
raise
if init: if init:
self.init() self.init()
@ -87,16 +86,3 @@ class TTSbase:
except: except:
print_exc() print_exc()
return return
def getvisidx(obj: TTSbase):
if obj is None:
vl = []
idx = -1
else:
vl = obj.voiceshowlist
if obj.voice:
idx = obj.voicelist.index(obj.voice)
else:
idx = -1
return vl, idx

View File

@ -1,31 +1,33 @@
import requests import requests
import time, os from urllib.parse import urljoin
from tts.basettsclass import TTSbase from tts.basettsclass import TTSbase
from urllib.parse import quote from urllib.parse import quote
class TTS(TTSbase): class TTS(TTSbase):
def getvoicelist(self): def getvoicelist(self):
if self.config["voices"] == "":
return [(0, 0, 0)], []
responseVits = requests.get( responseVits = requests.get(
f"http://127.0.0.1:{self.config['Port']}/voice/speakers" urljoin(self.config["URL"], self.config["voices"])
).json() ).json()
voicelist = [] voicelist = []
internal = []
# 获取所有模型类型,对于每个模型类型下的模型信息,将其 modelType、id、name 合成一个字符串
modelTypes = responseVits.keys() modelTypes = responseVits.keys()
for modelType in modelTypes: for modelType in modelTypes:
vits_data = responseVits[modelType] vits_data = responseVits[modelType]
for item in vits_data: for item in vits_data:
model_info = f'{modelType}_{item["id"]}_{item["name"]}' model_info = f'{modelType}_{item["id"]}_{item["name"]}'
voicelist.append(model_info) voicelist.append(model_info)
return voicelist, voicelist internal.append((modelType, item["id"], item["name"]))
return internal, voicelist
def speak(self, content, rate, voice): def speak(self, content, rate, voice):
encoded_content = quote(content) encoded_content = quote(content)
idx = int(voice.split("_")[1]) model, idx, _ = voice
model = str.lower(voice.split("_")[0]) speak = self.config["speak"].format(
response = requests.get( model_lower=model.lower(), model=model, id=idx, text=encoded_content
f"http://127.0.0.1:{self.config['Port']}/voice/{model}?text={encoded_content}&id={idx}&lang=auto&prompt_lang=auto&format=wav&preset={self.config['preset']}" )
).content response = requests.get(urljoin(self.config["URL"], speak)).content
return response return response

View File

@ -1037,6 +1037,12 @@
} }
}, },
"reader": { "reader": {
"windowstts": {
"use": false,
"voice": "",
"name": "WindowsTTS",
"type": "offline"
},
"huoshantts": { "huoshantts": {
"use": false, "use": false,
"voice": "", "voice": "",
@ -1054,12 +1060,6 @@
"name": "有道TTS", "name": "有道TTS",
"useproxy": false "useproxy": false
}, },
"windowstts": {
"use": false,
"voice": "",
"name": "WindowsTTS",
"type": "offline"
},
"NeoSpeech": { "NeoSpeech": {
"use": false, "use": false,
"voice": "", "voice": "",
@ -1106,35 +1106,14 @@
"name": "vits-simple-api", "name": "vits-simple-api",
"type": "offline", "type": "offline",
"args": { "args": {
"Port": 23456, "URL": "http://127.0.0.1:23456",
"preset": "", "voices": "/voice/speakers",
"整合包_CPU": "{main_server}/Resource/IntegrationPack/vits-simple-api/cpu", "speak": "/voice/{model_lower}?text={text}&id={id}&lang=auto&prompt_lang=auto&format=wav&preset=default"
"整合包_GPU": "{main_server}/Resource/IntegrationPack/vits-simple-api/gpu"
},
"argstype": {
"Port": {
"type": "intspin",
"min": 1,
"max": 65535,
"step": 1,
"name": "端口号"
},
"整合包_CPU": {
"type": "label",
"islink": true
},
"整合包_GPU": {
"type": "label",
"islink": true
},
"preset": {
"name": "GPT-SOVITS preset"
}
} }
}, },
"gtts": { "gtts": {
"use": false, "use": false,
"name": "谷歌", "name": "GoogleTTS",
"voice": "" "voice": ""
} }
}, },

View File

@ -29,7 +29,7 @@ include(generate_product_version)
set(VERSION_MAJOR 5) set(VERSION_MAJOR 5)
set(VERSION_MINOR 22) set(VERSION_MINOR 22)
set(VERSION_PATCH 1) set(VERSION_PATCH 2)
add_library(pch pch.cpp) add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h) target_precompile_headers(pch PUBLIC pch.h)