feat: add TTS services provider selection list
This commit is contained in:
@@ -16,7 +16,7 @@ from app.utils import utils
|
|||||||
|
|
||||||
|
|
||||||
def get_all_azure_voices(filter_locals=None) -> list[str]:
|
def get_all_azure_voices(filter_locals=None) -> list[str]:
|
||||||
voices_str = """
|
azure_voices_str = """
|
||||||
Name: af-ZA-AdriNeural
|
Name: af-ZA-AdriNeural
|
||||||
Gender: Female
|
Gender: Female
|
||||||
|
|
||||||
@@ -1015,7 +1015,7 @@ Gender: Female
|
|||||||
# 定义正则表达式模式,用于匹配 Name 和 Gender 行
|
# 定义正则表达式模式,用于匹配 Name 和 Gender 行
|
||||||
pattern = re.compile(r"Name:\s*(.+)\s*Gender:\s*(.+)\s*", re.MULTILINE)
|
pattern = re.compile(r"Name:\s*(.+)\s*Gender:\s*(.+)\s*", re.MULTILINE)
|
||||||
# 使用正则表达式查找所有匹配项
|
# 使用正则表达式查找所有匹配项
|
||||||
matches = pattern.findall(voices_str)
|
matches = pattern.findall(azure_voices_str)
|
||||||
|
|
||||||
for name, gender in matches:
|
for name, gender in matches:
|
||||||
# 应用过滤条件
|
# 应用过滤条件
|
||||||
@@ -1219,7 +1219,7 @@ def create_subtitle(sub_maker: submaker.SubMaker, text: str, subtitle_file: str)
|
|||||||
"""
|
"""
|
||||||
start_t = mktimestamp(start_time).replace(".", ",")
|
start_t = mktimestamp(start_time).replace(".", ",")
|
||||||
end_t = mktimestamp(end_time).replace(".", ",")
|
end_t = mktimestamp(end_time).replace(".", ",")
|
||||||
return f"{idx}\n" f"{start_t} --> {end_t}\n" f"{sub_text}\n"
|
return f"{idx}\n{start_t} --> {end_t}\n{sub_text}\n"
|
||||||
|
|
||||||
start_time = -1.0
|
start_time = -1.0
|
||||||
sub_items = []
|
sub_items = []
|
||||||
|
|||||||
145
webui/Main.py
145
webui/Main.py
@@ -107,6 +107,7 @@ support_locales = [
|
|||||||
"th-TH",
|
"th-TH",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_all_fonts():
|
def get_all_fonts():
|
||||||
fonts = []
|
fonts = []
|
||||||
for root, dirs, files in os.walk(font_dir):
|
for root, dirs, files in os.walk(font_dir):
|
||||||
@@ -197,7 +198,8 @@ def tr(key):
|
|||||||
loc = locales.get(st.session_state["ui_language"], {})
|
loc = locales.get(st.session_state["ui_language"], {})
|
||||||
return loc.get("Translation", {}).get(key, key)
|
return loc.get("Translation", {}).get(key, key)
|
||||||
|
|
||||||
# 创建基础设置折叠框
|
|
||||||
|
# 创建基础设置折叠框
|
||||||
if not config.app.get("hide_config", False):
|
if not config.app.get("hide_config", False):
|
||||||
with st.expander(tr("Basic Settings"), expanded=False):
|
with st.expander(tr("Basic Settings"), expanded=False):
|
||||||
config_panels = st.columns(3)
|
config_panels = st.columns(3)
|
||||||
@@ -423,31 +425,31 @@ if not config.app.get("hide_config", False):
|
|||||||
# 右侧面板 - API 密钥设置
|
# 右侧面板 - API 密钥设置
|
||||||
with right_config_panel:
|
with right_config_panel:
|
||||||
|
|
||||||
def get_keys_from_config(cfg_key):
|
def get_keys_from_config(cfg_key):
|
||||||
api_keys = config.app.get(cfg_key, [])
|
api_keys = config.app.get(cfg_key, [])
|
||||||
if isinstance(api_keys, str):
|
if isinstance(api_keys, str):
|
||||||
api_keys = [api_keys]
|
api_keys = [api_keys]
|
||||||
api_key = ", ".join(api_keys)
|
api_key = ", ".join(api_keys)
|
||||||
return api_key
|
return api_key
|
||||||
|
|
||||||
def save_keys_to_config(cfg_key, value):
|
def save_keys_to_config(cfg_key, value):
|
||||||
value = value.replace(" ", "")
|
value = value.replace(" ", "")
|
||||||
if value:
|
if value:
|
||||||
config.app[cfg_key] = value.split(",")
|
config.app[cfg_key] = value.split(",")
|
||||||
|
|
||||||
st.write(tr("Video Source Settings"))
|
st.write(tr("Video Source Settings"))
|
||||||
|
|
||||||
pexels_api_key = get_keys_from_config("pexels_api_keys")
|
pexels_api_key = get_keys_from_config("pexels_api_keys")
|
||||||
pexels_api_key = st.text_input(
|
pexels_api_key = st.text_input(
|
||||||
tr("Pexels API Key"), value=pexels_api_key, type="password"
|
tr("Pexels API Key"), value=pexels_api_key, type="password"
|
||||||
)
|
)
|
||||||
save_keys_to_config("pexels_api_keys", pexels_api_key)
|
save_keys_to_config("pexels_api_keys", pexels_api_key)
|
||||||
|
|
||||||
pixabay_api_key = get_keys_from_config("pixabay_api_keys")
|
pixabay_api_key = get_keys_from_config("pixabay_api_keys")
|
||||||
pixabay_api_key = st.text_input(
|
pixabay_api_key = st.text_input(
|
||||||
tr("Pixabay API Key"), value=pixabay_api_key, type="password"
|
tr("Pixabay API Key"), value=pixabay_api_key, type="password"
|
||||||
)
|
)
|
||||||
save_keys_to_config("pixabay_api_keys", pixabay_api_key)
|
save_keys_to_config("pixabay_api_keys", pixabay_api_key)
|
||||||
|
|
||||||
llm_provider = config.app.get("llm_provider", "").lower()
|
llm_provider = config.app.get("llm_provider", "").lower()
|
||||||
panel = st.columns(3)
|
panel = st.columns(3)
|
||||||
@@ -615,42 +617,96 @@ with middle_panel:
|
|||||||
with st.container(border=True):
|
with st.container(border=True):
|
||||||
st.write(tr("Audio Settings"))
|
st.write(tr("Audio Settings"))
|
||||||
|
|
||||||
# tts_providers = ['edge', 'azure']
|
# 添加TTS服务器选择下拉框
|
||||||
# tts_provider = st.selectbox(tr("TTS Provider"), tts_providers)
|
tts_servers = [
|
||||||
|
("azure-tts-v1", "Azure TTS V1"),
|
||||||
|
("azure-tts-v2", "Azure TTS V2"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# 获取保存的TTS服务器,默认为v1
|
||||||
|
saved_tts_server = config.ui.get("tts_server", "azure-tts-v1")
|
||||||
|
saved_tts_server_index = 0
|
||||||
|
for i, (server_value, _) in enumerate(tts_servers):
|
||||||
|
if server_value == saved_tts_server:
|
||||||
|
saved_tts_server_index = i
|
||||||
|
break
|
||||||
|
|
||||||
|
selected_tts_server_index = st.selectbox(
|
||||||
|
tr("TTS Servers"),
|
||||||
|
options=range(len(tts_servers)),
|
||||||
|
format_func=lambda x: tts_servers[x][1],
|
||||||
|
index=saved_tts_server_index,
|
||||||
|
)
|
||||||
|
|
||||||
|
selected_tts_server = tts_servers[selected_tts_server_index][0]
|
||||||
|
config.ui["tts_server"] = selected_tts_server
|
||||||
|
|
||||||
|
# 获取所有声音
|
||||||
|
all_voices = voice.get_all_azure_voices(filter_locals=None)
|
||||||
|
|
||||||
|
# 根据选择的TTS服务器筛选声音
|
||||||
|
filtered_voices = []
|
||||||
|
for v in all_voices:
|
||||||
|
if selected_tts_server == "azure-tts-v2":
|
||||||
|
# V2版本的声音名称中包含"v2"
|
||||||
|
if "V2" in v:
|
||||||
|
filtered_voices.append(v)
|
||||||
|
else:
|
||||||
|
# V1版本的声音名称中不包含"v2"
|
||||||
|
if "V2" not in v:
|
||||||
|
filtered_voices.append(v)
|
||||||
|
|
||||||
voices = voice.get_all_azure_voices(filter_locals=None)
|
|
||||||
friendly_names = {
|
friendly_names = {
|
||||||
v: v.replace("Female", tr("Female"))
|
v: v.replace("Female", tr("Female"))
|
||||||
.replace("Male", tr("Male"))
|
.replace("Male", tr("Male"))
|
||||||
.replace("Neural", "")
|
.replace("Neural", "")
|
||||||
for v in voices
|
for v in filtered_voices
|
||||||
}
|
}
|
||||||
|
|
||||||
saved_voice_name = config.ui.get("voice_name", "")
|
saved_voice_name = config.ui.get("voice_name", "")
|
||||||
saved_voice_name_index = 0
|
saved_voice_name_index = 0
|
||||||
|
|
||||||
|
# 检查保存的声音是否在当前筛选的声音列表中
|
||||||
if saved_voice_name in friendly_names:
|
if saved_voice_name in friendly_names:
|
||||||
saved_voice_name_index = list(friendly_names.keys()).index(saved_voice_name)
|
saved_voice_name_index = list(friendly_names.keys()).index(saved_voice_name)
|
||||||
else:
|
else:
|
||||||
for i, v in enumerate(voices):
|
# 如果不在,则根据当前UI语言选择一个默认声音
|
||||||
if (
|
for i, v in enumerate(filtered_voices):
|
||||||
v.lower().startswith(st.session_state["ui_language"].lower())
|
if v.lower().startswith(st.session_state["ui_language"].lower()):
|
||||||
and "V2" not in v
|
|
||||||
):
|
|
||||||
saved_voice_name_index = i
|
saved_voice_name_index = i
|
||||||
break
|
break
|
||||||
|
|
||||||
selected_friendly_name = st.selectbox(
|
# 如果没有找到匹配的声音,使用第一个声音
|
||||||
tr("Speech Synthesis"),
|
if saved_voice_name_index >= len(friendly_names) and friendly_names:
|
||||||
options=list(friendly_names.values()),
|
saved_voice_name_index = 0
|
||||||
index=saved_voice_name_index,
|
|
||||||
)
|
|
||||||
|
|
||||||
voice_name = list(friendly_names.keys())[
|
# 确保有声音可选
|
||||||
list(friendly_names.values()).index(selected_friendly_name)
|
if friendly_names:
|
||||||
]
|
selected_friendly_name = st.selectbox(
|
||||||
params.voice_name = voice_name
|
tr("Speech Synthesis"),
|
||||||
config.ui["voice_name"] = voice_name
|
options=list(friendly_names.values()),
|
||||||
|
index=min(saved_voice_name_index, len(friendly_names) - 1)
|
||||||
|
if friendly_names
|
||||||
|
else 0,
|
||||||
|
)
|
||||||
|
|
||||||
if st.button(tr("Play Voice")):
|
voice_name = list(friendly_names.keys())[
|
||||||
|
list(friendly_names.values()).index(selected_friendly_name)
|
||||||
|
]
|
||||||
|
params.voice_name = voice_name
|
||||||
|
config.ui["voice_name"] = voice_name
|
||||||
|
else:
|
||||||
|
# 如果没有声音可选,显示提示信息
|
||||||
|
st.warning(
|
||||||
|
tr(
|
||||||
|
"No voices available for the selected TTS server. Please select another server."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
params.voice_name = ""
|
||||||
|
config.ui["voice_name"] = ""
|
||||||
|
|
||||||
|
# 只有在有声音可选时才显示试听按钮
|
||||||
|
if friendly_names and st.button(tr("Play Voice")):
|
||||||
play_content = params.video_subject
|
play_content = params.video_subject
|
||||||
if not play_content:
|
if not play_content:
|
||||||
play_content = params.video_script
|
play_content = params.video_script
|
||||||
@@ -680,7 +736,10 @@ with middle_panel:
|
|||||||
if os.path.exists(audio_file):
|
if os.path.exists(audio_file):
|
||||||
os.remove(audio_file)
|
os.remove(audio_file)
|
||||||
|
|
||||||
if voice.is_azure_v2_voice(voice_name):
|
# 当选择V2版本或者声音是V2声音时,显示服务区域和API key输入框
|
||||||
|
if selected_tts_server == "azure-tts-v2" or (
|
||||||
|
voice_name and voice.is_azure_v2_voice(voice_name)
|
||||||
|
):
|
||||||
saved_azure_speech_region = config.azure.get("speech_region", "")
|
saved_azure_speech_region = config.azure.get("speech_region", "")
|
||||||
saved_azure_speech_key = config.azure.get("speech_key", "")
|
saved_azure_speech_key = config.azure.get("speech_key", "")
|
||||||
azure_speech_region = st.text_input(
|
azure_speech_region = st.text_input(
|
||||||
|
|||||||
@@ -91,6 +91,8 @@
|
|||||||
"Voice Example": "Dies ist ein Beispieltext zum Testen der Sprachsynthese",
|
"Voice Example": "Dies ist ein Beispieltext zum Testen der Sprachsynthese",
|
||||||
"Synthesizing Voice": "Sprachsynthese läuft, bitte warten...",
|
"Synthesizing Voice": "Sprachsynthese läuft, bitte warten...",
|
||||||
"TTS Provider": "Sprachsynthese-Anbieter auswählen",
|
"TTS Provider": "Sprachsynthese-Anbieter auswählen",
|
||||||
|
"TTS Servers": "TTS-Server",
|
||||||
|
"No voices available for the selected TTS server. Please select another server.": "Keine Stimmen für den ausgewählten TTS-Server verfügbar. Bitte wählen Sie einen anderen Server.",
|
||||||
"Hide Log": "Protokoll ausblenden",
|
"Hide Log": "Protokoll ausblenden",
|
||||||
"Hide Basic Settings": "Basis-Einstellungen ausblenden\n\nWenn diese Option deaktiviert ist, wird die Basis-Einstellungen-Leiste nicht auf der Seite angezeigt.\n\nWenn Sie sie erneut anzeigen möchten, setzen Sie `hide_config = false` in `config.toml`",
|
"Hide Basic Settings": "Basis-Einstellungen ausblenden\n\nWenn diese Option deaktiviert ist, wird die Basis-Einstellungen-Leiste nicht auf der Seite angezeigt.\n\nWenn Sie sie erneut anzeigen möchten, setzen Sie `hide_config = false` in `config.toml`",
|
||||||
"LLM Settings": "**LLM-Einstellungen**",
|
"LLM Settings": "**LLM-Einstellungen**",
|
||||||
|
|||||||
@@ -91,6 +91,8 @@
|
|||||||
"Voice Example": "This is an example text for testing speech synthesis",
|
"Voice Example": "This is an example text for testing speech synthesis",
|
||||||
"Synthesizing Voice": "Synthesizing voice, please wait...",
|
"Synthesizing Voice": "Synthesizing voice, please wait...",
|
||||||
"TTS Provider": "Select the voice synthesis provider",
|
"TTS Provider": "Select the voice synthesis provider",
|
||||||
|
"TTS Servers": "TTS Servers",
|
||||||
|
"No voices available for the selected TTS server. Please select another server.": "No voices available for the selected TTS server. Please select another server.",
|
||||||
"Hide Log": "Hide Log",
|
"Hide Log": "Hide Log",
|
||||||
"Hide Basic Settings": "Hide Basic Settings\n\nHidden, the basic settings panel will not be displayed on the page.\n\nIf you need to display it again, please set `hide_config = false` in `config.toml`",
|
"Hide Basic Settings": "Hide Basic Settings\n\nHidden, the basic settings panel will not be displayed on the page.\n\nIf you need to display it again, please set `hide_config = false` in `config.toml`",
|
||||||
"LLM Settings": "**LLM Settings**",
|
"LLM Settings": "**LLM Settings**",
|
||||||
|
|||||||
@@ -91,6 +91,8 @@
|
|||||||
"Voice Example": "Este é um exemplo de texto para testar a síntese de fala",
|
"Voice Example": "Este é um exemplo de texto para testar a síntese de fala",
|
||||||
"Synthesizing Voice": "Sintetizando voz, por favor aguarde...",
|
"Synthesizing Voice": "Sintetizando voz, por favor aguarde...",
|
||||||
"TTS Provider": "Selecione o provedor de síntese de voz",
|
"TTS Provider": "Selecione o provedor de síntese de voz",
|
||||||
|
"TTS Servers": "Servidores TTS",
|
||||||
|
"No voices available for the selected TTS server. Please select another server.": "Não há vozes disponíveis para o servidor TTS selecionado. Por favor, selecione outro servidor.",
|
||||||
"Hide Log": "Ocultar Log",
|
"Hide Log": "Ocultar Log",
|
||||||
"Hide Basic Settings": "Ocultar Configurações Básicas\n\nOculto, o painel de configurações básicas não será exibido na página.\n\nSe precisar exibi-lo novamente, defina `hide_config = false` em `config.toml`",
|
"Hide Basic Settings": "Ocultar Configurações Básicas\n\nOculto, o painel de configurações básicas não será exibido na página.\n\nSe precisar exibi-lo novamente, defina `hide_config = false` em `config.toml`",
|
||||||
"LLM Settings": "**Configurações do LLM**",
|
"LLM Settings": "**Configurações do LLM**",
|
||||||
|
|||||||
@@ -91,6 +91,8 @@
|
|||||||
"Voice Example": "Đây là văn bản mẫu để kiểm tra tổng hợp giọng nói",
|
"Voice Example": "Đây là văn bản mẫu để kiểm tra tổng hợp giọng nói",
|
||||||
"Synthesizing Voice": "Đang tổng hợp giọng nói, vui lòng đợi...",
|
"Synthesizing Voice": "Đang tổng hợp giọng nói, vui lòng đợi...",
|
||||||
"TTS Provider": "Chọn nhà cung cấp tổng hợp giọng nói",
|
"TTS Provider": "Chọn nhà cung cấp tổng hợp giọng nói",
|
||||||
|
"TTS Servers": "Máy chủ TTS",
|
||||||
|
"No voices available for the selected TTS server. Please select another server.": "Không có giọng nói nào cho máy chủ TTS đã chọn. Vui lòng chọn máy chủ khác.",
|
||||||
"Hide Log": "Ẩn Nhật Ký",
|
"Hide Log": "Ẩn Nhật Ký",
|
||||||
"Hide Basic Settings": "Ẩn Cài Đặt Cơ Bản\n\nẨn, thanh cài đặt cơ bản sẽ không hiển thị trên trang web.\n\nNếu bạn muốn hiển thị lại, vui lòng đặt `hide_config = false` trong `config.toml`",
|
"Hide Basic Settings": "Ẩn Cài Đặt Cơ Bản\n\nẨn, thanh cài đặt cơ bản sẽ không hiển thị trên trang web.\n\nNếu bạn muốn hiển thị lại, vui lòng đặt `hide_config = false` trong `config.toml`",
|
||||||
"LLM Settings": "**Cài Đặt LLM**",
|
"LLM Settings": "**Cài Đặt LLM**",
|
||||||
|
|||||||
@@ -91,6 +91,8 @@
|
|||||||
"Voice Example": "这是一段测试语音合成的示例文本",
|
"Voice Example": "这是一段测试语音合成的示例文本",
|
||||||
"Synthesizing Voice": "语音合成中,请稍候...",
|
"Synthesizing Voice": "语音合成中,请稍候...",
|
||||||
"TTS Provider": "语音合成提供商",
|
"TTS Provider": "语音合成提供商",
|
||||||
|
"TTS Servers": "TTS服务器",
|
||||||
|
"No voices available for the selected TTS server. Please select another server.": "当前选择的TTS服务器没有可用的声音,请选择其他服务器。",
|
||||||
"Hide Log": "隐藏日志",
|
"Hide Log": "隐藏日志",
|
||||||
"Hide Basic Settings": "隐藏基础设置\n\n隐藏后,基础设置面板将不会显示在页面中。\n\n如需要再次显示,请在 `config.toml` 中设置 `hide_config = false`",
|
"Hide Basic Settings": "隐藏基础设置\n\n隐藏后,基础设置面板将不会显示在页面中。\n\n如需要再次显示,请在 `config.toml` 中设置 `hide_config = false`",
|
||||||
"LLM Settings": "**大模型设置**",
|
"LLM Settings": "**大模型设置**",
|
||||||
|
|||||||
Reference in New Issue
Block a user