Phoenixak99 commited on
Commit
933315b
·
verified ·
1 Parent(s): 4819e39

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +233 -148
app.py CHANGED
@@ -23,20 +23,15 @@ from wordpress_xmlrpc import Client
23
  from wordpress_xmlrpc.compat import xmlrpc_client
24
  from wordpress_xmlrpc.methods import media
25
 
26
- # API URLs
27
- WP_LOGIN_URL = "https://songlabai.com/login"
28
- CURRENT_USER_ID_API = "https://songlabai.com/wp-json/custom-api/v1/current-user-id-session"
29
- SUBSCRIPTION_API_BASE = "https://songlabai.com/wp-json/custom-api/subscription/"
30
- UPDATE_LIMIT_API_BASE = "https://songlabai.com/wp-json/custom-api/update-limit/"
31
- HUGGING_FACE_API_URL = "https://api-inference.huggingface.co/models/YOUR_MODEL_NAME"
32
-
33
- # Try to get API_URL and BEARER_TOKEN from environment variables, if not found set to a default value
34
  try:
35
  API_URL = os.environ["API_URL"]
36
  except KeyError:
37
  st.error("API_URL environment variable is not set.")
38
  st.stop()
39
 
 
40
  try:
41
  BEARER_TOKEN = os.environ["BEARER_TOKEN"]
42
  except KeyError:
@@ -56,119 +51,13 @@ background-size: cover;
56
  '''
57
  st.markdown(page_bg_img, unsafe_allow_html=True)
58
 
59
- # Function to check if the user is logged in
60
- def check_user_logged_in():
61
- try:
62
- response = requests.get(CURRENT_USER_ID_API)
63
- if response.status_code == 200:
64
- user_data = response.json()
65
- if 'user_id' in user_data and user_data['user_id'] is not None:
66
- return user_data['user_id']
67
- return None
68
- except Exception as e:
69
- st.error(f"Error checking login status: {e}")
70
- return None
71
-
72
- # Function to show the login button with redirection
73
- def show_login_button():
74
- login_html = f'''
75
- <a href="{WP_LOGIN_URL}" target="_self">
76
- <button style="background-color: #4CAF50; color: white; padding: 15px 32px; text-align: center;
77
- text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer;">
78
- Login
79
- </button>
80
- </a>
81
- '''
82
- st.markdown(login_html, unsafe_allow_html=True)
83
-
84
- # Function to check the user's subscription
85
- def check_user_subscription(user_id):
86
- try:
87
- subscription_url = f"{SUBSCRIPTION_API_BASE}{user_id}"
88
- response = requests.get(subscription_url)
89
- if response.status_code == 200:
90
- return response.json() # Return the subscription data
91
- else:
92
- st.error(f"Error fetching subscription data: {response.status_code}")
93
- return None
94
- except Exception as e:
95
- st.error(f"Error checking subscription: {e}")
96
- return None
97
-
98
- # Function to update the user's daily limit after generating music
99
- def update_daily_limit(user_id):
100
- try:
101
- update_url = f"{UPDATE_LIMIT_API_BASE}{user_id}"
102
- response = requests.post(update_url)
103
- if response.status_code == 200:
104
- st.success("Daily limit updated successfully.")
105
- else:
106
- st.error(f"Error updating daily limit: {response.status_code}")
107
- except Exception as e:
108
- st.error(f"Error updating daily limit: {e}")
109
-
110
- # Function to handle generation logic based on the subscription
111
- def handle_generation_logic(subscription_data):
112
- # Check if the user is on the Free plan (ID: 576)
113
- if subscription_data["subscription_plan_id"] == "576":
114
- if subscription_data["has_exceeded_daily_limit"]:
115
- st.error("You have reached your daily generation limit for the Free plan.")
116
- return False
117
- else:
118
- st.success("You can generate music. You haven't hit your daily limit yet.")
119
- return True
120
- else:
121
- # For paid plans, allow unlimited generation
122
- st.success("You are on a paid plan. You can generate unlimited music.")
123
- return True
124
-
125
- # Function to generate music using Hugging Face API
126
- def generate_music_with_hugging_face(prompt, duration=30):
127
- headers = {"Authorization": f"Bearer YOUR_HUGGING_FACE_TOKEN"}
128
- payload = {
129
- "inputs": prompt,
130
- "parameters": {"duration": duration} # Example of sending duration to the API
131
- }
132
-
133
- try:
134
- response = requests.post(HUGGING_FACE_API_URL, headers=headers, json=payload)
135
- if response.status_code == 200:
136
- return response.content # Assuming the response returns audio bytes or a URL
137
- else:
138
- st.error(f"Error generating music: {response.status_code}")
139
- return None
140
- except Exception as e:
141
- st.error(f"Error generating music: {e}")
142
- return None
143
-
144
- # Function to handle the entire music generation process
145
- def generate_music(user_id, genre, energy_level, tempo, description, duration=30):
146
- prompt = f"Genre: {genre}, Energy Level: {energy_level}, Tempo: {tempo}, Description: {description}"
147
-
148
- # Simulate music generation with Hugging Face
149
- st.info(f"Generating music with prompt: {prompt}")
150
-
151
- # Call Hugging Face API to generate music
152
- audio_data = generate_music_with_hugging_face(prompt, duration)
153
-
154
- if audio_data:
155
- st.success("✔️ Music has been generated!")
156
- st.audio(audio_data) # This assumes Hugging Face returns raw audio data
157
-
158
- # If the user is on the free plan, update their daily limit
159
- subscription_data = check_user_subscription(user_id)
160
- if subscription_data and subscription_data["subscription_plan_id"] == "576":
161
- update_daily_limit(user_id)
162
- else:
163
- st.error("Failed to generate music. Please try again.")
164
-
165
- # Function to save generated audio to WordPress and WooCommerce
166
  def save_to_wordpress(channel1, channel2, sample_rate):
167
 
168
  channel1 = np.array(channel1).astype(np.float32)
169
  channel2 = np.array(channel2).astype(np.float32)
170
  stereo_audio = np.column_stack((channel1, channel2))
171
 
 
172
  wordpress_url = "https://songlabai.com/xmlrpc.php"
173
  woocommerce_url = "https://songlabai.com"
174
  consumer_key = "ck_93d516ba12289a6fd0eced56bbc0b05ecbf98735"
@@ -176,39 +65,58 @@ def save_to_wordpress(channel1, channel2, sample_rate):
176
  username = "admin_h2ibbgql"
177
  password = "um^VdaNK0H8Vw2*KNJlYABkh"
178
 
 
179
  wav_bytes = BytesIO()
180
  sf.write(wav_bytes, stereo_audio, samplerate=sample_rate, format="WAV")
181
  title = f"generated_audio_{datetime.now().timestamp()}.wav"
182
  file_data = {
183
  "name": title,
184
- "type": "audio/x-wav",
185
  "bits": xmlrpc_client.Binary(wav_bytes.getvalue()),
186
  }
187
-
188
  wp_client = Client(wordpress_url, username, password)
189
  for _ in range(4):
190
  try:
 
 
191
  media_response = wp_client.call(media.UploadFile(file_data))
 
 
192
  if media_response:
 
 
 
 
 
 
193
  product_data = {
194
  "status": "pending",
195
  "name": title,
196
  "type": "simple",
197
- "regular_price": "1.00",
198
  "sku": str(uuid.uuid4()),
199
  "downloadable": True,
200
  "download_limit": -1,
201
  "download_expiry": -1,
202
  }
 
 
203
  wc_api = API(
204
  url=woocommerce_url,
205
  consumer_key=consumer_key,
206
  consumer_secret=consumer_secret,
207
  version="wc/v3",
208
  )
 
 
209
  response = wc_api.post("products", product_data)
210
 
 
211
  if response.status_code == 201:
 
 
 
 
212
  product_update_data = {
213
  "downloads": [
214
  {
@@ -221,47 +129,35 @@ def save_to_wordpress(channel1, channel2, sample_rate):
221
  response = wc_api.put(f"products/{product_id}", product_update_data)
222
 
223
  if response.status_code == 200:
 
 
 
224
  return (
225
  response.json()["permalink"],
226
  response.json()["permalink"].split("p=")[-1],
227
  )
 
 
 
 
 
 
 
 
 
228
  break
229
  except Exception as e:
230
  print("Error:", e)
231
 
232
- # Main function for the app
233
- def main():
234
- st.title("Songlab AI - Music Generation")
235
 
236
- user_id = check_user_logged_in()
 
 
 
237
 
238
- if user_id:
239
- st.success(f"User is logged in with ID: {user_id}")
240
 
241
- # Check the user's subscription
242
- subscription_data = check_user_subscription(user_id)
243
-
244
- if subscription_data:
245
- if subscription_data["status"] == "active":
246
- # Handle the subscription-based generation logic
247
- if handle_generation_logic(subscription_data):
248
- # User inputs for music generation
249
- genre = st.selectbox("Select Genre:", ["Pop", "Rock", "Jazz", "Hip Hop", "Classical"])
250
- energy_level = st.radio("Energy Level:", ["Low", "Medium", "High"])
251
- description = st.text_input("Description of the mood or theme:", "")
252
- tempo = st.slider("Tempo (in bpm):", min_value=60, max_value=180, value=100)
253
- duration = st.slider("Duration (in seconds):", min_value=15, max_value=300, value=30)
254
-
255
- if st.button("Generate Music"):
256
- generate_music(user_id, genre, energy_level, tempo, description, duration)
257
- else:
258
- st.error("Your subscription is not active. Please renew your subscription.")
259
- else:
260
- st.error("Unable to fetch subscription data.")
261
- else:
262
- st.warning("You are not logged in.")
263
- show_login_button()
264
-
265
  # Initialize session state variables
266
  if "vocal_audio" not in st_state:
267
  st_state.vocal_audio = None
@@ -281,6 +177,195 @@ if "augmented_audio_pydub" not in st_state:
281
  st_state.augmented_audio_pydub = None
282
  if "augmented_audio_sample_rate" not in st_state:
283
  st_state.augmented_audio_sample_rate = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  # Post-processing options
285
  st.header("Post-processing Options")
286
 
 
23
  from wordpress_xmlrpc.compat import xmlrpc_client
24
  from wordpress_xmlrpc.methods import media
25
 
26
+
27
+ # Try to get API_URL from environment variables, if not found set to a default value
 
 
 
 
 
 
28
  try:
29
  API_URL = os.environ["API_URL"]
30
  except KeyError:
31
  st.error("API_URL environment variable is not set.")
32
  st.stop()
33
 
34
+ # Try to get the Bearer token from environment variables, if not found set to a default value
35
  try:
36
  BEARER_TOKEN = os.environ["BEARER_TOKEN"]
37
  except KeyError:
 
51
  '''
52
  st.markdown(page_bg_img, unsafe_allow_html=True)
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  def save_to_wordpress(channel1, channel2, sample_rate):
55
 
56
  channel1 = np.array(channel1).astype(np.float32)
57
  channel2 = np.array(channel2).astype(np.float32)
58
  stereo_audio = np.column_stack((channel1, channel2))
59
 
60
+ # Define your WordPress site URL and authentication credentials
61
  wordpress_url = "https://songlabai.com/xmlrpc.php"
62
  woocommerce_url = "https://songlabai.com"
63
  consumer_key = "ck_93d516ba12289a6fd0eced56bbc0b05ecbf98735"
 
65
  username = "admin_h2ibbgql"
66
  password = "um^VdaNK0H8Vw2*KNJlYABkh"
67
 
68
+ # Authenticate with WordPress XML-RPC API
69
  wav_bytes = BytesIO()
70
  sf.write(wav_bytes, stereo_audio, samplerate=sample_rate, format="WAV")
71
  title = f"generated_audio_{datetime.now().timestamp()}.wav"
72
  file_data = {
73
  "name": title,
74
+ "type": "audio/x-wav", # Change the MIME type according to your file type
75
  "bits": xmlrpc_client.Binary(wav_bytes.getvalue()),
76
  }
 
77
  wp_client = Client(wordpress_url, username, password)
78
  for _ in range(4):
79
  try:
80
+ # Upload the file to WordPress Media Library
81
+
82
  media_response = wp_client.call(media.UploadFile(file_data))
83
+
84
+ # Handle the response
85
  if media_response:
86
+ print(
87
+ "File successfully uploaded to WordPress with attachment ID:",
88
+ media_response,
89
+ )
90
+
91
+ # Create product data for WooCommerce
92
  product_data = {
93
  "status": "pending",
94
  "name": title,
95
  "type": "simple",
96
+ "regular_price": "1.00", # Set the price as needed
97
  "sku": str(uuid.uuid4()),
98
  "downloadable": True,
99
  "download_limit": -1,
100
  "download_expiry": -1,
101
  }
102
+
103
+ # Authenticate with WooCommerce API
104
  wc_api = API(
105
  url=woocommerce_url,
106
  consumer_key=consumer_key,
107
  consumer_secret=consumer_secret,
108
  version="wc/v3",
109
  )
110
+
111
+ # Create the product
112
  response = wc_api.post("products", product_data)
113
 
114
+ # Handle the response
115
  if response.status_code == 201:
116
+ print(
117
+ "Product successfully created in WooCommerce:", response.json()
118
+ )
119
+ # Update product to add downloadable file URL
120
  product_update_data = {
121
  "downloads": [
122
  {
 
129
  response = wc_api.put(f"products/{product_id}", product_update_data)
130
 
131
  if response.status_code == 200:
132
+ print(
133
+ "Downloadable file URL added to product:", response.json()
134
+ )
135
  return (
136
  response.json()["permalink"],
137
  response.json()["permalink"].split("p=")[-1],
138
  )
139
+ else:
140
+ print(
141
+ "Error adding downloadable file URL to product:",
142
+ response.text,
143
+ )
144
+ else:
145
+ print("Error creating product in WooCommerce:", response.text)
146
+ else:
147
+ print("Error uploading file to WordPress.")
148
  break
149
  except Exception as e:
150
  print("Error:", e)
151
 
 
 
 
152
 
153
+ headers = {
154
+ "Authorization": f"Bearer {BEARER_TOKEN}",
155
+ "Content-Type": "application/json",
156
+ }
157
 
158
+ # Streamlit app title
159
+ st.title("Songlab AI")
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  # Initialize session state variables
162
  if "vocal_audio" not in st_state:
163
  st_state.vocal_audio = None
 
177
  st_state.augmented_audio_pydub = None
178
  if "augmented_audio_sample_rate" not in st_state:
179
  st_state.augmented_audio_sample_rate = None
180
+
181
+
182
+ genres = [
183
+ "Pop",
184
+ "Rock",
185
+ "Hip Hop",
186
+ "Jazz",
187
+ "Blues",
188
+ "Country",
189
+ "Classical",
190
+ "Electronic",
191
+ "Reggae",
192
+ "Folk",
193
+ "R&B",
194
+ "Metal",
195
+ "Punk",
196
+ "Indie",
197
+ "Dance",
198
+ "World",
199
+ "Gospel",
200
+ "Soul",
201
+ "Funk",
202
+ "Ambient",
203
+ "Techno",
204
+ "Disco",
205
+ "House",
206
+ "Trance",
207
+ "Dubstep",
208
+ ]
209
+
210
+ genre = st.selectbox("Select Genre:", genres)
211
+ energy_levels = ["Low", "Medium", "High"]
212
+ energy_level = st.radio("Energy Level:", energy_levels, horizontal=True)
213
+ description = st.text_input("Description:", "")
214
+ tempo = st.slider("Tempo (in bpm):", min_value=40, max_value=100, value=60, step=5)
215
+
216
+ # Duration input
217
+ duration = st.slider(
218
+ "Duration (in seconds):", min_value=15, max_value=300, value=30, step=1
219
+ )
220
+
221
+ prompt2 = "Classical ,Low, 40, slow calm"
222
+
223
+
224
+ def convert_audio_segment_to_float_array(audio_pydub):
225
+ """
226
+ Convert a pydub AudioSegment to a NumPy array of type float32.
227
+
228
+ Args:
229
+ audio_pydub (AudioSegment): The AudioSegment object to be converted.
230
+
231
+ Returns:
232
+ np.ndarray: A NumPy array containing the audio data as float32.
233
+ """
234
+ # Get the raw audio data as a sequence of samples
235
+ samples = audio_pydub.get_array_of_samples()
236
+
237
+ # Convert the samples to a NumPy array and normalize to float32
238
+ audio_array = np.array(samples).astype(np.float32)
239
+
240
+ # Normalize the audio array to range between -1.0 and 1.0
241
+ max_val = 2**15 # Assuming 16-bit audio, modify this if using different bit depths
242
+ audio_array /= max_val
243
+ return audio_array
244
+
245
+ def time_post_request(api_url, headers=None, payload=None):
246
+ """
247
+ Times the execution of a POST request.
248
+
249
+ Parameters:
250
+ - api_url (str): The URL to which the POST request is sent.
251
+ - headers (dict): The headers to include in the POST request.
252
+ - payload (dict): The payload to include in the POST request.
253
+
254
+ Returns:
255
+ - response (requests.Response): The response object returned by the POST request.
256
+ - execution_time (float): The time it took to execute the POST request.
257
+ """
258
+ start_time = time.time()
259
+ response = requests.post(api_url, headers=headers, json=payload)
260
+ end_time = time.time()
261
+
262
+ execution_time = end_time - start_time
263
+ print(f"Execution time: {execution_time} seconds")
264
+
265
+ return response
266
+
267
+ def generate_audio(genre, energy_level, tempo, description, duration):
268
+ count_down = 300
269
+ prompt = f"Genre: {genre}, Energy Level: {energy_level}, Tempo: {tempo}, Description: {description},"
270
+ payload = {"inputs": {"prompt": prompt, "duration": duration}}
271
+ with st.spinner("Generating audio ..."):
272
+ response = time_post_request(API_URL, headers, payload)
273
+ placeholder1 = st.empty()
274
+ if response.status_code != 200:
275
+ # Temp Jay Start
276
+ print(f"Request Headers: {response.request.headers}")
277
+ print(f"Request Body: {response.request.body}")
278
+ print(f"Response Code: {response.status_code}")
279
+ print(f"Response Body: {response.text}")
280
+ # Temp Jay End
281
+
282
+
283
+ print(str(response.content))
284
+ count_down_placeholder = st.empty()
285
+ for seconds in range(count_down):
286
+ count_down_placeholder.info(
287
+ f"The server is currently loading. Retrying in ⏳ {count_down - seconds} seconds."
288
+ )
289
+ time.sleep(1)
290
+ count_down_placeholder.empty()
291
+ with st.spinner("Generating audio ..."):
292
+ response = time_post_request(API_URL, headers, payload)
293
+ if response.status_code != 200:
294
+ count_down_placeholder = st.empty()
295
+ for seconds in range(count_down):
296
+ count_down_placeholder.info(
297
+ f"2nd attempt failed. trying again one more time in ⏳ {count_down - seconds} seconds."
298
+ )
299
+ time.sleep(1)
300
+ count_down_placeholder.empty()
301
+ with st.spinner("Generating audio ..."):
302
+ response = time_post_request(API_URL, headers, payload)
303
+ if response.status_code != 200:
304
+ placeholder1.error(
305
+ "Failed to generate audio after multiple attempts. Please try again later."
306
+ )
307
+ else:
308
+ placeholder1.success(f"✔️ Audio Generated, Loading...")
309
+ load_and_play_generated_audio(response)
310
+ placeholder1.empty()
311
+ else:
312
+ placeholder1.success(f"✔️ Audio Generated, Loading...")
313
+ load_and_play_generated_audio(response)
314
+ placeholder1.empty()
315
+ else:
316
+ placeholder1.success(f"✔️ Audio Generated, Loading...")
317
+ load_and_play_generated_audio(response)
318
+ placeholder1.empty()
319
+
320
+
321
+ def load_and_play_generated_audio(response):
322
+
323
+ response_eval = json.loads(response.content)
324
+ channel1 = response_eval[0]["generated_audio"][0]
325
+ channel2 = response_eval[0]["generated_audio"][1]
326
+ with NamedTemporaryFile() as f1:
327
+ scipy.io.wavfile.write(
328
+ f1.name, rate=32000, data=np.array(channel1).astype(np.float32)
329
+ )
330
+ channel1_temp = AudioSegment.from_file(f1.name)
331
+ with NamedTemporaryFile() as f2:
332
+ scipy.io.wavfile.write(
333
+ f2.name, rate=32000, data=np.array(channel2).astype(np.float32)
334
+ )
335
+ channel2_temp = AudioSegment.from_file(f2.name)
336
+ audio_pydub = AudioSegment.from_mono_audiosegments(channel1_temp, channel2_temp)
337
+ st_state.audio_pydub = audio_pydub
338
+ st_state.audio_pydub_sample_rate = audio_pydub.frame_rate
339
+
340
+ st_state.audio = np.array(st_state.audio_pydub.get_array_of_samples()).astype(np.float32)
341
+ sample_rate = response_eval[0]["sample_rate"]
342
+ perm_link, product_code = save_to_wordpress(
343
+ channel1, channel2, 32000
344
+ )
345
+
346
+ st_state.audio_sample_rate = sample_rate
347
+ st_state.augmented_audio_pydub = st_state.audio_pydub
348
+ st.audio(st_state.audio_pydub.export().read())
349
+ col_btn, col_text = st.columns([2,4])
350
+
351
+ with col_btn:
352
+ st.link_button("Publish your Song", "https://songlabai.com/contact_us/")
353
+ st.link_button("Download Song", "https://songlabai.com/download-music/")
354
+
355
+ with col_text:
356
+ st.write(
357
+ f"To Publish, please contact the admin by sending the following link: {perm_link}"
358
+ )
359
+ st.write(f"To download use the following product code: {product_code}")
360
+
361
+
362
+ if st.button("Generate Audio"):
363
+ if genre and energy_level and description and tempo:
364
+ generate_audio(genre, energy_level, tempo, description, duration)
365
+
366
+ if description == "":
367
+ st.info("Description field is required.")
368
+
369
  # Post-processing options
370
  st.header("Post-processing Options")
371