基于GPT-SoVITS的API实现批量克隆声音
# env 日常使用目录/py
# -*- coding: UTF-8 -*-
'''
@Project :日常使用目录
@File :
@IDE :PyCharm
@Author :Mr数据杨
@Date :2024/3/27 16:24
'''
from pydub import AudioSegment
import shutil
import os
from gradio_client import Client, handle_file
# API的URL
client = Client("http://localhost:9888/")
base_dir = "H:/MyScriptPublic/AIGC/GPT-SoVITS-Gradio【bak】/"
change_sovits_weights = os.path.join(base_dir, "SoVITS_weights", "MrDataYang_e8_s1400.pth")
result_sovits = client.predict(
change_sovits_weights,
api_name="/change_sovits_weights"
)
change_sovits_weights = os.path.join(base_dir, "GPT_weights", "")
result_gpt = client.predict(
"GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=",
api_name="/change_gpt_weights"
)
# 合并音频文件
def merge_wav_files(directory, result_path):
# 获取所有.wav文件并按文件名排序
files = sorted([f for f in os.listdir(directory) if f.endswith('.wav')], key=lambda x:int(x.split('.')[0]))
print(directory, result_path)
print(files)
# 初始化一个空的音频段
combined = AudioSegment.empty()
# 依次加载每个文件并追加到combined变量中
for file in files:
path = os.path.join(directory, file)
audio = AudioSegment.from_wav(path)
combined += audio
# 导出合并后的文件
combined.export(result_path, format="wav")
def move_files_and_directories(src_dir, matching_directory):
# 确保目标目录存在,不存在则创建
os.makedirs(matching_directory, exist_ok=True)
wav_matching_directory = os.path.join(matching_directory, 'wav')
os.makedirs(wav_matching_directory, exist_ok=True)
# 遍历源目录中的所有文件和子目录
for root, dirs, files in os.walk(src_dir):
# 计算目标路径的子目录路径
relative_path = os.path.relpath(root, src_dir)
dest_path = os.path.join(wav_matching_directory, relative_path)
# 确保目标路径的子目录存在
os.makedirs(dest_path, exist_ok=True)
# 移动文件
for filename in files:
src_file = os.path.join(root, filename)
dest_file = os.path.join(dest_path, filename)
shutil.move(src_file, dest_file)
print(f"Moved: {src_file} to {dest_file}")
# 移动完成后,删除空的源目录
shutil.rmtree(src_dir)
print(f"Deleted empty source directory: {src_dir}")
def find_matching_directory(dest_dir, dir_name):
# 获取目标目录下的所有文件夹名称
for root, dirs, files in os.walk(dest_dir):
for folder in dirs:
# 检查 dir_name 是否包含在某个文件夹名称中
if dir_name in folder:
matching_dir = os.path.join(root, folder)
print(f"Found matching directory: {matching_dir}")
return matching_dir # 返回匹配的目录路径
# 如果没有找到匹配的文件夹,返回 None
print(f"No matching directory found for {dir_name} in {dest_dir}.")
return None
# 指定目录路径
base_dir = 'wav'
temp = 'temp_wav'
dest_dir = 'E:/Document and Video/ 编程基础'
for subdir, dirs, files in os.walk(base_dir):
# 初始化符合条件的文件列表
valid_files = []
# 检查每个文件是否符合条件
for file in files:
if file.endswith('.wav') and not 'txt' in file and file[0].isdigit():
valid_files.append(os.path.join(subdir, file))
# 所有文件的相对路径列表
# ['wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\',
# 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\',
# 'wav\\Python 学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\',
# 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\',
# 'wav\\Python学习笔记 - 探 索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\',
# 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\',
# 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\', 'wav\\Python学习笔记 - 探索5种数据类型\\temp\\']
# 如果存在符合条件的文件,则打印这些文件的路径
if valid_files:
menu_name = os.path.abspath(subdir).replace('\\temp', '')
dir_name = menu_name.split("\\")[-1]
# 0120-第一百二零回 甄士隐详说太虚情 贾雨村归结红楼梦
print("menu_name", menu_name) # H:\MyScriptPublic\AIGC\so-vits-svc_2023-08-18\克隆 API\wav\Python学习笔记 - 探索5种数据类型
print("dir_name", dir_name) # Python学习笔记 - 探索5种数据类型
# 清空temp目录
shutil.rmtree(temp)
os.makedirs(temp)
# 合并音频文件
result_path = os.path.join(menu_name, "clone_" + dir_name + '.wav')
print("result_path", result_path)
# 检查文件是否已存在
if os.path.exists(result_path):
print(f"文件 {result_path} 已存在,跳过合并。")
# continue # 跳过当前循环的剩余部分
print(f"开始处理文件夹:{os.path.basename(subdir)} 下的.wav文件路径:")
for wav_file in valid_files:
abs_path = os.path.abspath(wav_file)
wav_name = os.path.basename(abs_path)
print('开始处理文件:', wav_name, abs_path)
# H:\日常使用目录\6.文章阅读\《红楼梦》\0118-第一百十八回 记微嫌舅兄欺弱女 惊谜语妻妾谏痴人\
# 3-10秒样例文件
sample_file = "H:/MyScriptPublic/AIGC/GPT-SoVITS-Gradio【bak】/logs/MrDataYang/5-wav32k/MrDataYang_1_FormatFactoryPart1.wav_0000000000_0000240960.wav"
source_path = client.predict(
handle_file(abs_path), # filepath in '源音频' Audio component
"Hello!!", # str in '源音频对应文本' Textbox component
"中英混合", # Literal['中文', '英文', '日文', '中英混合', '日英混合', '多语种混合'] in '文本语种' Dropdown component
handle_file(sample_file), # filepath in '请上传 3~10 秒内参考音频,超过会报警!' Audio component
api_name="/vc_main"
)
# 创建目标目录路径
target_path = os.path.join(temp, wav_name)
# 复制并重命名文件
shutil.copy(source_path, target_path)
# 合并文件保存结果
merge_wav_files(temp, result_path)
src_dir = menu_name.replace("\\", '/')
print("src_dir", src_dir)
matching_directory = find_matching_directory(dest_dir, dir_name).replace("\\", '/')
print("matching_directory", matching_directory)
dest_dir = os.path.join(dest_dir, dir_name).replace("\\", '/')
print("src_dir", src_dir)
print("dest_dir", dest_dir)
move_files_and_directories(src_dir, matching_directory)