Spaces:
Running
Running
Phoenixak99
commited on
Commit
•
3440d36
1
Parent(s):
2b9fbf5
Update app.py
Browse files
app.py
CHANGED
@@ -1,41 +1,21 @@
|
|
1 |
-
import io
|
2 |
-
import json
|
3 |
import os
|
4 |
-
import time
|
5 |
-
import uuid
|
6 |
-
from datetime import datetime
|
7 |
-
from io import BytesIO
|
8 |
-
from tempfile import NamedTemporaryFile
|
9 |
-
|
10 |
import numpy as np
|
11 |
import requests
|
12 |
-
import scipy
|
13 |
import soundfile as sf
|
14 |
import streamlit as st
|
15 |
-
import
|
|
|
|
|
|
|
|
|
|
|
16 |
from pydub import AudioSegment
|
17 |
-
from scipy.signal import butter, sosfilt
|
18 |
from streamlit import session_state as st_state
|
19 |
-
from woocommerce import API
|
20 |
from wordpress_xmlrpc import Client
|
21 |
from wordpress_xmlrpc.compat import xmlrpc_client
|
22 |
from wordpress_xmlrpc.methods import media
|
23 |
|
24 |
-
#
|
25 |
-
try:
|
26 |
-
API_URL = os.environ["API_URL"]
|
27 |
-
except KeyError:
|
28 |
-
st.error("API_URL environment variable is not set.")
|
29 |
-
st.stop()
|
30 |
-
|
31 |
-
# Try to get the Bearer token from environment variables
|
32 |
-
try:
|
33 |
-
BEARER_TOKEN = os.environ["BEARER_TOKEN"]
|
34 |
-
except KeyError:
|
35 |
-
st.error("BEARER_TOKEN environment variable is not set.")
|
36 |
-
st.stop()
|
37 |
-
|
38 |
-
# Set the background image for the app
|
39 |
page_bg_img = '''
|
40 |
<style>
|
41 |
.stApp {
|
@@ -46,32 +26,33 @@ background-size: cover;
|
|
46 |
'''
|
47 |
st.markdown(page_bg_img, unsafe_allow_html=True)
|
48 |
|
|
|
|
|
|
|
49 |
|
50 |
-
#
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
# Save generated audio to WordPress and WooCommerce
|
75 |
def save_to_wordpress(channel1, channel2, sample_rate):
|
76 |
channel1 = np.array(channel1).astype(np.float32)
|
77 |
channel2 = np.array(channel2).astype(np.float32)
|
@@ -89,7 +70,7 @@ def save_to_wordpress(channel1, channel2, sample_rate):
|
|
89 |
title = f"generated_audio_{datetime.now().timestamp()}.wav"
|
90 |
file_data = {
|
91 |
"name": title,
|
92 |
-
"type": "audio/x-wav",
|
93 |
"bits": xmlrpc_client.Binary(wav_bytes.getvalue()),
|
94 |
}
|
95 |
|
@@ -99,6 +80,7 @@ def save_to_wordpress(channel1, channel2, sample_rate):
|
|
99 |
if media_response:
|
100 |
print("File uploaded to WordPress with attachment ID:", media_response)
|
101 |
|
|
|
102 |
product_data = {
|
103 |
"status": "pending",
|
104 |
"name": title,
|
@@ -118,7 +100,6 @@ def save_to_wordpress(channel1, channel2, sample_rate):
|
|
118 |
)
|
119 |
|
120 |
response = wc_api.post("products", product_data)
|
121 |
-
|
122 |
if response.status_code == 201:
|
123 |
product_id = response.json().get("id")
|
124 |
product_update_data = {
|
@@ -130,9 +111,7 @@ def save_to_wordpress(channel1, channel2, sample_rate):
|
|
130 |
]
|
131 |
}
|
132 |
response = wc_api.put(f"products/{product_id}", product_update_data)
|
133 |
-
|
134 |
if response.status_code == 200:
|
135 |
-
print("Downloadable file URL added to product:", response.json())
|
136 |
return response.json()["permalink"], response.json()["permalink"].split("p=")[-1]
|
137 |
else:
|
138 |
print("Error adding downloadable file URL:", response.text)
|
@@ -143,81 +122,10 @@ def save_to_wordpress(channel1, channel2, sample_rate):
|
|
143 |
except Exception as e:
|
144 |
print("Error:", e)
|
145 |
|
|
|
|
|
146 |
|
147 |
-
|
148 |
-
def time_post_request(api_url, headers=None, payload=None):
|
149 |
-
start_time = time.time()
|
150 |
-
response = requests.post(api_url, headers=headers, json=payload)
|
151 |
-
end_time = time.time()
|
152 |
-
|
153 |
-
print(f"Execution time: {end_time - start_time} seconds")
|
154 |
-
return response
|
155 |
-
|
156 |
-
|
157 |
-
# Function to generate audio from the API
|
158 |
-
def generate_audio(genre, energy_level, tempo, description, duration):
|
159 |
-
prompt = f"Genre: {genre}, Energy Level: {energy_level}, Tempo: {tempo}, Description: {description},"
|
160 |
-
payload = {"inputs": {"prompt": prompt, "duration": duration}}
|
161 |
-
|
162 |
-
print("Payload being sent to the API:", json.dumps(payload, indent=4)) # Debugging payload structure
|
163 |
-
|
164 |
-
response = time_post_request(API_URL, headers, payload)
|
165 |
-
|
166 |
-
if response.status_code != 200:
|
167 |
-
print(f"Error response: {response.status_code} - {response.text}")
|
168 |
-
st.error(f"Error generating audio: {response.text}")
|
169 |
-
else:
|
170 |
-
load_and_play_generated_audio(response)
|
171 |
-
|
172 |
-
|
173 |
-
# Function to load and play generated audio
|
174 |
-
def load_and_play_generated_audio(response):
|
175 |
-
try:
|
176 |
-
response_eval = json.loads(response.content)
|
177 |
-
|
178 |
-
if not response_eval or not isinstance(response_eval, list) or "generated_audio" not in response_eval[0]:
|
179 |
-
raise ValueError("Invalid response format")
|
180 |
-
|
181 |
-
channel1 = response_eval[0]["generated_audio"][0]
|
182 |
-
channel2 = response_eval[0]["generated_audio"][1]
|
183 |
-
sample_rate = response_eval[0].get("sample_rate", 32000) # Default to 32000 if not provided
|
184 |
-
|
185 |
-
with NamedTemporaryFile() as f1:
|
186 |
-
scipy.io.wavfile.write(f1.name, rate=sample_rate, data=np.array(channel1).astype(np.float32))
|
187 |
-
channel1_temp = AudioSegment.from_file(f1.name)
|
188 |
-
|
189 |
-
with NamedTemporaryFile() as f2:
|
190 |
-
scipy.io.wavfile.write(f2.name, rate=sample_rate, data=np.array(channel2).astype(np.float32))
|
191 |
-
channel2_temp = AudioSegment.from_file(f2.name)
|
192 |
-
|
193 |
-
audio_pydub = AudioSegment.from_mono_audiosegments(channel1_temp, channel2_temp)
|
194 |
-
st_state.audio_pydub = audio_pydub
|
195 |
-
st_state.audio_pydub_sample_rate = audio_pydub.frame_rate
|
196 |
-
|
197 |
-
st.audio(st_state.audio_pydub.export().read())
|
198 |
-
|
199 |
-
# Save audio to WordPress and WooCommerce
|
200 |
-
perm_link, product_code = save_to_wordpress(channel1, channel2, 32000)
|
201 |
-
st.write(f"To publish, contact the admin with this link: {perm_link}")
|
202 |
-
st.write(f"Download product code: {product_code}")
|
203 |
-
|
204 |
-
except Exception as e:
|
205 |
-
st.error(f"Error processing audio: {e}")
|
206 |
-
print(f"Error loading audio: {e}")
|
207 |
-
|
208 |
-
|
209 |
-
# Streamlit app UI
|
210 |
-
st.title("Songlab AI")
|
211 |
-
|
212 |
-
# Initialize session state variables
|
213 |
-
if "audio_pydub" not in st_state:
|
214 |
-
st_state.audio_pydub = None
|
215 |
-
|
216 |
-
genres = [
|
217 |
-
"Pop", "Rock", "Hip Hop", "Jazz", "Blues", "Country", "Classical",
|
218 |
-
"Electronic", "Reggae", "Folk", "R&B", "Metal", "Punk", "Indie",
|
219 |
-
"Dance", "World", "Gospel", "Soul", "Funk", "Ambient", "Techno", "Disco", "House", "Trance", "Dubstep",
|
220 |
-
]
|
221 |
genre = st.selectbox("Select Genre:", genres)
|
222 |
energy_levels = ["Low", "Medium", "High"]
|
223 |
energy_level = st.radio("Energy Level:", energy_levels, horizontal=True)
|
@@ -225,8 +133,23 @@ description = st.text_input("Description:", "")
|
|
225 |
tempo = st.slider("Tempo (in bpm):", min_value=40, max_value=100, value=60, step=5)
|
226 |
duration = st.slider("Duration (in seconds):", min_value=15, max_value=300, value=30, step=1)
|
227 |
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
st.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import numpy as np
|
3 |
import requests
|
|
|
4 |
import soundfile as sf
|
5 |
import streamlit as st
|
6 |
+
import torchaudio
|
7 |
+
from io import BytesIO
|
8 |
+
from tempfile import NamedTemporaryFile
|
9 |
+
from scipy.io.wavfile import write
|
10 |
+
import gradio as gr
|
11 |
+
from transformers import AutoProcessor, MusicgenForConditionalGeneration
|
12 |
from pydub import AudioSegment
|
|
|
13 |
from streamlit import session_state as st_state
|
|
|
14 |
from wordpress_xmlrpc import Client
|
15 |
from wordpress_xmlrpc.compat import xmlrpc_client
|
16 |
from wordpress_xmlrpc.methods import media
|
17 |
|
18 |
+
# Background image for the Streamlit app
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
page_bg_img = '''
|
20 |
<style>
|
21 |
.stApp {
|
|
|
26 |
'''
|
27 |
st.markdown(page_bg_img, unsafe_allow_html=True)
|
28 |
|
29 |
+
# Initialize session state variables for audio processing
|
30 |
+
if "audio_pydub" not in st_state:
|
31 |
+
st_state.audio_pydub = None
|
32 |
|
33 |
+
# Load the MusicGen model and processor
|
34 |
+
processor = AutoProcessor.from_pretrained("facebook/musicgen-melody")
|
35 |
+
model = MusicgenForConditionalGeneration.from_pretrained("facebook/musicgen-melody")
|
36 |
+
|
37 |
+
# Function to generate music using the MusicGen model
|
38 |
+
def generate_music(prompt, melody_file=None):
|
39 |
+
inputs = processor(text=[prompt], padding=True, return_tensors="pt")
|
40 |
+
|
41 |
+
if melody_file is not None:
|
42 |
+
melody, sr = torchaudio.load(melody_file.name)
|
43 |
+
melody = melody[None].expand(1, -1, -1) # expand melody for batch size 1
|
44 |
+
output = model.generate_with_chroma([prompt], melody, sr)
|
45 |
+
else:
|
46 |
+
output = model.generate(**inputs, max_new_tokens=256)
|
47 |
+
|
48 |
+
# Convert output to wav file format
|
49 |
+
audio_data = output[0, 0].detach().numpy()
|
50 |
+
sampling_rate = model.config.audio_encoder.sampling_rate
|
51 |
+
wav_file = NamedTemporaryFile(delete=False, suffix=".wav")
|
52 |
+
write(wav_file.name, rate=sampling_rate, data=np.int16(audio_data * 32767))
|
53 |
+
return wav_file.name
|
54 |
+
|
55 |
+
# Function to handle audio upload to WordPress
|
|
|
|
|
56 |
def save_to_wordpress(channel1, channel2, sample_rate):
|
57 |
channel1 = np.array(channel1).astype(np.float32)
|
58 |
channel2 = np.array(channel2).astype(np.float32)
|
|
|
70 |
title = f"generated_audio_{datetime.now().timestamp()}.wav"
|
71 |
file_data = {
|
72 |
"name": title,
|
73 |
+
"type": "audio/x-wav",
|
74 |
"bits": xmlrpc_client.Binary(wav_bytes.getvalue()),
|
75 |
}
|
76 |
|
|
|
80 |
if media_response:
|
81 |
print("File uploaded to WordPress with attachment ID:", media_response)
|
82 |
|
83 |
+
# Prepare WooCommerce product
|
84 |
product_data = {
|
85 |
"status": "pending",
|
86 |
"name": title,
|
|
|
100 |
)
|
101 |
|
102 |
response = wc_api.post("products", product_data)
|
|
|
103 |
if response.status_code == 201:
|
104 |
product_id = response.json().get("id")
|
105 |
product_update_data = {
|
|
|
111 |
]
|
112 |
}
|
113 |
response = wc_api.put(f"products/{product_id}", product_update_data)
|
|
|
114 |
if response.status_code == 200:
|
|
|
115 |
return response.json()["permalink"], response.json()["permalink"].split("p=")[-1]
|
116 |
else:
|
117 |
print("Error adding downloadable file URL:", response.text)
|
|
|
122 |
except Exception as e:
|
123 |
print("Error:", e)
|
124 |
|
125 |
+
# Streamlit UI for music generation
|
126 |
+
st.title("Songlab AI Music Generator")
|
127 |
|
128 |
+
genres = ["Pop", "Rock", "Hip Hop", "Jazz", "Blues", "Country", "Classical", "Electronic", "Reggae", "Folk"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
genre = st.selectbox("Select Genre:", genres)
|
130 |
energy_levels = ["Low", "Medium", "High"]
|
131 |
energy_level = st.radio("Energy Level:", energy_levels, horizontal=True)
|
|
|
133 |
tempo = st.slider("Tempo (in bpm):", min_value=40, max_value=100, value=60, step=5)
|
134 |
duration = st.slider("Duration (in seconds):", min_value=15, max_value=300, value=30, step=1)
|
135 |
|
136 |
+
# Generate music when the button is clicked
|
137 |
+
if st.button("Generate Music"):
|
138 |
+
if description:
|
139 |
+
melody_file = st.file_uploader("Upload Melody (optional)", type=["wav", "mp3"])
|
140 |
+
with st.spinner("Generating music..."):
|
141 |
+
generated_audio_path = generate_music(description, melody_file)
|
142 |
+
st.audio(generated_audio_path)
|
143 |
+
st.success("Music generated successfully!")
|
144 |
+
|
145 |
+
# Post-processing and upload options
|
146 |
+
if st_state.audio_pydub is not None:
|
147 |
+
st.header("Post-processing Options")
|
148 |
+
|
149 |
+
# Save generated audio to WordPress
|
150 |
+
if st.button("Save to WordPress"):
|
151 |
+
save_to_wordpress(
|
152 |
+
st_state.audio_pydub.get_array_of_samples(),
|
153 |
+
st_state.audio_pydub.get_array_of_samples(),
|
154 |
+
st_state.audio_pydub.frame_rate,
|
155 |
+
)
|