ray-006 commited on
Commit
9bdbcfb
·
verified ·
1 Parent(s): d0c9da6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -53
app.py CHANGED
@@ -5,8 +5,14 @@ import tempfile
5
  import shutil
6
  import threading
7
 
8
- def delayed_delete(path, delay=1800): # 1800 seconds = 30 minutes
9
- """Function to delete a path after a set delay."""
 
 
 
 
 
 
10
  def command():
11
  import time
12
  time.sleep(delay)
@@ -15,86 +21,65 @@ def delayed_delete(path, delay=1800): # 1800 seconds = 30 minutes
15
  shutil.rmtree(path)
16
  elif os.path.isfile(path):
17
  os.remove(path)
18
- print(f"Cleanup: Deleted {path}")
19
  except Exception as e:
20
- print(f"Error cleaning up {path}: {e}")
21
 
22
- # Start a background thread so it doesn't block your app
23
  threading.Thread(target=command, daemon=True).start()
24
-
25
  def separate_audio(input_file, model_name):
26
  if input_file is None:
27
  return [None] * 6
28
 
29
- # Create a temporary directory for this specific session
30
- temp_dir = tempfile.mkdtemp()
 
 
31
 
32
  try:
33
- # Initialize separator with the temp directory
34
- separator = Separator(output_dir=temp_dir, output_format="MP3", output_bitrate="128k")
35
- separator.load_model(model_filename=model_name)
36
- output_files = separator.separate(input_file)
 
37
 
38
  stems = ["Vocals", "Drums", "Bass", "Other", "Guitar", "Piano"]
39
  results = []
40
 
41
  for stem in stems:
42
- match = next((os.path.join(temp_dir, f) for f in output_files if stem in f), None)
43
  results.append(match)
44
 
45
- # Schedule cleanup once after processing is successful
46
- delayed_delete(temp_dir, delay=1800)
47
  return tuple(results)
48
 
49
  except Exception as e:
50
- # Cleanup immediately if something crashes
51
- if os.path.exists(temp_dir):
52
- shutil.rmtree(temp_dir)
53
- print(f"Error during separation: {e}")
54
- raise e
55
 
56
  # --- Gradio Interface ---
57
  with gr.Blocks() as demo:
58
- gr.Markdown("""
59
- # 🎵 AI 6-Stem Audio Separator
60
- Split your music into high-quality individual tracks using the **Demucs 6s** model.
61
- """)
62
 
63
  with gr.Row():
64
- with gr.Column(scale=1):
65
- input_audio = gr.Audio(
66
- label="Upload Audio File",
67
- type="filepath",
68
- interactive=True
69
- )
70
- model_dropdown = gr.Dropdown(
71
- choices=["htdemucs_6s.yaml"],
72
- value="htdemucs_6s.yaml",
73
- label="Select Model"
74
- )
75
- separate_btn = gr.Button("🚀 Separate Stems", variant="primary")
76
 
77
- with gr.Column(scale=2):
78
- with gr.Group():
79
- gr.Markdown("### 🔊 Separation Results")
80
- with gr.Row():
81
- output_vocals = gr.Audio(label="🎤 Vocals", type="filepath")
82
- output_drums = gr.Audio(label="🥁 Drums", type="filepath")
83
- with gr.Row():
84
- output_bass = gr.Audio(label="🎸 Bass", type="filepath")
85
- output_guitar = gr.Audio(label="🎸 Guitar", type="filepath")
86
- with gr.Row():
87
- output_piano = gr.Audio(label="🎹 Piano", type="filepath")
88
- output_other = gr.Audio(label="🎼 Other", type="filepath")
89
 
90
- # Action binding
91
  separate_btn.click(
92
  fn=separate_audio,
93
  inputs=[input_audio, model_dropdown],
94
- outputs=[
95
- output_vocals, output_drums, output_bass,
96
- output_other, output_guitar, output_piano
97
- ]
98
  )
99
 
100
  gr.Markdown("---")
 
5
  import shutil
6
  import threading
7
 
8
+ # 1. INITIALIZE SEPARATOR GLOBALLY (Load once, use many times)
9
+ # This stays in RAM so requests start instantly.
10
+ BASE_TEMP_DIR = tempfile.mkdtemp()
11
+ global_separator = Separator(output_dir=BASE_TEMP_DIR, output_format="MP3", output_bitrate="128k")
12
+ print("Loading model into memory...")
13
+ global_separator.load_model(model_filename="htdemucs_6s.yaml")
14
+
15
+ def delayed_delete(path, delay=1800):
16
  def command():
17
  import time
18
  time.sleep(delay)
 
21
  shutil.rmtree(path)
22
  elif os.path.isfile(path):
23
  os.remove(path)
 
24
  except Exception as e:
25
+ print(f"Cleanup error: {e}")
26
 
 
27
  threading.Thread(target=command, daemon=True).start()
28
+
29
  def separate_audio(input_file, model_name):
30
  if input_file is None:
31
  return [None] * 6
32
 
33
+ # Create a sub-folder for this specific request
34
+ request_id = next(tempfile._get_candidate_names())
35
+ session_dir = os.path.join(BASE_TEMP_DIR, request_id)
36
+ os.makedirs(session_dir, exist_ok=True)
37
 
38
  try:
39
+ # Update the output directory for this specific run
40
+ global_separator.output_dir = session_dir
41
+
42
+ # Perform separation (Model is already loaded!)
43
+ output_files = global_separator.separate(input_file)
44
 
45
  stems = ["Vocals", "Drums", "Bass", "Other", "Guitar", "Piano"]
46
  results = []
47
 
48
  for stem in stems:
49
+ match = next((os.path.join(session_dir, f) for f in output_files if stem in f), None)
50
  results.append(match)
51
 
52
+ delayed_delete(session_dir, delay=600) # Cleanup after 10 mins
 
53
  return tuple(results)
54
 
55
  except Exception as e:
56
+ if os.path.exists(session_dir):
57
+ shutil.rmtree(session_dir)
58
+ raise gr.Error(f"Separation failed: {e}")
 
 
59
 
60
  # --- Gradio Interface ---
61
  with gr.Blocks() as demo:
62
+ gr.Markdown("# 🎵 AI 6-Stem Audio Separator")
 
 
 
63
 
64
  with gr.Row():
65
+ with gr.Column():
66
+ input_audio = gr.Audio(label="Upload Audio File", type="filepath")
67
+ model_dropdown = gr.Dropdown(choices=["htdemucs_6s.yaml"], value="htdemucs_6s.yaml", label="Model")
68
+ separate_btn = gr.Button("🚀 Separate", variant="primary")
 
 
 
 
 
 
 
 
69
 
70
+ with gr.Column():
71
+ output_vocals = gr.Audio(label="🎤 Vocals")
72
+ output_drums = gr.Audio(label="🥁 Drums")
73
+ output_bass = gr.Audio(label="🎸 Bass")
74
+ output_guitar = gr.Audio(label="🎸 Guitar")
75
+ output_piano = gr.Audio(label="�� Piano")
76
+ output_other = gr.Audio(label="🎼 Other")
 
 
 
 
 
77
 
 
78
  separate_btn.click(
79
  fn=separate_audio,
80
  inputs=[input_audio, model_dropdown],
81
+ outputs=[output_vocals, output_drums, output_bass, output_other, output_guitar, output_piano],
82
+ api_name="separate_audio" # This is important for your JS client
 
 
83
  )
84
 
85
  gr.Markdown("---")