Phoenixak99 commited on
Commit
a91333d
·
verified ·
1 Parent(s): ce4b2b6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +214 -93
app.py CHANGED
@@ -6,6 +6,7 @@ import uuid
6
  from datetime import datetime
7
  from io import BytesIO
8
  from tempfile import NamedTemporaryFile
 
9
  import jwt
10
 
11
  import numpy as np
@@ -50,40 +51,13 @@ background-size: cover;
50
  '''
51
  st.markdown(page_bg_img, unsafe_allow_html=True)
52
 
53
- # Helper functions
54
- def check_user_login():
55
- """Check if the user is logged in by calling the WordPress API"""
56
- api_url = "https://songlabai.com/wp-json/custom-api/v1/current-user-id-session"
57
- response = requests.get(api_url)
58
- if response.status_code == 200:
59
- user_data = response.json()
60
- if 'user_id' in user_data:
61
- return user_data['user_id']
62
- return None
63
-
64
- def get_user_subscription(user_id):
65
- """Retrieve the subscription status and daily limit information"""
66
- api_url = f"https://songlabai.com/wp-json/custom-api/subscription/{user_id}"
67
- response = requests.get(api_url)
68
- if response.status_code == 200:
69
- return response.json()
70
- return None
71
-
72
- def update_user_generation_limit(user_id):
73
- """Update the user's daily generation limit once successful generation occurs"""
74
- api_url = f"https://songlabai.com/wp-json/custom-api/update-limit/{user_id}"
75
- response = requests.post(api_url)
76
- if response.status_code != 200:
77
- print("Failed to update the user's daily limit.")
78
- else:
79
- print("User's daily limit updated successfully.")
80
-
81
  def save_to_wordpress(channel1, channel2, sample_rate):
82
- """Save generated audio to WordPress and WooCommerce"""
83
  channel1 = np.array(channel1).astype(np.float32)
84
  channel2 = np.array(channel2).astype(np.float32)
85
  stereo_audio = np.column_stack((channel1, channel2))
86
 
 
87
  wordpress_url = "https://songlabai.com/xmlrpc.php"
88
  woocommerce_url = "https://songlabai.com"
89
  consumer_key = "ck_93d516ba12289a6fd0eced56bbc0b05ecbf98735"
@@ -91,30 +65,42 @@ def save_to_wordpress(channel1, channel2, sample_rate):
91
  username = "admin_h2ibbgql"
92
  password = "um^VdaNK0H8Vw2*KNJlYABkh"
93
 
 
94
  wav_bytes = BytesIO()
95
  sf.write(wav_bytes, stereo_audio, samplerate=sample_rate, format="WAV")
96
  title = f"generated_audio_{datetime.now().timestamp()}.wav"
97
  file_data = {
98
  "name": title,
99
- "type": "audio/x-wav",
100
  "bits": xmlrpc_client.Binary(wav_bytes.getvalue()),
101
  }
102
  wp_client = Client(wordpress_url, username, password)
103
  for _ in range(4):
104
  try:
 
 
105
  media_response = wp_client.call(media.UploadFile(file_data))
 
 
106
  if media_response:
 
 
 
 
 
 
107
  product_data = {
108
  "status": "pending",
109
  "name": title,
110
  "type": "simple",
111
- "regular_price": "1.00",
112
  "sku": str(uuid.uuid4()),
113
  "downloadable": True,
114
  "download_limit": -1,
115
  "download_expiry": -1,
116
  }
117
 
 
118
  wc_api = API(
119
  url=woocommerce_url,
120
  consumer_key=consumer_key,
@@ -122,8 +108,15 @@ def save_to_wordpress(channel1, channel2, sample_rate):
122
  version="wc/v3",
123
  )
124
 
 
125
  response = wc_api.post("products", product_data)
 
 
126
  if response.status_code == 201:
 
 
 
 
127
  product_update_data = {
128
  "downloads": [
129
  {
@@ -136,115 +129,243 @@ def save_to_wordpress(channel1, channel2, sample_rate):
136
  response = wc_api.put(f"products/{product_id}", product_update_data)
137
 
138
  if response.status_code == 200:
 
 
 
139
  return (
140
  response.json()["permalink"],
141
  response.json()["permalink"].split("p=")[-1],
142
  )
 
 
 
 
 
 
 
 
 
143
  break
144
  except Exception as e:
145
  print("Error:", e)
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
- print(f"Execution time: {end_time - start_time} seconds")
 
 
 
153
  return response
154
 
155
  def generate_audio(genre, energy_level, tempo, description, duration):
156
- user_id = check_user_login()
157
- if user_id:
158
- subscription_info = get_user_subscription(user_id)
159
- if subscription_info:
160
- plan_id = subscription_info['subscription_plan_id']
161
- has_exceeded_daily_limit = subscription_info['has_exceeded_daily_limit']
162
-
163
- if plan_id == "576" and has_exceeded_daily_limit:
164
- st.warning("You've reached your daily limit for free users. Upgrade to a paid plan to generate more audio.")
165
- st.stop()
166
-
167
- count_down = 300
168
- prompt = f"Genre: {genre}, Energy Level: {energy_level}, Tempo: {tempo}, Description: {description},"
169
- payload = {"inputs": {"prompt": prompt, "duration": duration}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  with st.spinner("Generating audio ..."):
171
  response = time_post_request(API_URL, headers, payload)
172
-
173
- placeholder1 = st.empty()
174
- if response.status_code == 200:
175
- placeholder1.success("✔️ Audio Generated, Loading...")
176
- load_and_play_generated_audio(response)
177
- update_user_generation_limit(user_id) # Update daily limit after successful generation
178
  else:
179
- handle_failed_request(response, count_down, payload)
 
 
180
  else:
181
- st.warning("Unable to retrieve subscription details.")
 
 
182
  else:
183
- st.warning("You must be logged in to generate audio.")
184
- st.button("Login", on_click=lambda: st.experimental_set_query_params(next="https://songlabai.com/login"))
185
-
186
- def handle_failed_request(response, count_down, payload):
187
- print(f"Response Code: {response.status_code}")
188
- print(f"Response Body: {response.text}")
189
- count_down_placeholder = st.empty()
190
- for seconds in range(count_down):
191
- count_down_placeholder.info(f"Retrying in ⏳ {count_down - seconds} seconds.")
192
- time.sleep(1)
193
- count_down_placeholder.empty()
194
- with st.spinner("Generating audio ..."):
195
- response = time_post_request(API_URL, headers, payload)
196
- if response.status_code == 200:
197
  load_and_play_generated_audio(response)
198
- else:
199
- st.error("Failed to generate audio. Please try again later.")
200
 
201
  def load_and_play_generated_audio(response):
202
- response_eval = json.loads(response.content)
203
- channel1 = response_eval[0]["generated_audio"][0]
204
- channel2 = response_eval[0]["generated_audio"][1]
205
 
 
 
 
206
  with NamedTemporaryFile() as f1:
207
- scipy.io.wavfile.write(f1.name, rate=32000, data=np.array(channel1).astype(np.float32))
 
 
208
  channel1_temp = AudioSegment.from_file(f1.name)
209
  with NamedTemporaryFile() as f2:
210
- scipy.io.wavfile.write(f2.name, rate=32000, data=np.array(channel2).astype(np.float32))
 
 
211
  channel2_temp = AudioSegment.from_file(f2.name)
212
  audio_pydub = AudioSegment.from_mono_audiosegments(channel1_temp, channel2_temp)
213
  st_state.audio_pydub = audio_pydub
214
  st_state.audio_pydub_sample_rate = audio_pydub.frame_rate
215
-
216
  st_state.audio = np.array(st_state.audio_pydub.get_array_of_samples()).astype(np.float32)
217
- perm_link, product_code = save_to_wordpress(channel1, channel2, 32000)
218
-
 
 
 
 
219
  st_state.augmented_audio_pydub = st_state.audio_pydub
220
  st.audio(st_state.audio_pydub.export().read())
221
- col_btn, col_text = st.columns([2, 4])
222
 
223
  with col_btn:
224
  st.link_button("Publish your Song", "https://songlabai.com/contact_us/")
225
  st.link_button("Download Song", "https://songlabai.com/download-music/")
226
 
227
  with col_text:
228
- st.write(f"To publish, contact admin using this link: {perm_link}")
229
- st.write(f"To download, use this product code: {product_code}")
230
-
 
231
 
232
- # Streamlit UI elements
233
- st.title("Songlab AI")
234
 
235
  if st.button("Generate Audio"):
236
- genre = st.selectbox("Select Genre:", ["Pop", "Rock", "Hip Hop", "Jazz", "Classical"])
237
- energy_level = st.radio("Energy Level:", ["Low", "Medium", "High"], horizontal=True)
238
- description = st.text_input("Description:", "")
239
- tempo = st.slider("Tempo (in bpm):", min_value=40, max_value=100, value=60, step=5)
240
- duration = st.slider("Duration (in seconds):", min_value=15, max_value=300, value=30, step=1)
241
-
242
- if description:
243
  generate_audio(genre, energy_level, tempo, description, duration)
244
- else:
 
245
  st.info("Description field is required.")
246
 
247
-
248
  # Post-processing options
249
  st.header("Post-processing Options")
250
 
 
6
  from datetime import datetime
7
  from io import BytesIO
8
  from tempfile import NamedTemporaryFile
9
+ from xmlrpc.client import Binary
10
  import jwt
11
 
12
  import numpy as np
 
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,
 
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
164
+ if "vocal_sample_rate" not in st_state:
165
+ st_state.vocal_sample_rate = None
166
+
167
+ if "audio" not in st_state:
168
+ st_state.audio = None
169
+ if "audio_pydub" not in st_state:
170
+ st_state.audio_pydub = None
171
+ if "audio_sample_rate" not in st_state:
172
+ st_state.audio_sample_rate = None
173
+
174
+ if "augmented_audio" not in st_state:
175
+ st_state.augmented_audio = None
176
+ if "augmented_audio_pydub" not in st_state:
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