GPT-SoVITS的批量克隆声音并且合并
标是将每一段声音通过GPT-SoVITS的API的API进行克隆,因为拼在一起的整个片段处理会造成内存或者缓存溢出
将目录下的音频文件生成到指定目录下,然后再进行拼接。
通过AI工具箱生成的数据文件是这样的结构,temp目录下是没个片段生成的部分,==connect_==是正常拼接的音频文件,==silent_==是剪切无声片段的音频文件,
这里克隆后会拼接生成一个 clone的音频文件。
然后移动到指定的目录下。
完整代码:
# env 日常使用目录/py
# -*- coding: UTF-8 -*-
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", "MrDataYang-e20.ckpt")
result_gpt = client.predict(
"GPT_SoVITS/pretrained_models/s1bert25hz-2kh-longer-epoch=68e-step=50232.ckpt",
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/02.Python 编程基础'
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\ 1.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 10.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 11.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 12.wav',
# 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 13.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 14.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 15.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 16.wav',
# 'wav\ Python 学习笔记 - 探索5种数据类型\ temp\ 17.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 18.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 19.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 2.wav',
# 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 20.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 21.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 22.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 23.wav',
# 'wav\ Python学习笔记 - 探 索5种数据类型\ temp\ 24.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 25.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 26.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 3.wav',
# 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 4.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 5.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 6.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 7.wav',
# 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 8.wav', 'wav\ Python学习笔记 - 探索5种数据类型\ temp\ 9.wav']
# 如果存在符合条件的文件,则打印这些文件的路径
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)
# 1.wav H:\日常使用目录\6.文章阅读\《红楼梦》\0118-第一百十八回 记微嫌舅兄欺弱女 惊谜语妻妾谏痴人\1.wav
# 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)
多音频合成一个音频:
from pydub import AudioSegment
import os
import shutil
# 合并音频文件
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")
# 指定目录路径
base_dir = 'yin_data'
temp = 'yin_hecheng_data'
# 合并音频文件
result_path = "E:/project/test/GLM_fastapi/yin_hecheng_data/hengcheng2.wav"
# dest_dir = 'E:/project/test/GLM_fastapi'
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))
# 所有文件的相对路径列表
# 如果存在符合条件的文件,则打印这些文件的路径
if valid_files:
# 清空temp目录
shutil.rmtree(temp)
os.makedirs(temp)
print("result_path", result_path)
# 检查文件是否已存在
if os.path.exists(result_path):
print(f"文件 {result_path} 已存在,跳过合并。")
# continue # 跳过当前循环的剩余部分
print(f"开始处理文件夹:{os.path.basename(subdir)} 下的.wav文件路径:")
merge_wav_files(base_dir, result_path)