MySafeCode commited on
Commit
3f8d06c
·
verified ·
1 Parent(s): ecde374

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -27
app.py CHANGED
@@ -9,8 +9,82 @@ SUNO_KEY = os.environ.get("SunoKey", "")
9
  if not SUNO_KEY:
10
  print("⚠️ SunoKey not set!")
11
 
12
- def separate_vocals(task_id, audio_id, separation_type):
13
- """Separate vocals and instruments from Suno tracks - semi working, you need some knowledge and api backroom access."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  if not SUNO_KEY:
15
  yield "❌ Error: SunoKey not configured in environment variables"
16
  return
@@ -146,17 +220,28 @@ with gr.Blocks(title="Suno Stem Separator", theme="soft") as app:
146
 
147
  with gr.Row():
148
  with gr.Column(scale=1):
149
- task_id = gr.Textbox(
150
- label="Original Task ID",
 
151
  placeholder="Example: 5c79****be8e",
152
- info="The task ID from your Suno music generation"
 
153
  )
154
- audio_id = gr.Textbox(
155
- label="Audio ID",
156
- placeholder="Example: e231****-****-****-****-****8cadc7dc",
157
- info="The specific audio ID to separate"
 
 
 
 
 
 
158
  )
159
 
 
 
 
160
  separation_type = gr.Radio(
161
  label="Separation Type",
162
  choices=[
@@ -164,37 +249,38 @@ with gr.Blocks(title="Suno Stem Separator", theme="soft") as app:
164
  ("split_stem (12 stems - 5 credits)", "split_stem")
165
  ],
166
  value="separate_vocal",
167
- info="Choose separation mode"
 
168
  )
169
 
170
- btn = gr.Button("🎵 Separate Stems", variant="primary", scale=1)
171
 
172
- gr.Markdown("""
173
- **How it works:**
174
- 1. Enter Task ID and Audio ID from your Suno track
175
- 2. Choose separation type
176
- 3. Click Separate Stems
177
- 4. Wait 30-120 seconds
178
- 5. Get download links for each stem
179
 
180
  **Separation types:**
181
  - 🎤 **separate_vocal**: Vocals + Instrumental (2 stems, 1 credit)
182
  - 🎛️ **split_stem**: 12 detailed stems (5 credits)
183
 
184
- **Stem Types in split_stem:**
185
- - Vocals, Backing Vocals, Drums, Bass
186
- - Guitar, Keyboard, Strings, Brass
187
- - Woodwinds, Percussion, Synth, FX/Other
188
-
189
  ⚠️ **Important:**
190
  - Each request consumes credits
191
  - Links expire in 14 days
192
  """)
193
 
194
  with gr.Column(scale=2):
195
- output = gr.Markdown(
 
 
 
 
 
196
  label="Separation Results",
197
- value="Your separated stems will appear here..."
198
  )
199
 
200
  gr.Markdown("---")
@@ -205,13 +291,71 @@ with gr.Blocks(title="Suno Stem Separator", theme="soft") as app:
205
  <a href="https://sunoapi.org" target="_blank">Suno API Docs</a> •
206
  <a href="https://docs.sunoapi.org/separate-vocals" target="_blank">Stem Separation Guide</a></p>
207
  <p><small>This app uses the Suno API to separate tracks into individual stems.</small></p>
208
- <p><small>💡 <strong>Tip:</strong> Find your Task ID and Audio ID in your Suno generation history or API responses.</small></p>
209
  </div>
210
  """,
211
  elem_id="footer"
212
  )
213
 
214
- btn.click(separate_vocals, [task_id, audio_id, separation_type], output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
 
216
  if __name__ == "__main__":
217
  print("🚀 Starting Suno Stem Separator")
 
9
  if not SUNO_KEY:
10
  print("⚠️ SunoKey not set!")
11
 
12
+ def get_audio_info(task_id):
13
+ """Get audio information from Suno task ID"""
14
+ if not SUNO_KEY:
15
+ return "❌ Error: SunoKey not configured in environment variables", []
16
+
17
+ if not task_id.strip():
18
+ return "❌ Error: Please enter Task ID", []
19
+
20
+ try:
21
+ resp = requests.get(
22
+ "https://api.sunoapi.org/api/v1/generate/record-info",
23
+ headers={"Authorization": f"Bearer {SUNO_KEY}"},
24
+ params={"taskId": task_id.strip()},
25
+ timeout=30
26
+ )
27
+
28
+ if resp.status_code != 200:
29
+ return f"❌ Request failed: HTTP {resp.status_code}", []
30
+
31
+ data = resp.json()
32
+ if data.get("code") != 200:
33
+ return f"❌ API error: {data.get('msg', 'Unknown')}", []
34
+
35
+ # Check if task is complete
36
+ status = data["data"].get("status", "PENDING")
37
+ if status != "SUCCESS":
38
+ return f"⏳ Task status: {status}. Please wait for generation to complete.", []
39
+
40
+ # Parse sunoData to get audio options
41
+ suno_data = data["data"]["response"].get("sunoData", [])
42
+ if not suno_data:
43
+ return "❌ No audio data found in response", []
44
+
45
+ # Create audio options for dropdown
46
+ audio_options = []
47
+ for i, audio in enumerate(suno_data):
48
+ audio_id = audio.get("id", "")
49
+ prompt = audio.get("prompt", "No prompt")
50
+ title = audio.get("title", "Untitled")
51
+ duration = audio.get("duration", 0)
52
+
53
+ # Truncate long prompts for display
54
+ display_prompt = prompt[:50] + "..." if len(prompt) > 50 else prompt
55
+
56
+ # Create display text and store full data
57
+ display_text = f"Track {i+1}: {title} ({duration:.1f}s) - {display_prompt}"
58
+ audio_options.append((display_text, audio_id, audio))
59
+
60
+ if not audio_options:
61
+ return "❌ No valid audio tracks found", []
62
+
63
+ # Format output message
64
+ output = f"✅ **Task Found!**\n"
65
+ output += f"**Task ID:** `{task_id}`\n"
66
+ output += f"**Status:** {status}\n"
67
+ output += f"**Found {len(audio_options)} audio track(s):**\n\n"
68
+
69
+ for i, (display_text, audio_id, audio) in enumerate(audio_options):
70
+ output += f"**Track {i+1}:**\n"
71
+ output += f"- **ID:** `{audio_id}`\n"
72
+ output += f"- **Title:** {audio.get('title', 'Untitled')}\n"
73
+ output += f"- **Prompt:** {audio.get('prompt', 'No prompt')[:100]}...\n"
74
+ output += f"- **Duration:** {audio.get('duration', 0):.1f}s\n"
75
+ if audio.get('audioUrl'):
76
+ output += f"- **Audio:** [Listen]({audio.get('audioUrl')})\n"
77
+ output += "\n"
78
+
79
+ output += "👇 **Select a track from the dropdown below to separate stems**"
80
+
81
+ return output, audio_options
82
+
83
+ except Exception as e:
84
+ return f"❌ Error: {str(e)}", []
85
+
86
+ def separate_vocals(task_id, audio_id, separation_type, audio_data=None):
87
+ """Separate vocals and instruments from Suno tracks"""
88
  if not SUNO_KEY:
89
  yield "❌ Error: SunoKey not configured in environment variables"
90
  return
 
220
 
221
  with gr.Row():
222
  with gr.Column(scale=1):
223
+ # Step 1: Enter Task ID
224
+ task_id_input = gr.Textbox(
225
+ label="Task ID",
226
  placeholder="Example: 5c79****be8e",
227
+ info="Enter your Suno generation task ID",
228
+ elem_id="task_id_input"
229
  )
230
+
231
+ get_audio_btn = gr.Button("🔍 Find Audio Tracks", variant="secondary")
232
+
233
+ # Will be updated after getting audio info
234
+ audio_dropdown = gr.Dropdown(
235
+ label="Select Audio Track to Separate",
236
+ choices=[],
237
+ info="Choose which audio track to process",
238
+ visible=False,
239
+ interactive=True
240
  )
241
 
242
+ # Hidden store for audio data
243
+ audio_data_store = gr.State(value=None)
244
+
245
  separation_type = gr.Radio(
246
  label="Separation Type",
247
  choices=[
 
249
  ("split_stem (12 stems - 5 credits)", "split_stem")
250
  ],
251
  value="separate_vocal",
252
+ info="Choose separation mode",
253
+ visible=False
254
  )
255
 
256
+ separate_btn = gr.Button("🎵 Separate Stems", variant="primary", visible=False)
257
 
258
+ gr.Markdown("""**Workflow:**
259
+ 1. Enter Task ID → Click "Find Audio Tracks"
260
+ 2. Select which audio track to separate
261
+ 3. Choose separation type
262
+ 4. Click "Separate Stems"
263
+ 5. Wait 30-120 seconds
264
+ 6. Get download links for each stem
265
 
266
  **Separation types:**
267
  - 🎤 **separate_vocal**: Vocals + Instrumental (2 stems, 1 credit)
268
  - 🎛️ **split_stem**: 12 detailed stems (5 credits)
269
 
 
 
 
 
 
270
  ⚠️ **Important:**
271
  - Each request consumes credits
272
  - Links expire in 14 days
273
  """)
274
 
275
  with gr.Column(scale=2):
276
+ status_output = gr.Markdown(
277
+ label="Status",
278
+ value="Enter a Task ID and click 'Find Audio Tracks'..."
279
+ )
280
+
281
+ results_output = gr.Markdown(
282
  label="Separation Results",
283
+ visible=False
284
  )
285
 
286
  gr.Markdown("---")
 
291
  <a href="https://sunoapi.org" target="_blank">Suno API Docs</a> •
292
  <a href="https://docs.sunoapi.org/separate-vocals" target="_blank">Stem Separation Guide</a></p>
293
  <p><small>This app uses the Suno API to separate tracks into individual stems.</small></p>
 
294
  </div>
295
  """,
296
  elem_id="footer"
297
  )
298
 
299
+ # Step 1: Get audio info when button is clicked
300
+ def on_get_audio(task_id):
301
+ if not task_id:
302
+ return (
303
+ "❌ Please enter a Task ID",
304
+ gr.Dropdown(choices=[], visible=False),
305
+ gr.Radio(visible=False),
306
+ gr.Button(visible=False),
307
+ gr.Markdown(visible=False),
308
+ None
309
+ )
310
+
311
+ output, audio_options = get_audio_info(task_id)
312
+
313
+ if not audio_options:
314
+ # No audio found, show error
315
+ return (
316
+ output,
317
+ gr.Dropdown(choices=[], visible=False),
318
+ gr.Radio(visible=False),
319
+ gr.Button(visible=False),
320
+ gr.Markdown(visible=False),
321
+ None
322
+ )
323
+
324
+ # Create choices for dropdown
325
+ choices = [(display_text, audio_id) for display_text, audio_id, _ in audio_options]
326
+
327
+ # Store full audio data for later use
328
+ audio_data_map = {audio_id: audio for _, audio_id, audio in audio_options}
329
+
330
+ return (
331
+ output,
332
+ gr.Dropdown(choices=choices, value=choices[0][1] if choices else None, visible=True),
333
+ gr.Radio(visible=True),
334
+ gr.Button(visible=True),
335
+ gr.Markdown(visible=False),
336
+ audio_data_map
337
+ )
338
+
339
+ # Step 2: Separate stems when button is clicked
340
+ def on_separate(task_id, audio_id, separation_type, audio_data_store):
341
+ # Use the stored task_id from the first step
342
+ yield from separate_vocals(task_id, audio_id, separation_type)
343
+
344
+ # Connect events
345
+ get_audio_btn.click(
346
+ fn=on_get_audio,
347
+ inputs=[task_id_input],
348
+ outputs=[status_output, audio_dropdown, separation_type, separate_btn, results_output, audio_data_store]
349
+ )
350
+
351
+ separate_btn.click(
352
+ fn=on_separate,
353
+ inputs=[task_id_input, audio_dropdown, separation_type, audio_data_store],
354
+ outputs=[results_output]
355
+ ).then(
356
+ lambda: gr.Markdown(visible=True),
357
+ outputs=[results_output]
358
+ )
359
 
360
  if __name__ == "__main__":
361
  print("🚀 Starting Suno Stem Separator")