-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsyclone.py
More file actions
executable file
·311 lines (257 loc) · 12.6 KB
/
syclone.py
File metadata and controls
executable file
·311 lines (257 loc) · 12.6 KB
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# 终端执行命令:
# cd /Volumes/AI/AI/GPT-SoVITS && conda activate GPTSoVits && ./go-api_v2.py.command
# API接口代码为:
# http://127.0.0.1:9880/tts?text=输入需要语音合成的内容。&text_lang=zh&ref_audio_path=./output/slicer_opt/hao.wav&prompt_lang=zh&prompt_text=爸爸,胡老师还以为爸爸没有来,然后我就去哪个墙壁里面躲着。&text_split_method=cut5&batch_size=1&media_type=wav&streaming_mode=true
# http://127.0.0.1:9880/tts?text=输入需要语音合成的内容。&text_lang=zh&ref_audio_path=./output/slicer_opt/yanbo109.wav&prompt_lang=zh&prompt_text=北宋诗人苏轼曾说,寄浮游于天地,渺沧海之遗粟。&text_split_method=cut5&batch_size=1&media_type=wav&streaming_mode=true
# YB接口
# http://127.0.0.1:9880/set_gpt_weights?weights_path=GPT_weights/yanbo109-e15.ckpt
# WQ接口
# http://127.0.0.1:9880/set_gpt_weights?weights_path=GPT_weights/weiqin109-e15.ckpt
# V1接口
# http://127.0.0.1:9880/set_gpt_weights?weights_path=GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=50232.ckpt
# http://127.0.0.1:9880/set_sovits_weights?weights_path=GPT_SoVITS/pretrained_models/s2G488k.pth
# V2接口
# http://127.0.0.1:9880/set_gpt_weights?weights_path=GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s1bert25hz-5kh-longer-epoch=12-step=369668.ckpt
# http://127.0.0.1:9880/set_sovits_weights?weights_path=GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s2G2333k.pth
# V3接口
# http://127.0.0.1:9880/set_gpt_weights?weights_path=GPT_SoVITS/pretrained_models/s1v3.ckpt
# http://127.0.0.1:9880/set_sovits_weights?weights_path=GPT_SoVITS/pretrained_models/s2Gv3.pth
# 重启
# http://127.0.0.1:9880/control?command=restart
import gradio as gr
import requests
import os
from pathlib import Path
import shutil
from datetime import datetime
# 设置住文件目录
sydir = "/Volumes/AI/AI/GPT-SoVITS/output/slicer_opt"
def copy_file_to_destination(uploaded_file, destination_dir):
# 确保目标目录存在
os.makedirs(destination_dir, exist_ok=True)
# 构建目标文件路径
dest_path = os.path.join(destination_dir, os.path.basename(uploaded_file))
# 复制文件
shutil.copy2(uploaded_file, dest_path)
return dest_path
def generate_audio(text, ref_audio, prompt_text):
if not text:
return "请输入要合成的文本!", None
try:
# 构建API请求URL
base_url = "http://127.0.0.1:9880/tts"
# 修复目标目录路径
# dest_dir = os.path.join("F:", "SOFT", "GPT-SoVITS-v3-20250212", "output", "slicer_opt")
dest_dir = sydir
# 如果有上传新的音频文件,复制到目标目录
if ref_audio:
copy_file_to_destination(ref_audio, dest_dir)
ref_path = f"./output/slicer_opt/{os.path.basename(ref_audio)}"
else:
ref_path = "./output/slicer_opt/hao.wav"
params = {
"text": text,
"text_lang": "zh",
"ref_audio_path": ref_path,
"prompt_lang": "zh",
"prompt_text": prompt_text or "爸爸,胡老师还以为爸爸没有来,然后我就去哪个墙壁里面躲着。",
"text_split_method": "cut5",
"batch_size": "1",
"media_type": "wav",
"streaming_mode": "true"
}
# 如果有上传新的音频文件,复制到目标目录
if ref_audio:
dest_dir = sydir
copy_file_to_destination(ref_audio, dest_dir)
# 发送API请求
response = requests.get(base_url, params=params, timeout=30)
if response.status_code == 200:
# 保存音频文件
# audio_file = "output.wav"
# 提取文件名(带扩展名)
filename = os.path.basename(ref_path) # "hao.wav"
# 分割文件名和扩展名
basename, ext = os.path.splitext(filename) # basename="hao", ext=".wav"
# 生成日期时间戳(格式示例:20230306-111514)
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
# 组合新文件名
# audio_file = f"{basename}-{timestamp}{ext}" # "hao-20230306-111514.wav"
# 定义目标目录和文件名
target_dir = "声音生成" # 子目录名称
audio_file = os.path.join(target_dir, f"{basename}-{timestamp}{ext}") # 路径拼接
# 确保目标目录存在(如果不存在则创建)
os.makedirs(target_dir, exist_ok=True)
with open(audio_file, "wb") as f:
f.write(response.content)
return f"{audio_file} 音频生成成功!", audio_file
else:
return f"生成失败:HTTP状态码{response.status_code}", None
except requests.Timeout:
return "请求超时,请检查服务是否正常运行", None
except requests.ConnectionError:
return "连接失败,请检查服务是否启动", None
except Exception as e:
return f"发生错误:{str(e)}", None
def switch_model(model_name):
base_url = "http://127.0.0.1:9880"
try:
if model_name == "YB接口":
response = requests.get(f"{base_url}/set_gpt_weights", params={
"weights_path": "GPT_weights/yanbo109-e15.ckpt"
})
return f"YB模型切换状态: {response.status_code}", f"{base_url}/set_gpt_weights?weights_path=GPT_weights/yanbo109-e15.ckpt"
elif model_name == "WQ接口":
response = requests.get(f"{base_url}/set_gpt_weights", params={
"weights_path": "GPT_weights/weiqin109-e15.ckpt"
})
return f"WQ模型切换状态: {response.status_code}", f"{base_url}/set_gpt_weights?weights_path=GPT_weights/weiqin109-e15.ckpt"
elif model_name in ["V1接口", "V2接口", "V3接口","F2024接口","蔡徐坤pro"]:
paths = {
"V1接口": {
"gpt": "GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=50232.ckpt",
"sovits": "GPT_SoVITS/pretrained_models/s2G488k.pth"
},
"V2接口": {
"gpt": "GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s1bert25hz-5kh-longer-epoch=12-step=369668.ckpt",
"sovits": "GPT_SoVITS/pretrained_models/gsv-v2final-pretrained/s2G2333k.pth"
},
"V3接口": {
"gpt": "GPT_SoVITS/pretrained_models/s1v3.ckpt",
"sovits": "GPT_SoVITS/pretrained_models/s2Gv3.pth"
},
"F2024接口": {
"gpt": "GPT_weights_v2/f1027-e15.ckpt",
"sovits": "SoVITS_weights_v2/f1027_e8_s208.pth"
},
"蔡徐坤pro": {
"gpt": "GPT_weights_v2/蔡徐坤pro-e15.ckpt",
"sovits": "SoVITS_weights_v2/蔡徐坤pro_e12_s660.pth"
}
}
gpt_response = requests.get(f"{base_url}/set_gpt_weights", params={
"weights_path": paths[model_name]["gpt"]
})
sovits_response = requests.get(f"{base_url}/set_sovits_weights", params={
"weights_path": paths[model_name]["sovits"]
})
status = f"{model_name}切换状态:\nGPT: {gpt_response.status_code}\nSoVITS: {sovits_response.status_code}"
urls = f"GPT URL: {base_url}/set_gpt_weights?weights_path={paths[model_name]['gpt']}\nSoVITS URL: {base_url}/set_sovits_weights?weights_path={paths[model_name]['sovits']}"
return status, urls
except Exception as e:
return f"切换失败:{str(e)}", "无法获取URL"
# 用于获取 ./output/slicer_opt/ 目录下的所有 WAV 文件
def get_wav_files():
wav_dir = sydir
wav_files = [f for f in os.listdir(wav_dir) if f.endswith('.wav')]
return wav_files
# 用于从文字.txt文件中读取对应的提示文本
def get_prompt_text(wav_filename):
try:
txt_path = os.path.join(sydir, "文字.txt") # 使用 os.path.join 来正确拼接路径
if not os.path.exists(txt_path):
# print(f"文件不存在: {txt_path}")
return "提示:文字.txt 文件不存在,将使用默认提示文本"
with open(txt_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 移除文件名中的.wav后缀
wav_name = wav_filename.replace('.wav', '')
# 构建音频名和文本的映射
text_map = {}
current_key = None
for line in lines:
line = line.strip()
if not line: # 跳过空行
continue
if line == '-----': # 跳过分隔符
continue
if current_key is None:
current_key = line
else:
text_map[current_key] = line
current_key = None
# 查找对应的文本
if wav_name in text_map:
print(f"找到匹配: {wav_name} -> {text_map[wav_name]}")
return text_map[wav_name]
print(f"未找到匹配的文本,文件名: {wav_name}")
print(f"当前映射表: {text_map}")
# return ""
return text_map.get(wav_name, "未找到对应的提示文本,将使用默认提示文本")
except UnicodeDecodeError:
return "文件编码错误,请确保文字.txt为UTF-8编码"
except Exception as e:
return f"读取提示文本错误:{str(e)}"
# 用于处理声音选择后的自动更新
def update_audio_and_prompt(wav_filename):
if not wav_filename:
return None, ""
wav_path = os.path.join(sydir, wav_filename)
prompt = get_prompt_text(wav_filename)
return wav_path, prompt
# 创建界面
with gr.Blocks(title="BOZO 专用声音生成器") as demo:
with gr.Column():
gr.Markdown("# BOZO 专用声音生成器")
# 文本输入区域移到最上方
text_input = gr.Textbox(
label="请输入要合成的文本",
placeholder="输入需要语音合成的内容",
lines=5
)
# 声音选择区域
with gr.Row():
voice_dropdown = gr.Dropdown(
choices=get_wav_files(),
label="选择声音",
value=None
)
# 音频上传和提示文本并排显示
with gr.Row():
audio_input = gr.Audio(
label="上传参考音频文件(可选)",
type="filepath",
format="wav"
)
prompt_input = gr.Textbox(
label="提示文本",
value="爸爸,胡老师还以为爸爸没有来,然后我就去哪个墙壁里面躲着。",
placeholder="输入提示文本",
lines=7
)
# 生成按钮
generate_btn = gr.Button("生成音频")
# 状态信息和音频输出并排显示
with gr.Row():
output_text = gr.Textbox(label="状态信息")
output_audio = gr.Audio(label="生成的音频")
# 模型选择区域
with gr.Row():
model_dropdown = gr.Dropdown(
choices=["YB接口", "WQ接口", "V1接口", "V2接口", "V3接口", "F2024接口", "蔡徐坤pro"],
label="选择模型接口",
value="YB接口"
)
switch_btn = gr.Button("切换模型")
with gr.Row():
model_status = gr.Textbox(label="模型切换状态", lines=3)
model_url = gr.Textbox(label="接口URL", lines=3)
# 添加声音选择的响应函数
voice_dropdown.change(
fn=update_audio_and_prompt,
inputs=[voice_dropdown],
outputs=[audio_input, prompt_input]
)
generate_btn.click(
fn=generate_audio,
inputs=[text_input, audio_input, prompt_input],
outputs=[output_text, output_audio]
)
switch_btn.click(
fn=switch_model,
inputs=[model_dropdown],
outputs=[model_status, model_url]
)
# 启动应用
if __name__ == "__main__":
demo.launch(inbrowser=True)