File size: 6,581 Bytes
599ffe3 a96de63 599ffe3 a96de63 599ffe3 a96de63 599ffe3 a96de63 599ffe3 a96de63 599ffe3 a96de63 599ffe3 a96de63 599ffe3 a96de63 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# app.py
import gradio as gr
import requests
import tempfile
from languages import languages
def generate_audio(input_text, model, voice, output_format, base_url_input, api_key_input, request: gr.Request):
# 获取 URL 参数
query_params = request.query_params
# 优先使用 URL 参数中的 base_url 和 api_key
base_url = query_params.get("base_url", base_url_input)
api_key = query_params.get("api_key", api_key_input)
# 准备请求负载
payload = {
"model": model, # 使用选择的模型
"input": input_text,
"voice": voice.lower(),
"format": output_format
}
headers = {
'Authorization': api_key,
'Content-Type': 'application/json'
}
# 构造请求 URL
url = f"{base_url}/v1/audio/speech"
# 发起 POST 请求
response = requests.post(url, headers=headers, json=payload)
# 检查是否有错误
if response.status_code != 200:
raise gr.Error(f"错误:{response.status_code} {response.text}")
# 获取音频内容
audio_content = response.content
# 创建临时文件
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=f".{output_format}")
with open(temp_file.name, 'wb') as f:
f.write(audio_content)
# 返回文件路径
return temp_file.name
def on_generate_click(input_text_value, model_value, voice_value, output_format_value, base_url_value, api_key_value, request: gr.Request):
audio_path = generate_audio(input_text_value, model_value, voice_value, output_format_value, base_url_value, api_key_value, request)
return audio_path
def update_settings_from_url(request: gr.Request):
# 获取 URL 参数
query_params = request.query_params
base_url = query_params.get("base_url", None)
api_key = query_params.get("api_key", None)
base_url_update = gr.update()
api_key_update = gr.update()
if base_url is not None:
base_url_update = gr.update(value=base_url)
if api_key is not None:
api_key_update = gr.update(value=api_key)
return base_url_update, api_key_update
def update_language(language_choice):
labels = languages[language_choice]
updates = [
gr.update(value=f"# {labels['title']}"), # title_markdown
gr.update(value=labels['intro']), # intro_text
gr.update(label=labels['input_text_label'], placeholder=labels['input_text_placeholder']), # input_text
gr.update(label=labels['model_label']), # model
gr.update(label=labels['voice_label']), # voice
gr.update(label=labels['output_format_label']), # output_format
gr.update(value=labels['generate_button_label']), # generate_button
gr.update(label=labels['output_audio_label']), # audio_output
gr.update(label=labels['settings_label']), # settings_accordion
gr.update(label=labels['base_url_label']), # base_url_input
gr.update(label=labels['api_key_label']), # api_key_input
gr.update(value=labels['BOW']), # mode_toggle_btn now uses value instead of label
gr.update(label=labels['language_label']), # language_choice_comp
]
return updates
def toggle_dark_mode(current_mode):
# 切换明亮/黑暗模式
if current_mode == "light":
return "dark"
return "light"
# 获取初始主题和模式(可以从配置文件或其他方式获取)
initial_mode = "light"
# 添加主题设置
with gr.Blocks(css=None, theme="Zarkel/IBM_Carbon_Theme", title="TTS Web") as demo:
# 使用状态存储当前模式
mode_state = gr.State(value=initial_mode)
# 布局
with gr.Row():
with gr.Column(scale=3):
title_markdown = gr.Markdown("# OpenAI TTS Web")
intro_text = gr.Markdown(languages["中文"]["intro"]) # 初始加载中文的介绍
# 输入文本
input_text = gr.Textbox(label="输入文本", placeholder="请输入要合成的文本")
# 选择模型
model = gr.Radio(choices=["tts-1", "tts-1-hd"], label="模型", value="tts-1")
# 选择声音
voice = gr.Radio(choices=["Alloy", "Echo", "Fable", "Onyx", "Nova", "Shimmer"], label="声音", value="Alloy")
# 选择输出格式
output_format = gr.Radio(choices=["mp3", "opus", "aac", "flac", "pcm"], label="输出格式", value="mp3")
# 生成按钮
generate_button = gr.Button("生成")
# 输出音频
audio_output = gr.Audio(label="输出音频", type="filepath")
with gr.Column(scale=1):
# 设置
with gr.Accordion("设置", open=True) as settings_accordion:
# 切换界面模式按钮
mode_toggle_btn = gr.Button("切换黑白模式")
# 选择语言
language_choice_comp = gr.Radio(choices=["中文", "English"], label="界面语言", value="中文")
# 基础设置
base_url_input = gr.Textbox(label="Base URL", value="https://api.maktubcn.info")
api_key_input = gr.Textbox(label="API Key", type="password")
# 界面加载时更新设置
demo.load(
update_settings_from_url,
inputs=None,
outputs=[base_url_input, api_key_input]
)
# 语言选择事件
language_choice_comp.change(
update_language,
inputs=language_choice_comp,
outputs=[
title_markdown,
intro_text, # 添加 intro_text 的更新
input_text,
model, # 更新模型组件
voice,
output_format,
generate_button,
audio_output,
settings_accordion,
base_url_input,
api_key_input,
mode_toggle_btn,
language_choice_comp,
]
)
# 切换黑白模式按钮
mode_toggle_btn.click(
lambda current_mode: toggle_dark_mode(current_mode),
inputs=[mode_state],
outputs=[mode_state],
js="""
() => {
if (document.body.classList.contains('dark')) {
document.body.classList.remove('dark');
} else {
document.body.classList.add('dark');
}
}
"""
)
# 按钮点击事件
generate_button.click(
on_generate_click,
inputs=[input_text, model, voice, output_format, base_url_input, api_key_input, gr.Request()],
outputs=[audio_output]
)
demo.launch(server_name="0.0.0.0", server_port=7860) |