|
import gradio as gr |
|
from inference import Inference |
|
import os |
|
import zipfile |
|
import hashlib |
|
from utils.model import model_downloader, get_model |
|
import requests |
|
import json |
|
import torch |
|
from tts.constants import VOICE_METHODS, BARK_VOICES, EDGE_VOICES |
|
from tts.conversion import tts_infer, ELEVENLABS_VOICES_RAW, ELEVENLABS_VOICES_NAMES, COQUI_LANGUAGES |
|
|
|
api_url = "https://rvc-models-api.onrender.com/uploadfile/" |
|
|
|
zips_folder = "./zips" |
|
unzips_folder = "./unzips" |
|
if not os.path.exists(zips_folder): |
|
os.mkdir(zips_folder) |
|
if not os.path.exists(unzips_folder): |
|
os.mkdir(unzips_folder) |
|
|
|
def get_info(path): |
|
path = os.path.join(unzips_folder, path) |
|
try: |
|
a = torch.load(path, map_location="cpu") |
|
return a |
|
except Exception as e: |
|
print("*****************eeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrr*****") |
|
print(e) |
|
return { |
|
|
|
} |
|
def calculate_md5(file_path): |
|
hash_md5 = hashlib.md5() |
|
with open(file_path, "rb") as f: |
|
for chunk in iter(lambda: f.read(4096), b""): |
|
hash_md5.update(chunk) |
|
return hash_md5.hexdigest() |
|
|
|
def compress(modelname, files): |
|
file_path = os.path.join(zips_folder, f"{modelname}.zip") |
|
|
|
|
|
compression = zipfile.ZIP_DEFLATED |
|
|
|
|
|
if not os.path.exists(file_path): |
|
|
|
with zipfile.ZipFile(file_path, mode="w") as zf: |
|
try: |
|
for file in files: |
|
if file: |
|
|
|
zf.write(unzips_folder if ".index" in file else os.path.join(unzips_folder, file), compress_type=compression) |
|
except FileNotFoundError as fnf: |
|
print("An error occurred", fnf) |
|
else: |
|
|
|
with zipfile.ZipFile(file_path, mode="a") as zf: |
|
try: |
|
for file in files: |
|
if file: |
|
|
|
zf.write(unzips_folder if ".index" in file else os.path.join(unzips_folder, file), compress_type=compression) |
|
except FileNotFoundError as fnf: |
|
print("An error occurred", fnf) |
|
|
|
return file_path |
|
|
|
def infer(model, f0_method, audio_file): |
|
print("****", audio_file) |
|
inference = Inference( |
|
model_name=model, |
|
f0_method=f0_method, |
|
source_audio_path=audio_file, |
|
output_file_name=os.path.join("./audio-outputs", os.path.basename(audio_file)) |
|
) |
|
output = inference.run() |
|
if 'success' in output and output['success']: |
|
return output, output['file'] |
|
else: |
|
return |
|
|
|
|
|
def post_model(name, model_url, version, creator): |
|
modelname = model_downloader(model_url, zips_folder, unzips_folder) |
|
model_files = get_model(unzips_folder, modelname) |
|
|
|
if not model_files: |
|
return "No se encontrado un modelo valido, verifica el contenido del enlace e intentalo más tarde." |
|
|
|
if not model_files.get('pth'): |
|
return "No se encontrado un modelo valido, verifica el contenido del enlace e intentalo más tarde." |
|
|
|
md5_hash = calculate_md5(os.path.join(unzips_folder,model_files['pth'])) |
|
zipfile = compress(modelname, list(model_files.values())) |
|
|
|
a = get_info(model_files.get('pth')) |
|
file_to_upload = open(zipfile, "rb") |
|
info = a.get("info", "None"), |
|
sr = a.get("sr", "None"), |
|
f0 = a.get("f0", "None"), |
|
|
|
data = { |
|
"name": name, |
|
"version": version, |
|
"creator": creator, |
|
"hash": md5_hash, |
|
"info": info, |
|
"sr": sr, |
|
"f0": f0 |
|
} |
|
print("Subiendo archivo...") |
|
|
|
response = requests.post(api_url, files={"file": file_to_upload}, data=data) |
|
result = response.json() |
|
|
|
|
|
if response.status_code == 200: |
|
result = response.json() |
|
return json.dumps(result, indent=4) |
|
else: |
|
print("Error al cargar el archivo:", response.status_code) |
|
return result |
|
|
|
|
|
def search_model(name): |
|
web_service_url = "https://script.google.com/macros/s/AKfycbyRaNxtcuN8CxUrcA_nHW6Sq9G2QJor8Z2-BJUGnQ2F_CB8klF4kQL--U2r2MhLFZ5J/exec" |
|
response = requests.post(web_service_url, json={ |
|
'type': 'search_by_filename', |
|
'name': name |
|
}) |
|
result = [] |
|
response.raise_for_status() |
|
json_response = response.json() |
|
cont = 0 |
|
result.append("""| Nombre del modelo | Url | Epoch | Sample Rate | |
|
| ---------------- | -------------- |:------:|:-----------:| |
|
""") |
|
yield "<br />".join(result) |
|
if json_response.get('ok', None): |
|
for model in json_response['ocurrences']: |
|
if cont < 20: |
|
model_name = str(model.get('name', 'N/A')).strip() |
|
model_url = model.get('url', 'N/A') |
|
epoch = model.get('epoch', 'N/A') |
|
sr = model.get('sr', 'N/A') |
|
line = f"""|{model_name}|<a>{model_url}</a>|{epoch}|{sr}| |
|
""" |
|
result.append(line) |
|
yield "".join(result) |
|
cont += 1 |
|
|
|
def update_tts_methods_voice(select_value): |
|
if select_value == "Edge-tts": |
|
return gr.Dropdown.update(choices=EDGE_VOICES, visible=True), gr.Markdown.update(visible=False), gr.Textbox.update(visible=False),gr.Radio.update(visible=False) |
|
elif select_value == "Bark-tts": |
|
return gr.update(choices=BARK_VOICES), gr.Markdown.update(visible=False), gr.Textbox.update(visible=False),gr.Radio.update(visible=False) |
|
elif select_value == 'ElevenLabs': |
|
return gr.update(choices=ELEVENLABS_VOICES_NAMES), gr.Markdown.update(visible=True), gr.Textbox.update(visible=True), gr.Radio.update(visible=False) |
|
elif select_value == 'CoquiTTS': |
|
return gr.Dropdown(visible=False), gr.Markdown.update(visible=True), gr.Textbox.update(visible=False), gr.Radio.update(visible=True) |
|
|
|
with gr.Blocks() as app: |
|
gr.HTML("<h1> Simple RVC Inference - by Juuxn 💻 </h1>") |
|
|
|
with gr.Tab("Inferencia"): |
|
model_url = gr.Textbox(placeholder="https://huggingface.co/AIVER-SE/BillieEilish/resolve/main/BillieEilish.zip", label="Url del modelo", show_label=True) |
|
audio_path = gr.Audio(label="Archivo de audio", show_label=True, type="filepath", ) |
|
f0_method = gr.Dropdown(choices=["harvest", "pm", "crepe", "crepe-tiny", "mangio-crepe", "mangio-crepe-tiny", "rmvpe"], |
|
value="rmvpe", |
|
label="Algoritmo", show_label=True) |
|
|
|
with gr.Row(): |
|
vc_output1 = gr.Textbox(label="Salida") |
|
vc_output2 = gr.Audio(label="Audio de salida") |
|
|
|
btn = gr.Button(value="Convertir") |
|
btn.click(infer, inputs=[model_url, f0_method, audio_path], outputs=[vc_output1, vc_output2]) |
|
|
|
with gr.TabItem("TTS"): |
|
with gr.Row(): |
|
tts_text = gr.Textbox( |
|
label="Texto:", |
|
placeholder="Texto que deseas convertir a voz...", |
|
lines=6, |
|
) |
|
|
|
with gr.Column(): |
|
with gr.Row(): |
|
tts_model_url = gr.Textbox(placeholder="https://huggingface.co/AIVER-SE/BillieEilish/resolve/main/BillieEilish.zip", label="Url del modelo RVC", show_label=True) |
|
|
|
with gr.Row(): |
|
tts_method = gr.Dropdown(choices=VOICE_METHODS, value="Edge-tts", label="Método TTS:", visible=True) |
|
tts_model = gr.Dropdown(choices=ELEVENLABS_VOICES_NAMES, label="Modelo TTS:", visible=True, interactive=True) |
|
tts_api_key = gr.Textbox(label="ElevenLabs Api key", show_label=True, placeholder="4a4afce72349680c8e8b6fdcfaf2b65a",interactive=True, visible=False) |
|
|
|
tts_coqui_languages = gr.Radio( |
|
label="Language", |
|
choices=COQUI_LANGUAGES, |
|
value="en", |
|
visible=False |
|
) |
|
|
|
tts_btn = gr.Button(value="Convertir") |
|
|
|
with gr.Row(): |
|
tts_vc_output1 = gr.Textbox(label="Salida") |
|
tts_vc_output2 = gr.Audio(label="Audio de salida") |
|
|
|
tts_btn.click(fn=tts_infer, inputs=[tts_text, tts_model_url, tts_method, tts_model, tts_api_key, tts_coqui_languages], outputs=[tts_vc_output1, tts_vc_output2]) |
|
|
|
tts_msg = gr.Markdown("""**Recomiendo que te crees una cuenta de eleven labs y pongas tu clave de api, es gratis y tienes 10k caracteres de limite al mes.** <br/> |
|
![Imgur](https://imgur.com/HH6YTu0.png) |
|
""", visible=False) |
|
|
|
tts_method.change(fn=update_tts_methods_voice, inputs=[tts_method], outputs=[tts_model, tts_msg, tts_api_key, tts_coqui_languages]) |
|
|
|
with gr.Tab("Modelos"): |
|
gr.HTML("<h4>Buscar modelos</h4>") |
|
search_name = gr.Textbox(placeholder="Billie Eillish (RVC v2 - 100 epoch)", label="Nombre", show_label=True) |
|
|
|
with gr.Row(): |
|
sarch_output = gr.Markdown(label="Salida") |
|
|
|
btn_search_model = gr.Button(value="Buscar") |
|
btn_search_model.click(fn=search_model, inputs=[search_name], outputs=[sarch_output]) |
|
|
|
gr.HTML("<h4>Publica tu modelo</h4>") |
|
post_name = gr.Textbox(placeholder="Billie Eillish (RVC v2 - 100 epoch)", label="Nombre", show_label=True) |
|
post_model_url = gr.Textbox(placeholder="https://huggingface.co/AIVER-SE/BillieEilish/resolve/main/BillieEilish.zip", label="Url del modelo", show_label=True) |
|
post_creator = gr.Textbox(placeholder="ID de discord o enlace al perfil del creador", label="Creador", show_label=True) |
|
post_version = gr.Dropdown(choices=["RVC v1", "RVC v2"], value="RVC v1", label="Versión", show_label=True) |
|
|
|
|
|
with gr.Row(): |
|
post_output = gr.Markdown(label="Salida") |
|
|
|
btn_post_model = gr.Button(value="Publicar") |
|
btn_post_model.click(fn=post_model, inputs=[post_name, post_model_url, post_version, post_creator], outputs=[post_output]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.queue(concurrency_count=511, max_size=1022).launch() |
|
|