Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,18 +1,17 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
from gradio_client import Client, handle_file
|
| 3 |
from transformers import pipeline
|
| 4 |
-
from moviepy import ImageClip, AudioFileClip
|
| 5 |
import os
|
| 6 |
|
| 7 |
-
# --- INITIALIZE
|
| 8 |
-
#
|
| 9 |
-
classifier = pipeline("audio-classification", model="
|
| 10 |
-
|
| 11 |
mastering_client = Client("amaai-lab/SonicMaster")
|
| 12 |
-
# The Artwork Engine
|
| 13 |
image_client = Client("stabilityai/stable-diffusion-xl-base-1.0")
|
| 14 |
|
| 15 |
-
# --- LOGIC FUNCTIONS ---
|
| 16 |
|
| 17 |
def master_logic(audio_path):
|
| 18 |
if not audio_path: return None, None, "Upload a track!", None
|
|
@@ -22,10 +21,9 @@ def master_logic(audio_path):
|
|
| 22 |
genre = results[0]['label']
|
| 23 |
|
| 24 |
# 2. AI Mastering
|
| 25 |
-
# We send the audio + a smart prompt based on the genre
|
| 26 |
result = mastering_client.predict(
|
| 27 |
audio=handle_file(audio_path),
|
| 28 |
-
prompt=f"Professional {genre} studio master
|
| 29 |
api_name="/predict"
|
| 30 |
)
|
| 31 |
mastered_path = result[1]
|
|
@@ -33,17 +31,16 @@ def master_logic(audio_path):
|
|
| 33 |
return mastered_path, mastered_path, f"Genre: {genre} | Mastered β¨", mastered_path
|
| 34 |
|
| 35 |
def art_logic(genre_text, vibe):
|
| 36 |
-
|
|
|
|
|
|
|
| 37 |
return image_client.predict(prompt=prompt, api_name="/predict")
|
| 38 |
|
| 39 |
def video_logic(audio_path, image_path):
|
| 40 |
if not audio_path or not image_path: return None
|
| 41 |
-
|
| 42 |
-
# MoviePy v2.x Syntax: Use 'with_' and 'subclipped'
|
| 43 |
audio = AudioFileClip(audio_path).subclipped(0, 30)
|
| 44 |
img = ImageClip(image_path).with_duration(audio.duration).resized(width=1080)
|
| 45 |
-
|
| 46 |
-
# Create 9:16 video for TikTok
|
| 47 |
video = img.on_color(size=(1080, 1920), color=(15, 15, 15), pos="center")
|
| 48 |
video = video.with_audio(audio)
|
| 49 |
|
|
@@ -51,60 +48,37 @@ def video_logic(audio_path, image_path):
|
|
| 51 |
video.write_videofile(out_path, fps=24, codec="libx264")
|
| 52 |
return out_path
|
| 53 |
|
| 54 |
-
# ---
|
| 55 |
-
|
| 56 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 57 |
-
gr.Markdown("#
|
| 58 |
|
| 59 |
-
#
|
| 60 |
raw_storage = gr.State()
|
| 61 |
master_storage = gr.State()
|
| 62 |
genre_name = gr.State()
|
| 63 |
|
| 64 |
with gr.Tabs():
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
ab_toggle = gr.Radio(["Original π", "Mastered β¨"], value="Mastered β¨", label="A/B Comparison")
|
| 72 |
-
|
| 73 |
-
master_btn = gr.Button("π MASTER TRACK", variant="primary")
|
| 74 |
-
status = gr.Markdown("Ready to process...")
|
| 75 |
-
download_wav = gr.File(label="Download Master (.wav)")
|
| 76 |
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
art_output = gr.Image(label="Your Artwork")
|
| 82 |
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
promo_video = gr.Video(label="9:16 Promo Video")
|
| 87 |
|
| 88 |
-
#
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
master_btn.click(
|
| 92 |
-
master_logic, in_audio, [out_audio, download_wav, status, master_storage]
|
| 93 |
-
).then(lambda x: x, in_audio, raw_storage).then(
|
| 94 |
-
# Extract genre name from status string for the next steps
|
| 95 |
-
lambda x: x.split(":")[1].split("|")[0].strip(), status, genre_name
|
| 96 |
)
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
ab_toggle.change(
|
| 100 |
-
lambda choice, raw, mastered: mastered if "Mastered" in choice else raw,
|
| 101 |
-
[ab_toggle, raw_storage, master_storage], out_audio
|
| 102 |
-
)
|
| 103 |
-
|
| 104 |
-
# Art Click
|
| 105 |
-
art_btn.click(art_logic, [genre_name, vibe_input], art_output)
|
| 106 |
-
|
| 107 |
-
# Video Click
|
| 108 |
-
promo_btn.click(video_logic, [master_storage, art_output], promo_video)
|
| 109 |
|
| 110 |
demo.launch()
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
from gradio_client import Client, handle_file
|
| 3 |
from transformers import pipeline
|
| 4 |
+
from moviepy import ImageClip, AudioFileClip
|
| 5 |
import os
|
| 6 |
|
| 7 |
+
# --- 1. INITIALIZE ENGINES ---
|
| 8 |
+
# CORRECTED: Using a dedicated music genre classifier to avoid 401 errors
|
| 9 |
+
classifier = pipeline("audio-classification", model="dima806/music_genres_classification")
|
| 10 |
+
|
| 11 |
mastering_client = Client("amaai-lab/SonicMaster")
|
|
|
|
| 12 |
image_client = Client("stabilityai/stable-diffusion-xl-base-1.0")
|
| 13 |
|
| 14 |
+
# --- 2. LOGIC FUNCTIONS ---
|
| 15 |
|
| 16 |
def master_logic(audio_path):
|
| 17 |
if not audio_path: return None, None, "Upload a track!", None
|
|
|
|
| 21 |
genre = results[0]['label']
|
| 22 |
|
| 23 |
# 2. AI Mastering
|
|
|
|
| 24 |
result = mastering_client.predict(
|
| 25 |
audio=handle_file(audio_path),
|
| 26 |
+
prompt=f"Professional {genre} studio master.",
|
| 27 |
api_name="/predict"
|
| 28 |
)
|
| 29 |
mastered_path = result[1]
|
|
|
|
| 31 |
return mastered_path, mastered_path, f"Genre: {genre} | Mastered β¨", mastered_path
|
| 32 |
|
| 33 |
def art_logic(genre_text, vibe):
|
| 34 |
+
# If genre is still a full status string, clean it
|
| 35 |
+
clean_genre = str(genre_text).split("|")[0].replace("Genre:", "").strip()
|
| 36 |
+
prompt = f"Professional album cover art, {clean_genre} style, {vibe}, 4k, no text."
|
| 37 |
return image_client.predict(prompt=prompt, api_name="/predict")
|
| 38 |
|
| 39 |
def video_logic(audio_path, image_path):
|
| 40 |
if not audio_path or not image_path: return None
|
| 41 |
+
# MoviePy v2.x Syntax
|
|
|
|
| 42 |
audio = AudioFileClip(audio_path).subclipped(0, 30)
|
| 43 |
img = ImageClip(image_path).with_duration(audio.duration).resized(width=1080)
|
|
|
|
|
|
|
| 44 |
video = img.on_color(size=(1080, 1920), color=(15, 15, 15), pos="center")
|
| 45 |
video = video.with_audio(audio)
|
| 46 |
|
|
|
|
| 48 |
video.write_videofile(out_path, fps=24, codec="libx264")
|
| 49 |
return out_path
|
| 50 |
|
| 51 |
+
# --- 3. UI LAYOUT ---
|
|
|
|
| 52 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 53 |
+
gr.Markdown("# π΅ AI Artist Suite")
|
| 54 |
|
| 55 |
+
# States
|
| 56 |
raw_storage = gr.State()
|
| 57 |
master_storage = gr.State()
|
| 58 |
genre_name = gr.State()
|
| 59 |
|
| 60 |
with gr.Tabs():
|
| 61 |
+
with gr.TabItem("π§ Mastering"):
|
| 62 |
+
in_audio = gr.Audio(label="Raw Track", type="filepath")
|
| 63 |
+
master_btn = gr.Button("π MASTER")
|
| 64 |
+
out_audio = gr.Audio(label="Output")
|
| 65 |
+
status = gr.Markdown()
|
| 66 |
+
export_file = gr.File(label="Download WAV")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
+
with gr.TabItem("π¨ Art"):
|
| 69 |
+
vibe_in = gr.Textbox(label="Visual Vibe")
|
| 70 |
+
art_btn = gr.Button("π¨ GENERATE ART")
|
| 71 |
+
art_out = gr.Image()
|
|
|
|
| 72 |
|
| 73 |
+
with gr.TabItem("π± Promo"):
|
| 74 |
+
promo_btn = gr.Button("π¬ CREATE VIDEO")
|
| 75 |
+
video_out = gr.Video()
|
|
|
|
| 76 |
|
| 77 |
+
# Wiring
|
| 78 |
+
master_btn.click(master_logic, in_audio, [out_audio, export_file, status, master_storage]).then(
|
| 79 |
+
lambda x: x, in_audio, raw_storage
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
)
|
| 81 |
+
art_btn.click(art_logic, [status, vibe_in], art_out)
|
| 82 |
+
promo_btn.click(video_logic, [master_storage, art_out], video_out)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
demo.launch()
|