Rvcmodelonxon / app.py
Woogiepark's picture
Create app.py
3a0d15e verified
import time
import gradio as gr
# --- Custom CSS to mimic your original look ---
custom_css = """
:root {
--primary: #6366f1;
--primary-dark: #4f46e5;
--secondary: #10b981;
--dark: #1e293b;
--light: #f8fafc;
--gray: #94a3b8;
--danger: #ef4444;
}
body {
background: linear-gradient(135deg, #0f172a, #1e293b) !important;
color: var(--light) !important;
}
.gradio-container {
max-width: 1200px !important;
margin: 0 auto !important;
padding: 20px !important;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
h1, h2, h3 {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
.rvc-card {
background: rgba(30, 41, 59, 0.7);
backdrop-filter: blur(10px);
border-radius: 16px;
padding: 30px;
margin-bottom: 30px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.rvc-title {
font-size: 2.5rem;
margin-bottom: 10px;
background: linear-gradient(to right, #8b5cf6, #06b6d4);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
text-align: center;
}
.rvc-subtitle {
font-size: 1.2rem;
color: var(--gray);
max-width: 600px;
margin: 0 auto;
text-align: center;
}
.rvc-card-title {
font-size: 1.5rem;
margin-bottom: 20px;
color: #8b5cf6;
display: flex;
align-items: center;
gap: 10px;
}
.rvc-status {
padding: 15px;
border-radius: 8px;
margin-top: 20px;
text-align: center;
font-weight: 500;
}
.rvc-status-processing {
background: rgba(59, 130, 246, 0.2);
color: #3b82f6;
}
.rvc-status-success {
background: rgba(16, 185, 129, 0.2);
color: var(--secondary);
}
.rvc-status-error {
background: rgba(239, 68, 68, 0.2);
color: var(--danger);
}
/* Fake progress bar */
.rvc-progress-container {
height: 8px;
background: rgba(15, 23, 42, 0.5);
border-radius: 4px;
overflow: hidden;
margin: 20px 0;
}
.rvc-progress-bar {
height: 100%;
background: linear-gradient(to right, var(--primary), var(--secondary));
width: 0%;
transition: width 0.2s ease;
}
/* Make Gradio buttons vaguely match your buttons */
button, .gr-button {
font-weight: 600 !important;
border-radius: 8px !important;
}
/* Smaller screens tweaks */
@media (max-width: 768px) {
.rvc-card {
padding: 20px;
}
.rvc-title {
font-size: 2rem;
}
}
"""
# --- Backend logic (simulated) ---
def train_model(files, model_name, voice_type, quality, epochs, trained, progress=gr.Progress(track_tqdm=True)):
"""Simulate model training."""
if not files:
# No files โ†’ error
status_html = (
'<div class="rvc-status rvc-status-error">'
"Please upload at least one audio file."
"</div>"
)
# progress_html with 0%
progress_html = (
'<div class="rvc-progress-container">'
'<div class="rvc-progress-bar" style="width:0%"></div>'
"</div>"
)
return status_html, False, progress_html
model_name = model_name or "MySingingVoice"
steps = 20
# Simulate training loop
for i in progress.tqdm(range(steps), desc=f'Training "{model_name}"'):
time.sleep(0.15)
status_html = (
'<div class="rvc-status rvc-status-success">'
f'Model "{model_name}" trained successfully!'
"</div>"
)
progress_html = (
'<div class="rvc-progress-container">'
'<div class="rvc-progress-bar" style="width:100%"></div>'
"</div>"
)
return status_html, True, progress_html
def preview_model(trained, model_name):
"""Simulate generating a preview."""
model_name = model_name or "MySingingVoice"
if not trained:
return (
'<div class="rvc-status rvc-status-error">'
"Please train a model first."
"</div>"
)
# Fake delay for โ€œpreview generationโ€
time.sleep(1.0)
return (
'<div class="rvc-status rvc-status-success">'
f'Preview generated successfully for "{model_name}"! '
"Imagine your custom voice playing here ๐ŸŽต"
"</div>"
)
def export_model(trained, what):
"""Simulate export of model / sample / info."""
if not trained:
return (
'<div class="rvc-status rvc-status-error">'
"Please train a model before exporting."
"</div>"
)
time.sleep(0.8)
return (
'<div class="rvc-status rvc-status-success">'
f'{what} exported successfully! (Demo only โ€“ no real file generated)'
"</div>"
)
def reset_app():
"""Reset everything to defaults."""
status_html = ""
trained = False
model_name = "MySingingVoice"
voice_type = "soprano"
quality = "high"
epochs = 300
files = None
progress_html = (
'<div class="rvc-progress-container">'
'<div class="rvc-progress-bar" style="width:0%"></div>'
"</div>"
)
return status_html, trained, model_name, voice_type, quality, epochs, files, progress_html
# --- Gradio UI ---
with gr.Blocks(css=custom_css, title="RVC Voice Model Creator") as demo:
# Header
gr.HTML(
"""
<h1 class="rvc-title">RVC Voice Model Creator</h1>
<p class="rvc-subtitle">
Upload your audio files to create custom singing voice models for AI voice conversion.
</p>
"""
)
trained_state = gr.State(False)
# --- Upload Card ---
with gr.Group(elem_classes="rvc-card"):
gr.HTML('<h2 class="rvc-card-title">๐Ÿ“ Upload Audio Files</h2>')
files = gr.File(
label="Drag & drop your audio files here or click to browse",
file_types=["audio"],
file_count="multiple",
)
# --- Settings + Training Card ---
with gr.Group(elem_classes="rvc-card"):
gr.HTML('<h2 class="rvc-card-title">โš™๏ธ Model Settings</h2>')
with gr.Row():
with gr.Column():
model_name = gr.Textbox(
label="Model Name",
value="MySingingVoice",
placeholder="Enter your model name",
)
voice_type = gr.Dropdown(
label="Voice Type",
choices=[
"soprano",
"alto",
"tenor",
"bass",
"custom",
],
value="soprano",
)
with gr.Column():
quality = gr.Dropdown(
label="Quality Level",
choices=["high", "medium", "low"],
value="high",
)
epochs = gr.Slider(
label="Training Epochs",
minimum=50,
maximum=1000,
step=10,
value=300,
)
progress_html = gr.HTML(
value=(
'<div class="rvc-progress-container">'
'<div class="rvc-progress-bar" style="width:0%"></div>'
"</div>"
)
)
status_html = gr.HTML(value="")
with gr.Row():
train_btn = gr.Button("๐Ÿš€ Train Model", variant="primary")
preview_btn = gr.Button("๐Ÿ‘๏ธ Preview Model", variant="secondary")
reset_btn = gr.Button("๐Ÿ—‘๏ธ Reset All", variant="stop")
# --- Export Card ---
with gr.Group(elem_classes="rvc-card"):
gr.HTML('<h2 class="rvc-card-title">๐Ÿ“ฅ Export Model</h2>')
with gr.Row():
with gr.Column():
gr.Markdown("**RVC Model** \n.pth weight file for voice conversion")
export_rvc_btn = gr.Button("Download RVC")
with gr.Column():
gr.Markdown("**Sample Audio** \nConverted sample with your voice")
export_sample_btn = gr.Button("Download Sample")
with gr.Column():
gr.Markdown("**Model Info** \nConfiguration and training details")
export_info_btn = gr.Button("Download Info")
# Footer note
gr.Markdown(
"> RVC Voice Model Creator | Create custom singing voices for AI applications \n"
"> **Note:** This Space is a frontend/demo. Real RVC training needs a proper backend pipeline."
)
# --- Wiring logic ---
# Train button
train_btn.click(
fn=train_model,
inputs=[files, model_name, voice_type, quality, epochs, trained_state],
outputs=[status_html, trained_state, progress_html],
)
# Preview button
preview_btn.click(
fn=preview_model,
inputs=[trained_state, model_name],
outputs=status_html,
)
# Export buttons
export_rvc_btn.click(
fn=export_model,
inputs=[trained_state, gr.State("RVC model (.pth)")],
outputs=status_html,
)
export_sample_btn.click(
fn=export_model,
inputs=[trained_state, gr.State("Sample audio")],
outputs=status_html,
)
export_info_btn.click(
fn=export_model,
inputs=[trained_state, gr.State("Model info")],
outputs=status_html,
)
# Reset button
reset_btn.click(
fn=reset_app,
inputs=None,
outputs=[
status_html,
trained_state,
model_name,
voice_type,
quality,
epochs,
files,
progress_html,
],
)
if __name__ == "__main__":
demo.launch()